< prev index next >

src/hotspot/share/oops/instanceKlass.cpp

Print this page
rev 58565 : 8238358: Implementation of JEP 371: Hidden Classes
Reviewed-by: duke
Contributed-by: mandy.chung@oracle.com, lois.foltan@oracle.com, david.holmes@oracle.com, harold.seigel@oracle.com, serguei.spitsyn@oracle.com, alex.buckley@oracle.com, jamsheed.c.m@oracle.com


  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "jvm.h"
  27 #include "aot/aotLoader.hpp"
  28 #include "classfile/classFileParser.hpp"
  29 #include "classfile/classFileStream.hpp"
  30 #include "classfile/classLoader.hpp"
  31 #include "classfile/classLoaderData.inline.hpp"
  32 #include "classfile/javaClasses.hpp"
  33 #include "classfile/moduleEntry.hpp"

  34 #include "classfile/symbolTable.hpp"
  35 #include "classfile/systemDictionary.hpp"
  36 #include "classfile/systemDictionaryShared.hpp"
  37 #include "classfile/verifier.hpp"
  38 #include "classfile/vmSymbols.hpp"
  39 #include "code/dependencyContext.hpp"
  40 #include "compiler/compileBroker.hpp"
  41 #include "gc/shared/collectedHeap.inline.hpp"
  42 #include "interpreter/oopMapCache.hpp"
  43 #include "interpreter/rewriter.hpp"
  44 #include "jvmtifiles/jvmti.h"
  45 #include "logging/log.hpp"
  46 #include "logging/logMessage.hpp"
  47 #include "logging/logStream.hpp"
  48 #include "memory/allocation.inline.hpp"
  49 #include "memory/iterator.inline.hpp"
  50 #include "memory/metadataFactory.hpp"
  51 #include "memory/metaspaceClosure.hpp"
  52 #include "memory/metaspaceShared.hpp"
  53 #include "memory/oopFactory.hpp"


 117 #define DTRACE_CLASSINIT_PROBE_WAIT(type, thread_type, wait)     \
 118   {                                                              \
 119     char* data = NULL;                                           \
 120     int len = 0;                                                 \
 121     Symbol* clss_name = name();                                  \
 122     if (clss_name != NULL) {                                     \
 123       data = (char*)clss_name->bytes();                          \
 124       len = clss_name->utf8_length();                            \
 125     }                                                            \
 126     HOTSPOT_CLASS_INITIALIZATION_##type(                         \
 127       data, len, (void*)class_loader(), thread_type, wait);      \
 128   }
 129 
 130 #else //  ndef DTRACE_ENABLED
 131 
 132 #define DTRACE_CLASSINIT_PROBE(type, thread_type)
 133 #define DTRACE_CLASSINIT_PROBE_WAIT(type, thread_type, wait)
 134 
 135 #endif //  ndef DTRACE_ENABLED
 136 

 137 static inline bool is_class_loader(const Symbol* class_name,
 138                                    const ClassFileParser& parser) {
 139   assert(class_name != NULL, "invariant");
 140 
 141   if (class_name == vmSymbols::java_lang_ClassLoader()) {
 142     return true;
 143   }
 144 
 145   if (SystemDictionary::ClassLoader_klass_loaded()) {
 146     const Klass* const super_klass = parser.super_klass();
 147     if (super_klass != NULL) {
 148       if (super_klass->is_subtype_of(SystemDictionary::ClassLoader_klass())) {
 149         return true;
 150       }
 151     }
 152   }
 153   return false;
 154 }
 155 
 156 // called to verify that k is a member of this nest


 157 bool InstanceKlass::has_nest_member(InstanceKlass* k, TRAPS) const {

 158   if (_nest_members == NULL || _nest_members == Universe::the_empty_short_array()) {
 159     if (log_is_enabled(Trace, class, nestmates)) {
 160       ResourceMark rm(THREAD);
 161       log_trace(class, nestmates)("Checked nest membership of %s in non-nest-host class %s",
 162                                   k->external_name(), this->external_name());
 163     }
 164     return false;
 165   }
 166 
 167   if (log_is_enabled(Trace, class, nestmates)) {
 168     ResourceMark rm(THREAD);
 169     log_trace(class, nestmates)("Checking nest membership of %s in %s",
 170                                 k->external_name(), this->external_name());
 171   }
 172 
 173   // Check for a resolved cp entry , else fall back to a name check.
 174   // We don't want to resolve any class other than the one being checked.
 175   for (int i = 0; i < _nest_members->length(); i++) {
 176     int cp_index = _nest_members->at(i);
 177     if (_constants->tag_at(cp_index).is_klass()) {
 178       Klass* k2 = _constants->klass_at(cp_index, CHECK_false);


 179       if (k2 == k) {
 180         log_trace(class, nestmates)("- class is listed at nest_members[%d] => cp[%d]", i, cp_index);
 181         return true;
 182       }
 183     }
 184     else {
 185       Symbol* name = _constants->klass_name_at(cp_index);
 186       if (name == k->name()) {
 187         log_trace(class, nestmates)("- Found it at nest_members[%d] => cp[%d]", i, cp_index);
 188 
 189         // Names match so check actual klass - this may trigger class loading if
 190         // it doesn't match (though that should be impossible). But to be safe we
 191         // have to check for a compiler thread executing here.
 192         if (!THREAD->can_call_java() && !_constants->tag_at(cp_index).is_klass()) {
 193           log_trace(class, nestmates)("- validation required resolution in an unsuitable thread");
 194           return false;
 195         }
 196 
 197         Klass* k2 = _constants->klass_at(cp_index, CHECK_false);
 198         if (k2 == k) {
 199           log_trace(class, nestmates)("- class is listed as a nest member");
 200           return true;
 201         }
 202         else {
 203           // same name but different klass!
 204           log_trace(class, nestmates)(" - klass comparison failed!");
 205           // can't have two names the same, so we're done
 206           return false;
 207         }
 208       }
 209     }
 210   }
 211   log_trace(class, nestmates)("- class is NOT a nest member!");
 212   return false;
 213 }
 214 
 215 // Return nest-host class, resolving, validating and saving it if needed.
 216 // In cases where this is called from a thread that can not do classloading
 217 // (such as a native JIT thread) then we simply return NULL, which in turn
 218 // causes the access check to return false. Such code will retry the access
 219 // from a more suitable environment later.
 220 InstanceKlass* InstanceKlass::nest_host(Symbol* validationException, TRAPS) {








 221   InstanceKlass* nest_host_k = _nest_host;
 222   if (nest_host_k == NULL) {
 223     // need to resolve and save our nest-host class. This could be attempted
 224     // concurrently but as the result is idempotent and we don't use the class
 225     // then we do not need any synchronization beyond what is implicitly used
 226     // during class loading.


 227     if (_nest_host_index != 0) { // we have a real nest_host
 228       // Before trying to resolve check if we're in a suitable context
 229       if (!THREAD->can_call_java() && !_constants->tag_at(_nest_host_index).is_klass()) {
 230         if (log_is_enabled(Trace, class, nestmates)) {
 231           ResourceMark rm(THREAD);
 232           log_trace(class, nestmates)("Rejected resolution of nest-host of %s in unsuitable thread",
 233                                       this->external_name());
 234         }
 235         return NULL;
 236       }
 237 
 238       if (log_is_enabled(Trace, class, nestmates)) {
 239         ResourceMark rm(THREAD);
 240         log_trace(class, nestmates)("Resolving nest-host of %s using cp entry for %s",
 241                                     this->external_name(),
 242                                     _constants->klass_name_at(_nest_host_index)->as_C_string());
 243       }
 244 
 245       Klass* k = _constants->klass_at(_nest_host_index, THREAD);
 246       if (HAS_PENDING_EXCEPTION) {
 247         Handle exc_h = Handle(THREAD, PENDING_EXCEPTION);
 248         if (exc_h->is_a(SystemDictionary::NoClassDefFoundError_klass())) {
 249           // throw a new CDNFE with the original as its cause, and a clear msg
 250           ResourceMark rm(THREAD);
 251           char buf[200];
 252           CLEAR_PENDING_EXCEPTION;
 253           jio_snprintf(buf, sizeof(buf),
 254                        "Unable to load nest-host class (%s) of %s",
 255                        _constants->klass_name_at(_nest_host_index)->as_C_string(),
 256                        this->external_name());
 257           log_trace(class, nestmates)("%s - NoClassDefFoundError", buf);
 258           THROW_MSG_CAUSE_NULL(vmSymbols::java_lang_NoClassDefFoundError(), buf, exc_h);
 259         }
 260         // All other exceptions pass through (OOME, StackOverflowError, LinkageErrors etc).
 261         return NULL;
 262       }









 263 


 264       // A valid nest-host is an instance class in the current package that lists this
 265       // class as a nest member. If any of these conditions are not met we post the
 266       // requested exception type (if any) and return NULL
 267 
 268       const char* error = NULL;
 269 
 270       // JVMS 5.4.4 indicates package check comes first
 271       if (is_same_class_package(k)) {
 272 
 273         // Now check actual membership. We can't be a member if our "host" is
 274         // not an instance class.
 275         if (k->is_instance_klass()) {
 276           nest_host_k = InstanceKlass::cast(k);
 277 
 278           bool is_member = nest_host_k->has_nest_member(this, CHECK_NULL);

 279           if (is_member) {
 280             // save resolved nest-host value
 281             _nest_host = nest_host_k;
 282 
 283             if (log_is_enabled(Trace, class, nestmates)) {
 284               ResourceMark rm(THREAD);
 285               log_trace(class, nestmates)("Resolved nest-host of %s to %s",
 286                                           this->external_name(), k->external_name());
 287             }
 288             return nest_host_k;


 289           }











 290         }
 291         error = "current type is not listed as a nest member";
 292       } else {
 293         error = "types are in different packages";
 294       }
 295 
 296       if (log_is_enabled(Trace, class, nestmates)) {
 297         ResourceMark rm(THREAD);
 298         log_trace(class, nestmates)
 299           ("Type %s (loader: %s) is not a nest member of "
 300            "resolved type %s (loader: %s): %s",
 301            this->external_name(),
 302            this->class_loader_data()->loader_name_and_id(),
 303            k->external_name(),
 304            k->class_loader_data()->loader_name_and_id(),
 305            error);




 306       }
 307 
 308       if (validationException != NULL && THREAD->can_call_java()) {
 309         ResourceMark rm(THREAD);
 310         Exceptions::fthrow(THREAD_AND_LOCATION,
 311                            validationException,
 312                            "Type %s (loader: %s) is not a nest member of %s (loader: %s): %s",
 313                            this->external_name(),
 314                            this->class_loader_data()->loader_name_and_id(),
 315                            k->external_name(),
 316                            k->class_loader_data()->loader_name_and_id(),
 317                            error
 318                            );
 319       }
 320       return NULL;
 321     } else {
 322       if (log_is_enabled(Trace, class, nestmates)) {
 323         ResourceMark rm(THREAD);
 324         log_trace(class, nestmates)("Type %s is not part of a nest: setting nest-host to self",
 325                                     this->external_name());
 326       }
 327       // save resolved nest-host value



 328       return (_nest_host = this);






























 329     }




 330   }
 331   return nest_host_k;




 332 }
 333 
 334 // check if 'this' and k are nestmates (same nest_host), or k is our nest_host,
 335 // or we are k's nest_host - all of which is covered by comparing the two
 336 // resolved_nest_hosts

 337 bool InstanceKlass::has_nestmate_access_to(InstanceKlass* k, TRAPS) {
 338 
 339   assert(this != k, "this should be handled by higher-level code");
 340 
 341   // Per JVMS 5.4.4 we first resolve and validate the current class, then
 342   // the target class k. Resolution exceptions will be passed on by upper
 343   // layers. IncompatibleClassChangeErrors from membership validation failures
 344   // will also be passed through.
 345 
 346   Symbol* icce = vmSymbols::java_lang_IncompatibleClassChangeError();
 347   InstanceKlass* cur_host = nest_host(icce, CHECK_false);
 348   if (cur_host == NULL) {
 349     return false;
 350   }
 351 
 352   Klass* k_nest_host = k->nest_host(icce, CHECK_false);
 353   if (k_nest_host == NULL) {
 354     return false;
 355   }
 356 
 357   bool access = (cur_host == k_nest_host);
 358 
 359   if (log_is_enabled(Trace, class, nestmates)) {
 360     ResourceMark rm(THREAD);
 361     log_trace(class, nestmates)("Class %s does %shave nestmate access to %s",
 362                                 this->external_name(),
 363                                 access ? "" : "NOT ",
 364                                 k->external_name());
 365   }
 366 
 367   return access;
 368 }
 369 









 370 InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& parser, TRAPS) {

 371   const int size = InstanceKlass::size(parser.vtable_size(),
 372                                        parser.itable_size(),
 373                                        nonstatic_oop_map_size(parser.total_oop_map_count()),
 374                                        parser.is_interface(),
 375                                        parser.is_unsafe_anonymous(),
 376                                        should_store_fingerprint(parser.is_unsafe_anonymous()));
 377 
 378   const Symbol* const class_name = parser.class_name();
 379   assert(class_name != NULL, "invariant");
 380   ClassLoaderData* loader_data = parser.loader_data();
 381   assert(loader_data != NULL, "invariant");
 382 
 383   InstanceKlass* ik;
 384 
 385   // Allocation
 386   if (REF_NONE == parser.reference_type()) {
 387     if (class_name == vmSymbols::java_lang_Class()) {
 388       // mirror
 389       ik = new (loader_data, size, THREAD) InstanceMirrorKlass(parser);
 390     }
 391     else if (is_class_loader(class_name, parser)) {
 392       // class loader
 393       ik = new (loader_data, size, THREAD) InstanceClassLoaderKlass(parser);
 394     } else {
 395       // normal
 396       ik = new (loader_data, size, THREAD) InstanceKlass(parser, InstanceKlass::_misc_kind_other);


 430   set_default_vtable_indices(vtable_indices);
 431   return vtable_indices;
 432 }
 433 
 434 InstanceKlass::InstanceKlass(const ClassFileParser& parser, unsigned kind, KlassID id) :
 435   Klass(id),
 436   _nest_members(NULL),
 437   _nest_host_index(0),
 438   _nest_host(NULL),
 439   _record_components(NULL),
 440   _static_field_size(parser.static_field_size()),
 441   _nonstatic_oop_map_size(nonstatic_oop_map_size(parser.total_oop_map_count())),
 442   _itable_len(parser.itable_size()),
 443   _init_thread(NULL),
 444   _init_state(allocated),
 445   _reference_type(parser.reference_type())
 446 {
 447   set_vtable_length(parser.vtable_size());
 448   set_kind(kind);
 449   set_access_flags(parser.access_flags());

 450   set_is_unsafe_anonymous(parser.is_unsafe_anonymous());
 451   set_layout_helper(Klass::instance_layout_helper(parser.layout_size(),
 452                                                     false));
 453 
 454   assert(NULL == _methods, "underlying memory not zeroed?");
 455   assert(is_instance_klass(), "is layout incorrect?");
 456   assert(size_helper() == parser.layout_size(), "incorrect size_helper?");
 457 
 458   if (Arguments::is_dumping_archive()) {
 459     SystemDictionaryShared::init_dumptime_info(this);
 460   }
 461 
 462   // Set biased locking bit for all instances of this class; it will be
 463   // cleared if revocation occurs too often for this type
 464   if (UseBiasedLocking && BiasedLocking::enabled()) {
 465     set_prototype_header(markWord::biased_locking_prototype());
 466   }
 467 }
 468 
 469 void InstanceKlass::deallocate_methods(ClassLoaderData* loader_data,


2259     log_trace(class, fingerprint)("%s : super %s not fingerprinted", external_name(), java_super()->external_name());
2260     return false;
2261   }
2262 
2263   Array<InstanceKlass*>* local_interfaces = this->local_interfaces();
2264   if (local_interfaces != NULL) {
2265     int length = local_interfaces->length();
2266     for (int i = 0; i < length; i++) {
2267       InstanceKlass* intf = local_interfaces->at(i);
2268       if (!intf->has_passed_fingerprint_check()) {
2269         ResourceMark rm;
2270         log_trace(class, fingerprint)("%s : interface %s not fingerprinted", external_name(), intf->external_name());
2271         return false;
2272       }
2273     }
2274   }
2275 
2276   return true;
2277 }
2278 
2279 bool InstanceKlass::should_store_fingerprint(bool is_unsafe_anonymous) {
2280 #if INCLUDE_AOT
2281   // We store the fingerprint into the InstanceKlass only in the following 2 cases:
2282   if (CalculateClassFingerprint) {
2283     // (1) We are running AOT to generate a shared library.
2284     return true;
2285   }
2286   if (Arguments::is_dumping_archive()) {
2287     // (2) We are running -Xshare:dump or -XX:ArchiveClassesAtExit to create a shared archive
2288     return true;
2289   }
2290   if (UseAOT && is_unsafe_anonymous) {
2291     // (3) We are using AOT code from a shared library and see an unsafe anonymous class
2292     return true;
2293   }
2294 #endif
2295 
2296   // In all other cases we might set the _misc_has_passed_fingerprint_check bit,
2297   // but do not store the 64-bit fingerprint to save space.
2298   return false;
2299 }
2300 
2301 bool InstanceKlass::has_stored_fingerprint() const {
2302 #if INCLUDE_AOT
2303   return should_store_fingerprint() || is_shared();
2304 #else
2305   return false;
2306 #endif
2307 }
2308 
2309 uint64_t InstanceKlass::get_stored_fingerprint() const {
2310   address adr = adr_fingerprint();
2311   if (adr != NULL) {


2563 
2564   assert(_dep_context == NULL,
2565          "dependencies should already be cleaned");
2566 
2567 #if INCLUDE_JVMTI
2568   // Deallocate breakpoint records
2569   if (breakpoints() != 0x0) {
2570     methods_do(clear_all_breakpoints);
2571     assert(breakpoints() == 0x0, "should have cleared breakpoints");
2572   }
2573 
2574   // deallocate the cached class file
2575   if (_cached_class_file != NULL) {
2576     os::free(_cached_class_file);
2577     _cached_class_file = NULL;
2578   }
2579 #endif
2580 
2581   // Decrement symbol reference counts associated with the unloaded class.
2582   if (_name != NULL) _name->decrement_refcount();

2583   // unreference array name derived from this class name (arrays of an unloaded
2584   // class can't be referenced anymore).
2585   if (_array_name != NULL)  _array_name->decrement_refcount();
2586   FREE_C_HEAP_ARRAY(char, _source_debug_extension);
2587 }
2588 
2589 void InstanceKlass::set_source_debug_extension(const char* array, int length) {
2590   if (array == NULL) {
2591     _source_debug_extension = NULL;
2592   } else {
2593     // Adding one to the attribute length in order to store a null terminator
2594     // character could cause an overflow because the attribute length is
2595     // already coded with an u4 in the classfile, but in practice, it's
2596     // unlikely to happen.
2597     assert((length+1) > length, "Overflow checking");
2598     char* sde = NEW_C_HEAP_ARRAY(char, (length + 1), mtClass);
2599     for (int i = 0; i < length; i++) {
2600       sde[i] = array[i];
2601     }
2602     sde[length] = '\0';


2613     intptr_t hash = (java_mirror() != NULL) ? java_mirror()->identity_hash() : 0;
2614     jio_snprintf(hash_buf, sizeof(hash_buf), "/" UINTX_FORMAT, (uintx)hash);
2615     hash_len = (int)strlen(hash_buf);
2616   }
2617 
2618   // Get the internal name as a c string
2619   const char* src = (const char*) (name()->as_C_string());
2620   const int src_length = (int)strlen(src);
2621 
2622   char* dest = NEW_RESOURCE_ARRAY(char, src_length + hash_len + 3);
2623 
2624   // Add L as type indicator
2625   int dest_index = 0;
2626   dest[dest_index++] = JVM_SIGNATURE_CLASS;
2627 
2628   // Add the actual class name
2629   for (int src_index = 0; src_index < src_length; ) {
2630     dest[dest_index++] = src[src_index++];
2631   }
2632 









2633   // If we have a hash, append it
2634   for (int hash_index = 0; hash_index < hash_len; ) {
2635     dest[dest_index++] = hash_buf[hash_index++];
2636   }
2637 
2638   // Add the semicolon and the NULL
2639   dest[dest_index++] = JVM_SIGNATURE_ENDCLASS;
2640   dest[dest_index] = '\0';
2641   return dest;
2642 }
2643 
2644 ModuleEntry* InstanceKlass::module() const {
2645   // For an unsafe anonymous class return the host class' module
2646   if (is_unsafe_anonymous()) {
2647     assert(unsafe_anonymous_host() != NULL, "unsafe anonymous class must have a host class");
2648     return unsafe_anonymous_host()->module();
2649   }
2650 



















2651   // Class is in a named package
2652   if (!in_unnamed_package()) {
2653     return _package_entry->module();
2654   }
2655 
2656   // Class is in an unnamed package, return its loader's unnamed module
2657   return class_loader_data()->unnamed_module();
2658 }
2659 
2660 void InstanceKlass::set_package(ClassLoaderData* loader_data, TRAPS) {
2661 
2662   // ensure java/ packages only loaded by boot or platform builtin loaders
2663   check_prohibited_package(name(), loader_data, CHECK);
2664 
2665   TempNewSymbol pkg_name = ClassLoader::package_from_class_name(name());
2666 
2667   if (pkg_name != NULL && loader_data != NULL) {
2668 
2669     // Find in class loader's package entry table.
2670     _package_entry = loader_data->packages()->lookup_only(pkg_name);


2841         }
2842       }
2843     }
2844   }
2845   return false;
2846 }
2847 
2848 InstanceKlass* InstanceKlass::compute_enclosing_class(bool* inner_is_member, TRAPS) const {
2849   InstanceKlass* outer_klass = NULL;
2850   *inner_is_member = false;
2851   int ooff = 0, noff = 0;
2852   bool has_inner_classes_attr = find_inner_classes_attr(&ooff, &noff, THREAD);
2853   if (has_inner_classes_attr) {
2854     constantPoolHandle i_cp(THREAD, constants());
2855     if (ooff != 0) {
2856       Klass* ok = i_cp->klass_at(ooff, CHECK_NULL);
2857       outer_klass = InstanceKlass::cast(ok);
2858       *inner_is_member = true;
2859     }
2860     if (NULL == outer_klass) {
2861       // It may be unsafe anonymous; try for that.
2862       int encl_method_class_idx = enclosing_method_class_index();
2863       if (encl_method_class_idx != 0) {
2864         Klass* ok = i_cp->klass_at(encl_method_class_idx, CHECK_NULL);
2865         outer_klass = InstanceKlass::cast(ok);
2866         *inner_is_member = false;
2867       }
2868     }
2869   }
2870 
2871   // If no inner class attribute found for this class.
2872   if (NULL == outer_klass) return NULL;
2873 
2874   // Throws an exception if outer klass has not declared k as an inner klass
2875   // We need evidence that each klass knows about the other, or else
2876   // the system could allow a spoof of an inner class to gain access rights.
2877   Reflection::check_for_inner_class(outer_klass, this, *inner_is_member, CHECK_NULL);
2878   return outer_klass;
2879 }
2880 
2881 jint InstanceKlass::compute_modifier_flags(TRAPS) const {




  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "jvm.h"
  27 #include "aot/aotLoader.hpp"
  28 #include "classfile/classFileParser.hpp"
  29 #include "classfile/classFileStream.hpp"
  30 #include "classfile/classLoader.hpp"
  31 #include "classfile/classLoaderData.inline.hpp"
  32 #include "classfile/javaClasses.hpp"
  33 #include "classfile/moduleEntry.hpp"
  34 #include "classfile/resolutionErrors.hpp"
  35 #include "classfile/symbolTable.hpp"
  36 #include "classfile/systemDictionary.hpp"
  37 #include "classfile/systemDictionaryShared.hpp"
  38 #include "classfile/verifier.hpp"
  39 #include "classfile/vmSymbols.hpp"
  40 #include "code/dependencyContext.hpp"
  41 #include "compiler/compileBroker.hpp"
  42 #include "gc/shared/collectedHeap.inline.hpp"
  43 #include "interpreter/oopMapCache.hpp"
  44 #include "interpreter/rewriter.hpp"
  45 #include "jvmtifiles/jvmti.h"
  46 #include "logging/log.hpp"
  47 #include "logging/logMessage.hpp"
  48 #include "logging/logStream.hpp"
  49 #include "memory/allocation.inline.hpp"
  50 #include "memory/iterator.inline.hpp"
  51 #include "memory/metadataFactory.hpp"
  52 #include "memory/metaspaceClosure.hpp"
  53 #include "memory/metaspaceShared.hpp"
  54 #include "memory/oopFactory.hpp"


 118 #define DTRACE_CLASSINIT_PROBE_WAIT(type, thread_type, wait)     \
 119   {                                                              \
 120     char* data = NULL;                                           \
 121     int len = 0;                                                 \
 122     Symbol* clss_name = name();                                  \
 123     if (clss_name != NULL) {                                     \
 124       data = (char*)clss_name->bytes();                          \
 125       len = clss_name->utf8_length();                            \
 126     }                                                            \
 127     HOTSPOT_CLASS_INITIALIZATION_##type(                         \
 128       data, len, (void*)class_loader(), thread_type, wait);      \
 129   }
 130 
 131 #else //  ndef DTRACE_ENABLED
 132 
 133 #define DTRACE_CLASSINIT_PROBE(type, thread_type)
 134 #define DTRACE_CLASSINIT_PROBE_WAIT(type, thread_type, wait)
 135 
 136 #endif //  ndef DTRACE_ENABLED
 137 
 138 
 139 static inline bool is_class_loader(const Symbol* class_name,
 140                                    const ClassFileParser& parser) {
 141   assert(class_name != NULL, "invariant");
 142 
 143   if (class_name == vmSymbols::java_lang_ClassLoader()) {
 144     return true;
 145   }
 146 
 147   if (SystemDictionary::ClassLoader_klass_loaded()) {
 148     const Klass* const super_klass = parser.super_klass();
 149     if (super_klass != NULL) {
 150       if (super_klass->is_subtype_of(SystemDictionary::ClassLoader_klass())) {
 151         return true;
 152       }
 153     }
 154   }
 155   return false;
 156 }
 157 
 158 // private: called to verify that k is a static member of this nest.
 159 // We know that k is an instance class in the same package and hence the
 160 // same classloader.
 161 bool InstanceKlass::has_nest_member(InstanceKlass* k, TRAPS) const {
 162   assert(!is_hidden(), "unexpected hidden class");
 163   if (_nest_members == NULL || _nest_members == Universe::the_empty_short_array()) {
 164     if (log_is_enabled(Trace, class, nestmates)) {
 165       ResourceMark rm(THREAD);
 166       log_trace(class, nestmates)("Checked nest membership of %s in non-nest-host class %s",
 167                                   k->external_name(), this->external_name());
 168     }
 169     return false;
 170   }
 171 
 172   if (log_is_enabled(Trace, class, nestmates)) {
 173     ResourceMark rm(THREAD);
 174     log_trace(class, nestmates)("Checking nest membership of %s in %s",
 175                                 k->external_name(), this->external_name());
 176   }
 177 
 178   // Check for a resolved cp entry , else fall back to a name check.
 179   // We don't want to resolve any class other than the one being checked.
 180   for (int i = 0; i < _nest_members->length(); i++) {
 181     int cp_index = _nest_members->at(i);
 182     if (_constants->tag_at(cp_index).is_klass()) {
 183       Klass* k2 = _constants->klass_at(cp_index, THREAD);
 184       assert(!HAS_PENDING_EXCEPTION || PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass()),
 185              "Exceptions should not be possible here");
 186       if (k2 == k) {
 187         log_trace(class, nestmates)("- class is listed at nest_members[%d] => cp[%d]", i, cp_index);
 188         return true;
 189       }
 190     }
 191     else {
 192       Symbol* name = _constants->klass_name_at(cp_index);
 193       if (name == k->name()) {
 194         log_trace(class, nestmates)("- Found it at nest_members[%d] => cp[%d]", i, cp_index);
 195 
 196         // Names match so check actual klass. This may trigger class loading if
 197         // it doesn't match though that should be impossible as it means one classloader
 198         // has defined two different classes with the same name! A compiler thread won't be
 199         // able to perform that loading but we can't exclude the compiler threads from
 200         // executing this logic. But it should actually be impossible to trigger loading here.
 201         Klass* k2 = _constants->klass_at(cp_index, THREAD);
 202         assert(!HAS_PENDING_EXCEPTION || PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass()),
 203                "Exceptions should not be possible here");

 204         if (k2 == k) {
 205           log_trace(class, nestmates)("- class is listed as a nest member");
 206           return true;
 207         }
 208         else {
 209           // same name but different klass!
 210           log_trace(class, nestmates)(" - klass comparison failed!");
 211           // can't have two names the same, so we're done
 212           return false;
 213         }
 214       }
 215     }
 216   }
 217   log_trace(class, nestmates)("- class is NOT a nest member!");
 218   return false;
 219 }
 220 
 221 // Return nest-host class, resolving, validating and saving it if needed.
 222 // In cases where this is called from a thread that cannot do classloading
 223 // (such as a native JIT thread) then we simply return NULL, which in turn
 224 // causes the access check to return false. Such code will retry the access
 225 // from a more suitable environment later. Otherwise the _nest_host is always
 226 // set once this method returns.
 227 // Any errors from nest-host resolution must be preserved so they can be queried
 228 // from higher-level access checking code, and reported as part of access checking
 229 // exceptions.
 230 // VirtualMachineErrors are propagated with a NULL return.
 231 // Under any conditions where the _nest_host can be set to non-NULL the resulting
 232 // value of it and, if applicable, the nest host resolution/validation error,
 233 // are idempotent.
 234 InstanceKlass* InstanceKlass::nest_host(TRAPS) {
 235   InstanceKlass* nest_host_k = _nest_host;
 236   if (nest_host_k != NULL) {
 237     return nest_host_k;
 238   }
 239 
 240   ResourceMark rm(THREAD);
 241 
 242   // need to resolve and save our nest-host class.
 243   if (_nest_host_index != 0) { // we have a real nest_host
 244     // Before trying to resolve check if we're in a suitable context
 245     if (!THREAD->can_call_java() && !_constants->tag_at(_nest_host_index).is_klass()) {


 246       log_trace(class, nestmates)("Rejected resolution of nest-host of %s in unsuitable thread",
 247                                   this->external_name());
 248       return NULL; // sentinel to say "try again from a different context"

 249     }
 250 


 251     log_trace(class, nestmates)("Resolving nest-host of %s using cp entry for %s",
 252                                 this->external_name(),
 253                                 _constants->klass_name_at(_nest_host_index)->as_C_string());

 254 
 255     Klass* k = _constants->klass_at(_nest_host_index, THREAD);
 256     if (HAS_PENDING_EXCEPTION) {
 257       if (PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass())) {
 258         return NULL; // propagate VMEs













 259       }
 260       stringStream ss;
 261       char* target_host_class = _constants->klass_name_at(_nest_host_index)->as_C_string();
 262       ss.print("Nest host resolution of %s with host %s failed: ",
 263                this->external_name(), target_host_class);
 264       java_lang_Throwable::print(PENDING_EXCEPTION, &ss);
 265       const char* msg = ss.as_string(true /* on C-heap */);
 266       constantPoolHandle cph(THREAD, constants());
 267       SystemDictionary::add_nest_host_error(cph, _nest_host_index, msg);
 268       CLEAR_PENDING_EXCEPTION;
 269 
 270       log_trace(class, nestmates)("%s", msg);
 271     } else {
 272       // A valid nest-host is an instance class in the current package that lists this
 273       // class as a nest member. If any of these conditions are not met the class is
 274       // its own nest-host.

 275       const char* error = NULL;
 276 
 277       // JVMS 5.4.4 indicates package check comes first
 278       if (is_same_class_package(k)) {

 279         // Now check actual membership. We can't be a member if our "host" is
 280         // not an instance class.
 281         if (k->is_instance_klass()) {
 282           nest_host_k = InstanceKlass::cast(k);
 283           bool is_member = nest_host_k->has_nest_member(this, THREAD);
 284           // exception is rare, perhaps impossible
 285           if (!HAS_PENDING_EXCEPTION) {
 286             if (is_member) {
 287               _nest_host = nest_host_k; // save resolved nest-host value

 288 


 289               log_trace(class, nestmates)("Resolved nest-host of %s to %s",
 290                                           this->external_name(), k->external_name());

 291               return nest_host_k;
 292             } else {
 293               error = "current type is not listed as a nest member";
 294             }
 295           } else {
 296             if (PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass())) {
 297               return NULL; // propagate VMEs
 298             }
 299             stringStream ss;
 300             ss.print("exception on member check: ");
 301             java_lang_Throwable::print(PENDING_EXCEPTION, &ss);
 302             error = ss.as_string();
 303           }
 304         } else {
 305           error = "host is not an instance class";
 306         }

 307       } else {
 308         error = "types are in different packages";
 309       }
 310 
 311       // something went wrong, so record what and log it
 312       {
 313         stringStream ss;
 314         ss.print("Type %s (loader: %s) is not a nest member of type %s (loader: %s): %s",

 315                  this->external_name(),
 316                  this->class_loader_data()->loader_name_and_id(),
 317                  k->external_name(),
 318                  k->class_loader_data()->loader_name_and_id(),
 319                  error);
 320         const char* msg = ss.as_string(true /* on C-heap */);
 321         constantPoolHandle cph(THREAD, constants());
 322         SystemDictionary::add_nest_host_error(cph, _nest_host_index, msg);
 323         log_trace(class, nestmates)("%s", msg);
 324       }












 325     }

 326   } else {


 327     log_trace(class, nestmates)("Type %s is not part of a nest: setting nest-host to self",
 328                                 this->external_name());
 329   }
 330 
 331   // Either not in an explicit nest, or else an error occurred, so
 332   // the nest-host is set to `this`. Any thread that sees this assignment
 333   // will also see any setting of nest_host_error(), if applicable.
 334   return (_nest_host = this);
 335 }
 336 
 337 // Dynamic nest member support: set this class's nest host to the given class.
 338 // This occurs as part of the class definition, as soon as the instanceKlass
 339 // has been created and doesn't require further resolution. The code:
 340 //    lookup().defineHiddenClass(bytes_for_X, NESTMATE);
 341 // results in:
 342 //    class_of_X.set_nest_host(lookup().lookupClass().getNestHost())
 343 // If it has an explicit _nest_host_index or _nest_members, these will be ignored.
 344 // We also know the "host" is a valid nest-host in the same package so we can
 345 // assert some of those facts.
 346 void InstanceKlass::set_nest_host(InstanceKlass* host, TRAPS) {
 347   assert(is_hidden(), "must be a hidden class");
 348   assert(host != NULL, "NULL nest host specified");
 349   assert(_nest_host == NULL, "current class has resolved nest-host");
 350   assert(nest_host_error(THREAD) == NULL, "unexpected nest host resolution error exists: %s",
 351          nest_host_error(THREAD));
 352   assert((host->_nest_host == NULL && host->_nest_host_index == 0) ||
 353          (host->_nest_host == host), "proposed host is not a valid nest-host");
 354   // Can't assert this as package is not set yet:
 355   // assert(is_same_class_package(host), "proposed host is in wrong package");
 356 
 357   if (log_is_enabled(Trace, class, nestmates)) {
 358     ResourceMark rm(THREAD);
 359     const char* msg = "";
 360     // a hidden class does not expect a statically defined nest-host
 361     if (_nest_host_index > 0) {
 362       msg = "(the NestHost attribute in the current class is ignored)";
 363     } else if (_nest_members != NULL && _nest_members != Universe::the_empty_short_array()) {
 364       msg = "(the NestMembers attribute in the current class is ignored)";
 365     }
 366     log_trace(class, nestmates)("Injected type %s into the nest of %s %s",
 367                                 this->external_name(),
 368                                 host->external_name(),
 369                                 msg);
 370   }
 371   // set dynamic nest host
 372   _nest_host = host;
 373   // Record dependency to keep nest host from being unloaded before this class.
 374   ClassLoaderData* this_key = class_loader_data();
 375   this_key->record_dependency(host);
 376 }
 377 
 378 // check if 'this' and k are nestmates (same nest_host), or k is our nest_host,
 379 // or we are k's nest_host - all of which is covered by comparing the two
 380 // resolved_nest_hosts.
 381 // Any exceptions (i.e. VMEs) are propagated.
 382 bool InstanceKlass::has_nestmate_access_to(InstanceKlass* k, TRAPS) {
 383 
 384   assert(this != k, "this should be handled by higher-level code");
 385 
 386   // Per JVMS 5.4.4 we first resolve and validate the current class, then
 387   // the target class k.


 388 
 389   InstanceKlass* cur_host = nest_host(CHECK_false);

 390   if (cur_host == NULL) {
 391     return false;
 392   }
 393 
 394   Klass* k_nest_host = k->nest_host(CHECK_false);
 395   if (k_nest_host == NULL) {
 396     return false;
 397   }
 398 
 399   bool access = (cur_host == k_nest_host);
 400 

 401   ResourceMark rm(THREAD);
 402   log_trace(class, nestmates)("Class %s does %shave nestmate access to %s",
 403                               this->external_name(),
 404                               access ? "" : "NOT ",
 405                               k->external_name());


 406   return access;
 407 }
 408 
 409 const char* InstanceKlass::nest_host_error(TRAPS) {
 410   if (_nest_host_index == 0) {
 411     return NULL;
 412   } else {
 413     constantPoolHandle cph(THREAD, constants());
 414     return SystemDictionary::find_nest_host_error(cph, (int)_nest_host_index);
 415   }
 416 }
 417 
 418 InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& parser, TRAPS) {
 419   bool is_hidden_or_anonymous = parser.is_hidden() || parser.is_unsafe_anonymous();
 420   const int size = InstanceKlass::size(parser.vtable_size(),
 421                                        parser.itable_size(),
 422                                        nonstatic_oop_map_size(parser.total_oop_map_count()),
 423                                        parser.is_interface(),
 424                                        parser.is_unsafe_anonymous(),
 425                                        should_store_fingerprint(is_hidden_or_anonymous));
 426 
 427   const Symbol* const class_name = parser.class_name();
 428   assert(class_name != NULL, "invariant");
 429   ClassLoaderData* loader_data = parser.loader_data();
 430   assert(loader_data != NULL, "invariant");
 431 
 432   InstanceKlass* ik;
 433 
 434   // Allocation
 435   if (REF_NONE == parser.reference_type()) {
 436     if (class_name == vmSymbols::java_lang_Class()) {
 437       // mirror
 438       ik = new (loader_data, size, THREAD) InstanceMirrorKlass(parser);
 439     }
 440     else if (is_class_loader(class_name, parser)) {
 441       // class loader
 442       ik = new (loader_data, size, THREAD) InstanceClassLoaderKlass(parser);
 443     } else {
 444       // normal
 445       ik = new (loader_data, size, THREAD) InstanceKlass(parser, InstanceKlass::_misc_kind_other);


 479   set_default_vtable_indices(vtable_indices);
 480   return vtable_indices;
 481 }
 482 
 483 InstanceKlass::InstanceKlass(const ClassFileParser& parser, unsigned kind, KlassID id) :
 484   Klass(id),
 485   _nest_members(NULL),
 486   _nest_host_index(0),
 487   _nest_host(NULL),
 488   _record_components(NULL),
 489   _static_field_size(parser.static_field_size()),
 490   _nonstatic_oop_map_size(nonstatic_oop_map_size(parser.total_oop_map_count())),
 491   _itable_len(parser.itable_size()),
 492   _init_thread(NULL),
 493   _init_state(allocated),
 494   _reference_type(parser.reference_type())
 495 {
 496   set_vtable_length(parser.vtable_size());
 497   set_kind(kind);
 498   set_access_flags(parser.access_flags());
 499   if (parser.is_hidden()) set_is_hidden();
 500   set_is_unsafe_anonymous(parser.is_unsafe_anonymous());
 501   set_layout_helper(Klass::instance_layout_helper(parser.layout_size(),
 502                                                     false));
 503 
 504   assert(NULL == _methods, "underlying memory not zeroed?");
 505   assert(is_instance_klass(), "is layout incorrect?");
 506   assert(size_helper() == parser.layout_size(), "incorrect size_helper?");
 507 
 508   if (Arguments::is_dumping_archive()) {
 509     SystemDictionaryShared::init_dumptime_info(this);
 510   }
 511 
 512   // Set biased locking bit for all instances of this class; it will be
 513   // cleared if revocation occurs too often for this type
 514   if (UseBiasedLocking && BiasedLocking::enabled()) {
 515     set_prototype_header(markWord::biased_locking_prototype());
 516   }
 517 }
 518 
 519 void InstanceKlass::deallocate_methods(ClassLoaderData* loader_data,


2309     log_trace(class, fingerprint)("%s : super %s not fingerprinted", external_name(), java_super()->external_name());
2310     return false;
2311   }
2312 
2313   Array<InstanceKlass*>* local_interfaces = this->local_interfaces();
2314   if (local_interfaces != NULL) {
2315     int length = local_interfaces->length();
2316     for (int i = 0; i < length; i++) {
2317       InstanceKlass* intf = local_interfaces->at(i);
2318       if (!intf->has_passed_fingerprint_check()) {
2319         ResourceMark rm;
2320         log_trace(class, fingerprint)("%s : interface %s not fingerprinted", external_name(), intf->external_name());
2321         return false;
2322       }
2323     }
2324   }
2325 
2326   return true;
2327 }
2328 
2329 bool InstanceKlass::should_store_fingerprint(bool is_hidden_or_anonymous) {
2330 #if INCLUDE_AOT
2331   // We store the fingerprint into the InstanceKlass only in the following 2 cases:
2332   if (CalculateClassFingerprint) {
2333     // (1) We are running AOT to generate a shared library.
2334     return true;
2335   }
2336   if (Arguments::is_dumping_archive()) {
2337     // (2) We are running -Xshare:dump or -XX:ArchiveClassesAtExit to create a shared archive
2338     return true;
2339   }
2340   if (UseAOT && is_hidden_or_anonymous) {
2341     // (3) We are using AOT code from a shared library and see a hidden or unsafe anonymous class
2342     return true;
2343   }
2344 #endif
2345 
2346   // In all other cases we might set the _misc_has_passed_fingerprint_check bit,
2347   // but do not store the 64-bit fingerprint to save space.
2348   return false;
2349 }
2350 
2351 bool InstanceKlass::has_stored_fingerprint() const {
2352 #if INCLUDE_AOT
2353   return should_store_fingerprint() || is_shared();
2354 #else
2355   return false;
2356 #endif
2357 }
2358 
2359 uint64_t InstanceKlass::get_stored_fingerprint() const {
2360   address adr = adr_fingerprint();
2361   if (adr != NULL) {


2613 
2614   assert(_dep_context == NULL,
2615          "dependencies should already be cleaned");
2616 
2617 #if INCLUDE_JVMTI
2618   // Deallocate breakpoint records
2619   if (breakpoints() != 0x0) {
2620     methods_do(clear_all_breakpoints);
2621     assert(breakpoints() == 0x0, "should have cleared breakpoints");
2622   }
2623 
2624   // deallocate the cached class file
2625   if (_cached_class_file != NULL) {
2626     os::free(_cached_class_file);
2627     _cached_class_file = NULL;
2628   }
2629 #endif
2630 
2631   // Decrement symbol reference counts associated with the unloaded class.
2632   if (_name != NULL) _name->decrement_refcount();
2633 
2634   // unreference array name derived from this class name (arrays of an unloaded
2635   // class can't be referenced anymore).
2636   if (_array_name != NULL)  _array_name->decrement_refcount();
2637   FREE_C_HEAP_ARRAY(char, _source_debug_extension);
2638 }
2639 
2640 void InstanceKlass::set_source_debug_extension(const char* array, int length) {
2641   if (array == NULL) {
2642     _source_debug_extension = NULL;
2643   } else {
2644     // Adding one to the attribute length in order to store a null terminator
2645     // character could cause an overflow because the attribute length is
2646     // already coded with an u4 in the classfile, but in practice, it's
2647     // unlikely to happen.
2648     assert((length+1) > length, "Overflow checking");
2649     char* sde = NEW_C_HEAP_ARRAY(char, (length + 1), mtClass);
2650     for (int i = 0; i < length; i++) {
2651       sde[i] = array[i];
2652     }
2653     sde[length] = '\0';


2664     intptr_t hash = (java_mirror() != NULL) ? java_mirror()->identity_hash() : 0;
2665     jio_snprintf(hash_buf, sizeof(hash_buf), "/" UINTX_FORMAT, (uintx)hash);
2666     hash_len = (int)strlen(hash_buf);
2667   }
2668 
2669   // Get the internal name as a c string
2670   const char* src = (const char*) (name()->as_C_string());
2671   const int src_length = (int)strlen(src);
2672 
2673   char* dest = NEW_RESOURCE_ARRAY(char, src_length + hash_len + 3);
2674 
2675   // Add L as type indicator
2676   int dest_index = 0;
2677   dest[dest_index++] = JVM_SIGNATURE_CLASS;
2678 
2679   // Add the actual class name
2680   for (int src_index = 0; src_index < src_length; ) {
2681     dest[dest_index++] = src[src_index++];
2682   }
2683 
2684   if (is_hidden()) { // Replace the last '+' with a '.'.
2685     for (int index = (int)src_length; index > 0; index--) {
2686       if (dest[index] == '+') {
2687         dest[index] = JVM_SIGNATURE_DOT;
2688         break;
2689       }
2690     }
2691   }
2692 
2693   // If we have a hash, append it
2694   for (int hash_index = 0; hash_index < hash_len; ) {
2695     dest[dest_index++] = hash_buf[hash_index++];
2696   }
2697 
2698   // Add the semicolon and the NULL
2699   dest[dest_index++] = JVM_SIGNATURE_ENDCLASS;
2700   dest[dest_index] = '\0';
2701   return dest;
2702 }
2703 
2704 ModuleEntry* InstanceKlass::module() const {
2705   // For an unsafe anonymous class return the host class' module
2706   if (is_unsafe_anonymous()) {
2707     assert(unsafe_anonymous_host() != NULL, "unsafe anonymous class must have a host class");
2708     return unsafe_anonymous_host()->module();
2709   }
2710 
2711   if (is_hidden() &&
2712       in_unnamed_package() &&
2713       class_loader_data()->has_class_mirror_holder()) {
2714     // For a weak hidden class defined to an unnamed package,
2715     // its (class held) CLD will not have an unnamed module created for it.
2716     // Two choices to find the correct ModuleEntry:
2717     // 1. If hidden class is within a nest, use nest host's module
2718     // 2. Find the unnamed module off from the class loader
2719     // For now option #2 is used since a nest host is not set until
2720     // after the instance class is created in jvm_lookup_define_class().
2721     if (class_loader_data()->is_boot_class_loader_data()) {
2722       return ClassLoaderData::the_null_class_loader_data()->unnamed_module();
2723     } else {
2724       oop module = java_lang_ClassLoader::unnamedModule(class_loader_data()->class_loader());
2725       assert(java_lang_Module::is_instance(module), "Not an instance of java.lang.Module");
2726       return java_lang_Module::module_entry(module);
2727     }
2728   }
2729 
2730   // Class is in a named package
2731   if (!in_unnamed_package()) {
2732     return _package_entry->module();
2733   }
2734 
2735   // Class is in an unnamed package, return its loader's unnamed module
2736   return class_loader_data()->unnamed_module();
2737 }
2738 
2739 void InstanceKlass::set_package(ClassLoaderData* loader_data, TRAPS) {
2740 
2741   // ensure java/ packages only loaded by boot or platform builtin loaders
2742   check_prohibited_package(name(), loader_data, CHECK);
2743 
2744   TempNewSymbol pkg_name = ClassLoader::package_from_class_name(name());
2745 
2746   if (pkg_name != NULL && loader_data != NULL) {
2747 
2748     // Find in class loader's package entry table.
2749     _package_entry = loader_data->packages()->lookup_only(pkg_name);


2920         }
2921       }
2922     }
2923   }
2924   return false;
2925 }
2926 
2927 InstanceKlass* InstanceKlass::compute_enclosing_class(bool* inner_is_member, TRAPS) const {
2928   InstanceKlass* outer_klass = NULL;
2929   *inner_is_member = false;
2930   int ooff = 0, noff = 0;
2931   bool has_inner_classes_attr = find_inner_classes_attr(&ooff, &noff, THREAD);
2932   if (has_inner_classes_attr) {
2933     constantPoolHandle i_cp(THREAD, constants());
2934     if (ooff != 0) {
2935       Klass* ok = i_cp->klass_at(ooff, CHECK_NULL);
2936       outer_klass = InstanceKlass::cast(ok);
2937       *inner_is_member = true;
2938     }
2939     if (NULL == outer_klass) {
2940       // It may be a local or anonymous class; try for that.
2941       int encl_method_class_idx = enclosing_method_class_index();
2942       if (encl_method_class_idx != 0) {
2943         Klass* ok = i_cp->klass_at(encl_method_class_idx, CHECK_NULL);
2944         outer_klass = InstanceKlass::cast(ok);
2945         *inner_is_member = false;
2946       }
2947     }
2948   }
2949 
2950   // If no inner class attribute found for this class.
2951   if (NULL == outer_klass) return NULL;
2952 
2953   // Throws an exception if outer klass has not declared k as an inner klass
2954   // We need evidence that each klass knows about the other, or else
2955   // the system could allow a spoof of an inner class to gain access rights.
2956   Reflection::check_for_inner_class(outer_klass, this, *inner_is_member, CHECK_NULL);
2957   return outer_klass;
2958 }
2959 
2960 jint InstanceKlass::compute_modifier_flags(TRAPS) const {


< prev index next >