src/hotspot/share/asm/assembler.cpp
changeset 57514 9b6d4e64778c
parent 55425 7cf925f385fe
child 58679 9c3209ff7550
child 59290 97d13893ec3c
equal deleted inserted replaced
57513:6073b2290c0a 57514:9b6d4e64778c
   216     // Push the target offset into the branch instruction.
   216     // Push the target offset into the branch instruction.
   217     masm->pd_patch_instruction(branch, target, file, line);
   217     masm->pd_patch_instruction(branch, target, file, line);
   218   }
   218   }
   219 }
   219 }
   220 
   220 
   221 struct DelayedConstant {
       
   222   typedef void (*value_fn_t)();
       
   223   BasicType type;
       
   224   intptr_t value;
       
   225   value_fn_t value_fn;
       
   226   // This limit of 20 is generous for initial uses.
       
   227   // The limit needs to be large enough to store the field offsets
       
   228   // into classes which do not have statically fixed layouts.
       
   229   // (Initial use is for method handle object offsets.)
       
   230   // Look for uses of "delayed_value" in the source code
       
   231   // and make sure this number is generous enough to handle all of them.
       
   232   enum { DC_LIMIT = 20 };
       
   233   static DelayedConstant delayed_constants[DC_LIMIT];
       
   234   static DelayedConstant* add(BasicType type, value_fn_t value_fn);
       
   235   bool match(BasicType t, value_fn_t cfn) {
       
   236     return type == t && value_fn == cfn;
       
   237   }
       
   238   static void update_all();
       
   239 };
       
   240 
       
   241 DelayedConstant DelayedConstant::delayed_constants[DC_LIMIT];
       
   242 // Default C structure initialization rules have the following effect here:
       
   243 // = { { (BasicType)0, (intptr_t)NULL }, ... };
       
   244 
       
   245 DelayedConstant* DelayedConstant::add(BasicType type,
       
   246                                       DelayedConstant::value_fn_t cfn) {
       
   247   for (int i = 0; i < DC_LIMIT; i++) {
       
   248     DelayedConstant* dcon = &delayed_constants[i];
       
   249     if (dcon->match(type, cfn))
       
   250       return dcon;
       
   251     if (dcon->value_fn == NULL) {
       
   252         dcon->value_fn = cfn;
       
   253         dcon->type = type;
       
   254         return dcon;
       
   255     }
       
   256   }
       
   257   // If this assert is hit (in pre-integration testing!) then re-evaluate
       
   258   // the comment on the definition of DC_LIMIT.
       
   259   guarantee(false, "too many delayed constants");
       
   260   return NULL;
       
   261 }
       
   262 
       
   263 void DelayedConstant::update_all() {
       
   264   for (int i = 0; i < DC_LIMIT; i++) {
       
   265     DelayedConstant* dcon = &delayed_constants[i];
       
   266     if (dcon->value_fn != NULL && dcon->value == 0) {
       
   267       typedef int     (*int_fn_t)();
       
   268       typedef address (*address_fn_t)();
       
   269       switch (dcon->type) {
       
   270       case T_INT:     dcon->value = (intptr_t) ((int_fn_t)    dcon->value_fn)(); break;
       
   271       case T_ADDRESS: dcon->value = (intptr_t) ((address_fn_t)dcon->value_fn)(); break;
       
   272       default:        break;
       
   273       }
       
   274     }
       
   275   }
       
   276 }
       
   277 
       
   278 RegisterOrConstant AbstractAssembler::delayed_value(int(*value_fn)(), Register tmp, int offset) {
       
   279   intptr_t val = (intptr_t) (*value_fn)();
       
   280   if (val != 0)  return val + offset;
       
   281   return delayed_value_impl(delayed_value_addr(value_fn), tmp, offset);
       
   282 }
       
   283 RegisterOrConstant AbstractAssembler::delayed_value(address(*value_fn)(), Register tmp, int offset) {
       
   284   intptr_t val = (intptr_t) (*value_fn)();
       
   285   if (val != 0)  return val + offset;
       
   286   return delayed_value_impl(delayed_value_addr(value_fn), tmp, offset);
       
   287 }
       
   288 intptr_t* AbstractAssembler::delayed_value_addr(int(*value_fn)()) {
       
   289   DelayedConstant* dcon = DelayedConstant::add(T_INT, (DelayedConstant::value_fn_t) value_fn);
       
   290   return &dcon->value;
       
   291 }
       
   292 intptr_t* AbstractAssembler::delayed_value_addr(address(*value_fn)()) {
       
   293   DelayedConstant* dcon = DelayedConstant::add(T_ADDRESS, (DelayedConstant::value_fn_t) value_fn);
       
   294   return &dcon->value;
       
   295 }
       
   296 void AbstractAssembler::update_delayed_values() {
       
   297   DelayedConstant::update_all();
       
   298 }
       
   299 
       
   300 void AbstractAssembler::block_comment(const char* comment) {
   221 void AbstractAssembler::block_comment(const char* comment) {
   301   if (sect() == CodeBuffer::SECT_INSTS) {
   222   if (sect() == CodeBuffer::SECT_INSTS) {
   302     code_section()->outer()->block_comment(offset(), comment);
   223     code_section()->outer()->block_comment(offset(), comment);
   303   }
   224   }
   304 }
   225 }