< prev index next >

src/hotspot/share/oops/constantPool.cpp

Print this page

  36 #include "classfile/systemDictionary.hpp"
  37 #include "classfile/systemDictionaryShared.hpp"
  38 #include "classfile/vmClasses.hpp"
  39 #include "classfile/vmSymbols.hpp"
  40 #include "code/codeCache.hpp"
  41 #include "interpreter/bootstrapInfo.hpp"
  42 #include "interpreter/linkResolver.hpp"
  43 #include "jvm.h"
  44 #include "logging/log.hpp"
  45 #include "logging/logStream.hpp"
  46 #include "memory/allocation.inline.hpp"
  47 #include "memory/metadataFactory.hpp"
  48 #include "memory/metaspaceClosure.hpp"
  49 #include "memory/oopFactory.hpp"
  50 #include "memory/resourceArea.hpp"
  51 #include "memory/universe.hpp"
  52 #include "oops/array.hpp"
  53 #include "oops/constantPool.inline.hpp"
  54 #include "oops/cpCache.inline.hpp"
  55 #include "oops/fieldStreams.inline.hpp"

  56 #include "oops/instanceKlass.hpp"
  57 #include "oops/klass.inline.hpp"
  58 #include "oops/objArrayKlass.hpp"
  59 #include "oops/objArrayOop.inline.hpp"
  60 #include "oops/oop.inline.hpp"

  61 #include "oops/typeArrayOop.inline.hpp"
  62 #include "prims/jvmtiExport.hpp"
  63 #include "runtime/atomicAccess.hpp"
  64 #include "runtime/fieldDescriptor.inline.hpp"
  65 #include "runtime/handles.inline.hpp"
  66 #include "runtime/init.hpp"
  67 #include "runtime/javaCalls.hpp"
  68 #include "runtime/javaThread.inline.hpp"
  69 #include "runtime/perfData.hpp"
  70 #include "runtime/signature.hpp"
  71 #include "runtime/vframe.inline.hpp"
  72 #include "utilities/checkedCast.hpp"
  73 #include "utilities/copy.hpp"
  74 
  75 ConstantPool* ConstantPool::allocate(ClassLoaderData* loader_data, int length, TRAPS) {
  76   Array<u1>* tags = MetadataFactory::new_array<u1>(loader_data, length, 0, CHECK_NULL);
  77   int size = ConstantPool::size(length);
  78   return new (loader_data, size, MetaspaceObj::ConstantPoolType, THREAD) ConstantPool(tags);
  79 }
  80 

 174 
 175 // Called from outside constant pool resolution where a resolved_reference array
 176 // may not be present.
 177 objArrayOop ConstantPool::resolved_references_or_null() const {
 178   if (_cache == nullptr) {
 179     return nullptr;
 180   } else {
 181     return _cache->resolved_references();
 182   }
 183 }
 184 
 185 oop ConstantPool::resolved_reference_at(int index) const {
 186   oop result = resolved_references()->obj_at(index);
 187   assert(oopDesc::is_oop_or_null(result), "Must be oop");
 188   return result;
 189 }
 190 
 191 // Use a CAS for multithreaded access
 192 oop ConstantPool::set_resolved_reference_at(int index, oop new_result) {
 193   assert(oopDesc::is_oop_or_null(new_result), "Must be oop");
 194   return resolved_references()->replace_if_null(index, new_result);
 195 }
 196 
 197 // Create resolved_references array and mapping array for original cp indexes
 198 // The ldc bytecode was rewritten to have the resolved reference array index so need a way
 199 // to map it back for resolving and some unlikely miscellaneous uses.
 200 // The objects created by invokedynamic are appended to this list.
 201 void ConstantPool::initialize_resolved_references(ClassLoaderData* loader_data,
 202                                                   const intStack& reference_map,
 203                                                   int constant_pool_map_length,
 204                                                   TRAPS) {
 205   // Initialized the resolved object cache.
 206   int map_length = reference_map.length();
 207   if (map_length > 0) {
 208     // Only need mapping back to constant pool entries.  The map isn't used for
 209     // invokedynamic resolved_reference entries.  For invokedynamic entries,
 210     // the constant pool cache index has the mapping back to both the constant
 211     // pool and to the resolved reference index.
 212     if (constant_pool_map_length > 0) {
 213       Array<u2>* om = MetadataFactory::new_array<u2>(loader_data, constant_pool_map_length, CHECK);
 214 

 245   assert(resolved_klasses() == nullptr, "sanity");
 246   Array<Klass*>* rk = MetadataFactory::new_array<Klass*>(loader_data, num_klasses, CHECK);
 247   set_resolved_klasses(rk);
 248 }
 249 
 250 void ConstantPool::initialize_unresolved_klasses(ClassLoaderData* loader_data, TRAPS) {
 251   int len = length();
 252   int num_klasses = 0;
 253   for (int i = 1; i <len; i++) {
 254     switch (tag_at(i).value()) {
 255     case JVM_CONSTANT_ClassIndex:
 256       {
 257         const int class_index = klass_index_at(i);
 258         unresolved_klass_at_put(i, class_index, num_klasses++);
 259       }
 260       break;
 261 #ifndef PRODUCT
 262     case JVM_CONSTANT_Class:
 263     case JVM_CONSTANT_UnresolvedClass:
 264     case JVM_CONSTANT_UnresolvedClassInError:
 265       // All of these should have been reverted back to ClassIndex before calling
 266       // this function.
 267       ShouldNotReachHere();
 268 #endif
 269     }
 270   }
 271   allocate_resolved_klasses(loader_data, num_klasses, THREAD);
 272 }
 273 
 274 // Hidden class support:
 275 void ConstantPool::klass_at_put(int class_index, Klass* k) {
 276   assert(k != nullptr, "must be valid klass");
 277   CPKlassSlot kslot = klass_slot_at(class_index);
 278   int resolved_klass_index = kslot.resolved_klass_index();
 279   Klass** adr = resolved_klasses()->adr_at(resolved_klass_index);
 280   AtomicAccess::release_store(adr, k);
 281 
 282   // The interpreter assumes when the tag is stored, the klass is resolved
 283   // and the Klass* non-null, so we need hardware store ordering here.
 284   release_tag_at_put(class_index, JVM_CONSTANT_Class);
 285 }

 461   if (update_resolved_reference && cache() != nullptr) {
 462     set_resolved_reference_length(
 463         resolved_references() != nullptr ? resolved_references()->length() : 0);
 464     set_resolved_references(OopHandle());
 465   }
 466   remove_unshareable_entries();
 467 }
 468 
 469 static const char* get_type(Klass* k) {
 470   const char* type;
 471   Klass* src_k;
 472   if (ArchiveBuilder::is_active() && ArchiveBuilder::current()->is_in_buffer_space(k)) {
 473     src_k = ArchiveBuilder::current()->get_source_addr(k);
 474   } else {
 475     src_k = k;
 476   }
 477 
 478   if (src_k->is_objArray_klass()) {
 479     src_k = ObjArrayKlass::cast(src_k)->bottom_klass();
 480     assert(!src_k->is_objArray_klass(), "sanity");

 481   }
 482 
 483   if (src_k->is_typeArray_klass()) {
 484     type = "prim";
 485   } else {
 486     InstanceKlass* src_ik = InstanceKlass::cast(src_k);
 487     if (src_ik->defined_by_boot_loader()) {
 488       return "boot";
 489     } else if (src_ik->defined_by_platform_loader()) {
 490       return "plat";
 491     } else if (src_ik->defined_by_app_loader()) {
 492       return "app";
 493     } else {
 494       return "unreg";
 495     }
 496   }
 497 
 498   return type;
 499 }
 500 

 607       Symbol* s = vfst.method()->method_holder()->source_file_name();
 608       if (s != nullptr) {
 609         source_file = s->as_C_string();
 610       }
 611     }
 612   }
 613   if (k != this_cp->pool_holder()) {
 614     // only print something if the classes are different
 615     if (source_file != nullptr) {
 616       log_debug(class, resolve)("%s %s %s:%d",
 617                  this_cp->pool_holder()->external_name(),
 618                  k->external_name(), source_file, line_number);
 619     } else {
 620       log_debug(class, resolve)("%s %s",
 621                  this_cp->pool_holder()->external_name(),
 622                  k->external_name());
 623     }
 624   }
 625 }
 626 






 627 Klass* ConstantPool::klass_at_impl(const constantPoolHandle& this_cp, int cp_index,
 628                                    TRAPS) {
 629   JavaThread* javaThread = THREAD;
 630 
 631   // A resolved constantPool entry will contain a Klass*, otherwise a Symbol*.
 632   // It is not safe to rely on the tag bit's here, since we don't have a lock, and
 633   // the entry and tag is not updated atomically.
 634   CPKlassSlot kslot = this_cp->klass_slot_at(cp_index);
 635   int resolved_klass_index = kslot.resolved_klass_index();
 636   int name_index = kslot.name_index();
 637   assert(this_cp->tag_at(name_index).is_symbol(), "sanity");
 638 
 639   // The tag must be JVM_CONSTANT_Class in order to read the correct value from
 640   // the unresolved_klasses() array.
 641   if (this_cp->tag_at(cp_index).is_klass()) {
 642     Klass* klass = this_cp->resolved_klasses()->at(resolved_klass_index);
 643     assert(klass != nullptr, "must be resolved");
 644     return klass;
 645   }
 646 
 647   // This tag doesn't change back to unresolved class unless at a safepoint.
 648   if (this_cp->tag_at(cp_index).is_unresolved_klass_in_error()) {
 649     // The original attempt to resolve this constant pool entry failed so find the
 650     // class of the original error and throw another error of the same class
 651     // (JVMS 5.4.3).
 652     // If there is a detail message, pass that detail message to the error.
 653     // The JVMS does not strictly require us to duplicate the same detail message,
 654     // or any internal exception fields such as cause or stacktrace.  But since the
 655     // detail message is often a class name or other literal string, we will repeat it
 656     // if we can find it in the symbol table.
 657     throw_resolution_error(this_cp, cp_index, CHECK_NULL);
 658     ShouldNotReachHere();
 659   }
 660 
 661   HandleMark hm(THREAD);
 662   Handle mirror_handle;
 663   Symbol* name = this_cp->symbol_at(name_index);

 664   Handle loader (THREAD, this_cp->pool_holder()->class_loader());
 665 
 666   Klass* k;
 667   {
 668     // Turn off the single stepping while doing class resolution
 669     JvmtiHideSingleStepping jhss(javaThread);
 670     k = SystemDictionary::resolve_or_fail(name, loader, true, THREAD);
 671   } //  JvmtiHideSingleStepping jhss(javaThread);



 672 
 673   if (!HAS_PENDING_EXCEPTION) {
 674     // preserve the resolved klass from unloading
 675     mirror_handle = Handle(THREAD, k->java_mirror());
 676     // Do access check for klasses
 677     verify_constant_pool_resolve(this_cp, k, THREAD);
 678   }
 679 
















 680   // Failed to resolve class. We must record the errors so that subsequent attempts
 681   // to resolve this constant pool entry fail with the same error (JVMS 5.4.3).
 682   if (HAS_PENDING_EXCEPTION) {
 683     save_and_throw_exception(this_cp, cp_index, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_NULL);
 684     // If CHECK_NULL above doesn't return the exception, that means that
 685     // some other thread has beaten us and has resolved the class.
 686     // To preserve old behavior, we return the resolved class.
 687     Klass* klass = this_cp->resolved_klasses()->at(resolved_klass_index);
 688     assert(klass != nullptr, "must be resolved if exception was cleared");
 689     return klass;
 690   }
 691 
 692   // logging for class+resolve.
 693   if (log_is_enabled(Debug, class, resolve)){
 694     trace_class_resolution(this_cp, k);
 695   }
 696 
 697   // The interpreter assumes when the tag is stored, the klass is resolved
 698   // and the Klass* stored in _resolved_klasses is non-null, so we need
 699   // hardware store ordering here.

  36 #include "classfile/systemDictionary.hpp"
  37 #include "classfile/systemDictionaryShared.hpp"
  38 #include "classfile/vmClasses.hpp"
  39 #include "classfile/vmSymbols.hpp"
  40 #include "code/codeCache.hpp"
  41 #include "interpreter/bootstrapInfo.hpp"
  42 #include "interpreter/linkResolver.hpp"
  43 #include "jvm.h"
  44 #include "logging/log.hpp"
  45 #include "logging/logStream.hpp"
  46 #include "memory/allocation.inline.hpp"
  47 #include "memory/metadataFactory.hpp"
  48 #include "memory/metaspaceClosure.hpp"
  49 #include "memory/oopFactory.hpp"
  50 #include "memory/resourceArea.hpp"
  51 #include "memory/universe.hpp"
  52 #include "oops/array.hpp"
  53 #include "oops/constantPool.inline.hpp"
  54 #include "oops/cpCache.inline.hpp"
  55 #include "oops/fieldStreams.inline.hpp"
  56 #include "oops/flatArrayKlass.hpp"
  57 #include "oops/instanceKlass.hpp"
  58 #include "oops/klass.inline.hpp"
  59 #include "oops/objArrayKlass.hpp"
  60 #include "oops/objArrayOop.inline.hpp"
  61 #include "oops/oop.inline.hpp"
  62 #include "oops/refArrayOop.hpp"
  63 #include "oops/typeArrayOop.inline.hpp"
  64 #include "prims/jvmtiExport.hpp"
  65 #include "runtime/atomicAccess.hpp"
  66 #include "runtime/fieldDescriptor.inline.hpp"
  67 #include "runtime/handles.inline.hpp"
  68 #include "runtime/init.hpp"
  69 #include "runtime/javaCalls.hpp"
  70 #include "runtime/javaThread.inline.hpp"
  71 #include "runtime/perfData.hpp"
  72 #include "runtime/signature.hpp"
  73 #include "runtime/vframe.inline.hpp"
  74 #include "utilities/checkedCast.hpp"
  75 #include "utilities/copy.hpp"
  76 
  77 ConstantPool* ConstantPool::allocate(ClassLoaderData* loader_data, int length, TRAPS) {
  78   Array<u1>* tags = MetadataFactory::new_array<u1>(loader_data, length, 0, CHECK_NULL);
  79   int size = ConstantPool::size(length);
  80   return new (loader_data, size, MetaspaceObj::ConstantPoolType, THREAD) ConstantPool(tags);
  81 }
  82 

 176 
 177 // Called from outside constant pool resolution where a resolved_reference array
 178 // may not be present.
 179 objArrayOop ConstantPool::resolved_references_or_null() const {
 180   if (_cache == nullptr) {
 181     return nullptr;
 182   } else {
 183     return _cache->resolved_references();
 184   }
 185 }
 186 
 187 oop ConstantPool::resolved_reference_at(int index) const {
 188   oop result = resolved_references()->obj_at(index);
 189   assert(oopDesc::is_oop_or_null(result), "Must be oop");
 190   return result;
 191 }
 192 
 193 // Use a CAS for multithreaded access
 194 oop ConstantPool::set_resolved_reference_at(int index, oop new_result) {
 195   assert(oopDesc::is_oop_or_null(new_result), "Must be oop");
 196   return refArrayOopDesc::cast(resolved_references())->replace_if_null(index, new_result);
 197 }
 198 
 199 // Create resolved_references array and mapping array for original cp indexes
 200 // The ldc bytecode was rewritten to have the resolved reference array index so need a way
 201 // to map it back for resolving and some unlikely miscellaneous uses.
 202 // The objects created by invokedynamic are appended to this list.
 203 void ConstantPool::initialize_resolved_references(ClassLoaderData* loader_data,
 204                                                   const intStack& reference_map,
 205                                                   int constant_pool_map_length,
 206                                                   TRAPS) {
 207   // Initialized the resolved object cache.
 208   int map_length = reference_map.length();
 209   if (map_length > 0) {
 210     // Only need mapping back to constant pool entries.  The map isn't used for
 211     // invokedynamic resolved_reference entries.  For invokedynamic entries,
 212     // the constant pool cache index has the mapping back to both the constant
 213     // pool and to the resolved reference index.
 214     if (constant_pool_map_length > 0) {
 215       Array<u2>* om = MetadataFactory::new_array<u2>(loader_data, constant_pool_map_length, CHECK);
 216 

 247   assert(resolved_klasses() == nullptr, "sanity");
 248   Array<Klass*>* rk = MetadataFactory::new_array<Klass*>(loader_data, num_klasses, CHECK);
 249   set_resolved_klasses(rk);
 250 }
 251 
 252 void ConstantPool::initialize_unresolved_klasses(ClassLoaderData* loader_data, TRAPS) {
 253   int len = length();
 254   int num_klasses = 0;
 255   for (int i = 1; i <len; i++) {
 256     switch (tag_at(i).value()) {
 257     case JVM_CONSTANT_ClassIndex:
 258       {
 259         const int class_index = klass_index_at(i);
 260         unresolved_klass_at_put(i, class_index, num_klasses++);
 261       }
 262       break;
 263 #ifndef PRODUCT
 264     case JVM_CONSTANT_Class:
 265     case JVM_CONSTANT_UnresolvedClass:
 266     case JVM_CONSTANT_UnresolvedClassInError:
 267       // All of these should have been reverted back to Unresolved before calling
 268       // this function.
 269       ShouldNotReachHere();
 270 #endif
 271     }
 272   }
 273   allocate_resolved_klasses(loader_data, num_klasses, THREAD);
 274 }
 275 
 276 // Hidden class support:
 277 void ConstantPool::klass_at_put(int class_index, Klass* k) {
 278   assert(k != nullptr, "must be valid klass");
 279   CPKlassSlot kslot = klass_slot_at(class_index);
 280   int resolved_klass_index = kslot.resolved_klass_index();
 281   Klass** adr = resolved_klasses()->adr_at(resolved_klass_index);
 282   AtomicAccess::release_store(adr, k);
 283 
 284   // The interpreter assumes when the tag is stored, the klass is resolved
 285   // and the Klass* non-null, so we need hardware store ordering here.
 286   release_tag_at_put(class_index, JVM_CONSTANT_Class);
 287 }

 463   if (update_resolved_reference && cache() != nullptr) {
 464     set_resolved_reference_length(
 465         resolved_references() != nullptr ? resolved_references()->length() : 0);
 466     set_resolved_references(OopHandle());
 467   }
 468   remove_unshareable_entries();
 469 }
 470 
 471 static const char* get_type(Klass* k) {
 472   const char* type;
 473   Klass* src_k;
 474   if (ArchiveBuilder::is_active() && ArchiveBuilder::current()->is_in_buffer_space(k)) {
 475     src_k = ArchiveBuilder::current()->get_source_addr(k);
 476   } else {
 477     src_k = k;
 478   }
 479 
 480   if (src_k->is_objArray_klass()) {
 481     src_k = ObjArrayKlass::cast(src_k)->bottom_klass();
 482     assert(!src_k->is_objArray_klass(), "sanity");
 483     assert(src_k->is_instance_klass() || src_k->is_typeArray_klass(), "Sanity check");
 484   }
 485 
 486   if (src_k->is_typeArray_klass()) {
 487     type = "prim";
 488   } else {
 489     InstanceKlass* src_ik = InstanceKlass::cast(src_k);
 490     if (src_ik->defined_by_boot_loader()) {
 491       return "boot";
 492     } else if (src_ik->defined_by_platform_loader()) {
 493       return "plat";
 494     } else if (src_ik->defined_by_app_loader()) {
 495       return "app";
 496     } else {
 497       return "unreg";
 498     }
 499   }
 500 
 501   return type;
 502 }
 503 

 610       Symbol* s = vfst.method()->method_holder()->source_file_name();
 611       if (s != nullptr) {
 612         source_file = s->as_C_string();
 613       }
 614     }
 615   }
 616   if (k != this_cp->pool_holder()) {
 617     // only print something if the classes are different
 618     if (source_file != nullptr) {
 619       log_debug(class, resolve)("%s %s %s:%d",
 620                  this_cp->pool_holder()->external_name(),
 621                  k->external_name(), source_file, line_number);
 622     } else {
 623       log_debug(class, resolve)("%s %s",
 624                  this_cp->pool_holder()->external_name(),
 625                  k->external_name());
 626     }
 627   }
 628 }
 629 
 630 void check_is_inline_type(Klass* k, TRAPS) {
 631   if (!k->is_inline_klass()) {
 632     THROW(vmSymbols::java_lang_IncompatibleClassChangeError());
 633   }
 634 }
 635 
 636 Klass* ConstantPool::klass_at_impl(const constantPoolHandle& this_cp, int cp_index,
 637                                    TRAPS) {
 638   JavaThread* javaThread = THREAD;
 639 
 640   // A resolved constantPool entry will contain a Klass*, otherwise a Symbol*.
 641   // It is not safe to rely on the tag bit's here, since we don't have a lock, and
 642   // the entry and tag is not updated atomically.
 643   CPKlassSlot kslot = this_cp->klass_slot_at(cp_index);
 644   int resolved_klass_index = kslot.resolved_klass_index();
 645   int name_index = kslot.name_index();
 646   assert(this_cp->tag_at(name_index).is_symbol(), "sanity");
 647 
 648   // The tag must be JVM_CONSTANT_Class in order to read the correct value from
 649   // the unresolved_klasses() array.
 650   if (this_cp->tag_at(cp_index).is_klass()) {
 651     Klass* klass = this_cp->resolved_klasses()->at(resolved_klass_index);
 652     assert(klass != nullptr, "must be resolved");
 653     return klass;
 654   }
 655 
 656   // This tag doesn't change back to unresolved class unless at a safepoint.
 657   if (this_cp->tag_at(cp_index).is_unresolved_klass_in_error()) {
 658     // The original attempt to resolve this constant pool entry failed so find the
 659     // class of the original error and throw another error of the same class
 660     // (JVMS 5.4.3).
 661     // If there is a detail message, pass that detail message to the error.
 662     // The JVMS does not strictly require us to duplicate the same detail message,
 663     // or any internal exception fields such as cause or stacktrace.  But since the
 664     // detail message is often a class name or other literal string, we will repeat it
 665     // if we can find it in the symbol table.
 666     throw_resolution_error(this_cp, cp_index, CHECK_NULL);
 667     ShouldNotReachHere();
 668   }
 669 
 670   HandleMark hm(THREAD);
 671   Handle mirror_handle;
 672   Symbol* name = this_cp->symbol_at(name_index);
 673   bool inline_type_signature = false;
 674   Handle loader (THREAD, this_cp->pool_holder()->class_loader());
 675 
 676   Klass* k;
 677   {
 678     // Turn off the single stepping while doing class resolution
 679     JvmtiHideSingleStepping jhss(javaThread);
 680     k = SystemDictionary::resolve_or_fail(name, loader, true, THREAD);
 681   } //  JvmtiHideSingleStepping jhss(javaThread);
 682   if (inline_type_signature) {
 683     name->decrement_refcount();
 684   }
 685 
 686   if (!HAS_PENDING_EXCEPTION) {
 687     // preserve the resolved klass from unloading
 688     mirror_handle = Handle(THREAD, k->java_mirror());
 689     // Do access check for klasses
 690     verify_constant_pool_resolve(this_cp, k, THREAD);
 691   }
 692 
 693   if (!HAS_PENDING_EXCEPTION && inline_type_signature) {
 694     check_is_inline_type(k, THREAD);
 695   }
 696 
 697   if (!HAS_PENDING_EXCEPTION) {
 698     Klass* bottom_klass = nullptr;
 699     if (k->is_objArray_klass()) {
 700       bottom_klass = ObjArrayKlass::cast(k)->bottom_klass();
 701       assert(bottom_klass != nullptr, "Should be set");
 702       assert(bottom_klass->is_instance_klass() || bottom_klass->is_typeArray_klass(), "Sanity check");
 703     } else if (k->is_flatArray_klass()) {
 704       bottom_klass = FlatArrayKlass::cast(k)->element_klass();
 705       assert(bottom_klass != nullptr, "Should be set");
 706     }
 707   }
 708 
 709   // Failed to resolve class. We must record the errors so that subsequent attempts
 710   // to resolve this constant pool entry fail with the same error (JVMS 5.4.3).
 711   if (HAS_PENDING_EXCEPTION) {
 712     save_and_throw_exception(this_cp, cp_index, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_NULL);
 713     // If CHECK_NULL above doesn't return the exception, that means that
 714     // some other thread has beaten us and has resolved the class.
 715     // To preserve old behavior, we return the resolved class.
 716     Klass* klass = this_cp->resolved_klasses()->at(resolved_klass_index);
 717     assert(klass != nullptr, "must be resolved if exception was cleared");
 718     return klass;
 719   }
 720 
 721   // logging for class+resolve.
 722   if (log_is_enabled(Debug, class, resolve)){
 723     trace_class_resolution(this_cp, k);
 724   }
 725 
 726   // The interpreter assumes when the tag is stored, the klass is resolved
 727   // and the Klass* stored in _resolved_klasses is non-null, so we need
 728   // hardware store ordering here.
< prev index next >