hotspot/src/share/vm/oops/cpCache.cpp
changeset 13929 8da0dc50a6e4
parent 13740 ae6179641137
child 14391 df0a1573d5bd
child 14393 93a4dcdbebfd
equal deleted inserted replaced
13918:b01a48301e67 13929:8da0dc50a6e4
   242   set_bytecode_1(Bytecodes::_invokeinterface);
   242   set_bytecode_1(Bytecodes::_invokeinterface);
   243 }
   243 }
   244 
   244 
   245 
   245 
   246 void ConstantPoolCacheEntry::set_method_handle(constantPoolHandle cpool,
   246 void ConstantPoolCacheEntry::set_method_handle(constantPoolHandle cpool,
   247                                                methodHandle adapter, Handle appendix,
   247                                                methodHandle adapter,
       
   248                                                Handle appendix, Handle method_type,
   248                                                objArrayHandle resolved_references) {
   249                                                objArrayHandle resolved_references) {
   249   set_method_handle_common(cpool, Bytecodes::_invokehandle, adapter, appendix, resolved_references);
   250   set_method_handle_common(cpool, Bytecodes::_invokehandle, adapter, appendix, method_type, resolved_references);
   250 }
   251 }
   251 
   252 
   252 void ConstantPoolCacheEntry::set_dynamic_call(constantPoolHandle cpool,
   253 void ConstantPoolCacheEntry::set_dynamic_call(constantPoolHandle cpool,
   253                                               methodHandle adapter, Handle appendix,
   254                                               methodHandle adapter,
       
   255                                               Handle appendix, Handle method_type,
   254                                               objArrayHandle resolved_references) {
   256                                               objArrayHandle resolved_references) {
   255   set_method_handle_common(cpool, Bytecodes::_invokedynamic, adapter, appendix, resolved_references);
   257   set_method_handle_common(cpool, Bytecodes::_invokedynamic, adapter, appendix, method_type, resolved_references);
   256 }
   258 }
   257 
   259 
   258 void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
   260 void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
   259                                                       Bytecodes::Code invoke_code,
   261                                                       Bytecodes::Code invoke_code,
   260                                                       methodHandle adapter,
   262                                                       methodHandle adapter,
   261                                                       Handle appendix,
   263                                                       Handle appendix, Handle method_type,
   262                                                       objArrayHandle resolved_references) {
   264                                                       objArrayHandle resolved_references) {
   263   // NOTE: This CPCE can be the subject of data races.
   265   // NOTE: This CPCE can be the subject of data races.
   264   // There are three words to update: flags, refs[f2], f1 (in that order).
   266   // There are three words to update: flags, refs[f2], f1 (in that order).
   265   // Writers must store all other values before f1.
   267   // Writers must store all other values before f1.
   266   // Readers must test f1 first for non-null before reading other fields.
   268   // Readers must test f1 first for non-null before reading other fields.
   272   MonitorLockerEx ml(cpool->lock());
   274   MonitorLockerEx ml(cpool->lock());
   273   if (!is_f1_null()) {
   275   if (!is_f1_null()) {
   274     return;
   276     return;
   275   }
   277   }
   276 
   278 
   277   bool has_appendix = appendix.not_null();
   279   const bool has_appendix    = appendix.not_null();
       
   280   const bool has_method_type = method_type.not_null();
   278 
   281 
   279   // Write the flags.
   282   // Write the flags.
   280   set_method_flags(as_TosState(adapter->result_type()),
   283   set_method_flags(as_TosState(adapter->result_type()),
   281                    ((has_appendix ?  1 : 0) << has_appendix_shift) |
   284                    ((has_appendix    ? 1 : 0) << has_appendix_shift   ) |
   282                    (                 1      << is_final_shift),
   285                    ((has_method_type ? 1 : 0) << has_method_type_shift) |
       
   286                    (                   1      << is_final_shift       ),
   283                    adapter->size_of_parameters());
   287                    adapter->size_of_parameters());
   284 
   288 
   285   if (TraceInvokeDynamic) {
   289   if (TraceInvokeDynamic) {
   286     tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method="PTR_FORMAT" ",
   290     tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method_type="PTR_FORMAT"%s method="PTR_FORMAT" ",
   287                   invoke_code,
   291                   invoke_code,
   288                   (intptr_t)appendix(), (has_appendix ? "" : " (unused)"),
   292                   (intptr_t)appendix(),    (has_appendix    ? "" : " (unused)"),
       
   293                   (intptr_t)method_type(), (has_method_type ? "" : " (unused)"),
   289                   (intptr_t)adapter());
   294                   (intptr_t)adapter());
   290     adapter->print();
   295     adapter->print();
   291     if (has_appendix)  appendix()->print();
   296     if (has_appendix)  appendix()->print();
   292   }
   297   }
   293 
   298 
   308   // not '(Ljava/lang/String;)Ljava/util/List;'.
   313   // not '(Ljava/lang/String;)Ljava/util/List;'.
   309   // The fact that String and List are involved is encoded in the MethodType in refs[f2].
   314   // The fact that String and List are involved is encoded in the MethodType in refs[f2].
   310   // This allows us to create fewer method oops, while keeping type safety.
   315   // This allows us to create fewer method oops, while keeping type safety.
   311   //
   316   //
   312 
   317 
       
   318   // Store appendix, if any.
   313   if (has_appendix) {
   319   if (has_appendix) {
   314     int ref_index = f2_as_index();
   320     const int appendix_index = f2_as_index() + _indy_resolved_references_appendix_offset;
   315     assert(ref_index >= 0 && ref_index < resolved_references->length(), "oob");
   321     assert(appendix_index >= 0 && appendix_index < resolved_references->length(), "oob");
   316     assert(resolved_references->obj_at(ref_index) == NULL, "init just once");
   322     assert(resolved_references->obj_at(appendix_index) == NULL, "init just once");
   317     resolved_references->obj_at_put(ref_index, appendix());
   323     resolved_references->obj_at_put(appendix_index, appendix());
       
   324   }
       
   325 
       
   326   // Store MethodType, if any.
       
   327   if (has_method_type) {
       
   328     const int method_type_index = f2_as_index() + _indy_resolved_references_method_type_offset;
       
   329     assert(method_type_index >= 0 && method_type_index < resolved_references->length(), "oob");
       
   330     assert(resolved_references->obj_at(method_type_index) == NULL, "init just once");
       
   331     resolved_references->obj_at_put(method_type_index, method_type());
   318   }
   332   }
   319 
   333 
   320   release_set_f1(adapter());  // This must be the last one to set (see NOTE above)!
   334   release_set_f1(adapter());  // This must be the last one to set (see NOTE above)!
   321 
   335 
   322     // The interpreter assembly code does not check byte_2,
   336   // The interpreter assembly code does not check byte_2,
   323     // but it is used by is_resolved, method_if_resolved, etc.
   337   // but it is used by is_resolved, method_if_resolved, etc.
   324   set_bytecode_1(invoke_code);
   338   set_bytecode_1(invoke_code);
   325   NOT_PRODUCT(verify(tty));
   339   NOT_PRODUCT(verify(tty));
   326   if (TraceInvokeDynamic) {
   340   if (TraceInvokeDynamic) {
   327     this->print(tty, 0);
   341     this->print(tty, 0);
   328   }
   342   }
   374 
   388 
   375 
   389 
   376 oop ConstantPoolCacheEntry::appendix_if_resolved(constantPoolHandle cpool) {
   390 oop ConstantPoolCacheEntry::appendix_if_resolved(constantPoolHandle cpool) {
   377   if (is_f1_null() || !has_appendix())
   391   if (is_f1_null() || !has_appendix())
   378     return NULL;
   392     return NULL;
   379   int ref_index = f2_as_index();
   393   const int ref_index = f2_as_index() + _indy_resolved_references_appendix_offset;
       
   394   objArrayOop resolved_references = cpool->resolved_references();
       
   395   return resolved_references->obj_at(ref_index);
       
   396 }
       
   397 
       
   398 
       
   399 oop ConstantPoolCacheEntry::method_type_if_resolved(constantPoolHandle cpool) {
       
   400   if (is_f1_null() || !has_method_type())
       
   401     return NULL;
       
   402   const int ref_index = f2_as_index() + _indy_resolved_references_method_type_offset;
   380   objArrayOop resolved_references = cpool->resolved_references();
   403   objArrayOop resolved_references = cpool->resolved_references();
   381   return resolved_references->obj_at(ref_index);
   404   return resolved_references->obj_at(ref_index);
   382 }
   405 }
   383 
   406 
   384 
   407 
   511 void ConstantPoolCache::initialize(intArray& inverse_index_map, intArray& invokedynamic_references_map) {
   534 void ConstantPoolCache::initialize(intArray& inverse_index_map, intArray& invokedynamic_references_map) {
   512   assert(inverse_index_map.length() == length(), "inverse index map must have same length as cache");
   535   assert(inverse_index_map.length() == length(), "inverse index map must have same length as cache");
   513   for (int i = 0; i < length(); i++) {
   536   for (int i = 0; i < length(); i++) {
   514     ConstantPoolCacheEntry* e = entry_at(i);
   537     ConstantPoolCacheEntry* e = entry_at(i);
   515     int original_index = inverse_index_map[i];
   538     int original_index = inverse_index_map[i];
   516       e->initialize_entry(original_index);
   539     e->initialize_entry(original_index);
   517     assert(entry_at(i) == e, "sanity");
   540     assert(entry_at(i) == e, "sanity");
   518     }
   541   }
   519   for (int ref = 0; ref < invokedynamic_references_map.length(); ref++) {
   542   for (int ref = 0; ref < invokedynamic_references_map.length(); ref++) {
   520     int cpci = invokedynamic_references_map[ref];
   543     const int cpci = invokedynamic_references_map[ref];
   521     if (cpci >= 0)
   544     if (cpci >= 0) {
       
   545 #ifdef ASSERT
       
   546       // invokedynamic and invokehandle have more entries; check if they
       
   547       // all point to the same constant pool cache entry.
       
   548       for (int entry = 1; entry < ConstantPoolCacheEntry::_indy_resolved_references_entries; entry++) {
       
   549         const int cpci_next = invokedynamic_references_map[ref + entry];
       
   550         assert(cpci == cpci_next, err_msg_res("%d == %d", cpci, cpci_next));
       
   551       }
       
   552 #endif
   522       entry_at(cpci)->initialize_resolved_reference_index(ref);
   553       entry_at(cpci)->initialize_resolved_reference_index(ref);
       
   554       ref += ConstantPoolCacheEntry::_indy_resolved_references_entries - 1;  // skip extra entries
       
   555     }
   523   }
   556   }
   524 }
   557 }
   525 
   558 
   526 // RedefineClasses() API support:
   559 // RedefineClasses() API support:
   527 // If any entry of this constantPoolCache points to any of
   560 // If any entry of this constantPoolCache points to any of