1.1 --- a/src/share/vm/ci/ciObjectFactory.cpp Fri Oct 24 09:13:12 2014 -0700 1.2 +++ b/src/share/vm/ci/ciObjectFactory.cpp Tue Nov 11 04:46:13 2014 -0800 1.3 @@ -239,7 +239,7 @@ 1.4 ciObject* ciObjectFactory::get(oop key) { 1.5 ASSERT_IN_VM; 1.6 1.7 - assert(key == NULL || Universe::heap()->is_in_reserved(key), "must be"); 1.8 + assert(Universe::heap()->is_in_reserved(key), "must be"); 1.9 1.10 NonPermObject* &bucket = find_non_perm(key); 1.11 if (bucket != NULL) { 1.12 @@ -260,10 +260,10 @@ 1.13 } 1.14 1.15 // ------------------------------------------------------------------ 1.16 -// ciObjectFactory::get 1.17 +// ciObjectFactory::get_metadata 1.18 // 1.19 -// Get the ciObject corresponding to some oop. If the ciObject has 1.20 -// already been created, it is returned. Otherwise, a new ciObject 1.21 +// Get the ciMetadata corresponding to some Metadata. If the ciMetadata has 1.22 +// already been created, it is returned. Otherwise, a new ciMetadata 1.23 // is created. 1.24 ciMetadata* ciObjectFactory::get_metadata(Metadata* key) { 1.25 ASSERT_IN_VM; 1.26 @@ -290,9 +290,9 @@ 1.27 } 1.28 #endif 1.29 if (!is_found_at(index, key, _ci_metadata)) { 1.30 - // The ciObject does not yet exist. Create it and insert it 1.31 + // The ciMetadata does not yet exist. Create it and insert it 1.32 // into the cache. 1.33 - ciMetadata* new_object = create_new_object(key); 1.34 + ciMetadata* new_object = create_new_metadata(key); 1.35 init_ident_of(new_object); 1.36 assert(new_object->is_metadata(), "must be"); 1.37 1.38 @@ -344,15 +344,28 @@ 1.39 } 1.40 1.41 // ------------------------------------------------------------------ 1.42 -// ciObjectFactory::create_new_object 1.43 +// ciObjectFactory::create_new_metadata 1.44 // 1.45 -// Create a new ciObject from a Metadata*. 1.46 +// Create a new ciMetadata from a Metadata*. 1.47 // 1.48 -// Implementation note: this functionality could be virtual behavior 1.49 -// of the oop itself. For now, we explicitly marshal the object. 1.50 -ciMetadata* ciObjectFactory::create_new_object(Metadata* o) { 1.51 +// Implementation note: in order to keep Metadata live, an auxiliary ciObject 1.52 +// is used, which points to it's holder. 1.53 +ciMetadata* ciObjectFactory::create_new_metadata(Metadata* o) { 1.54 EXCEPTION_CONTEXT; 1.55 1.56 + // Hold metadata from unloading by keeping it's holder alive. 1.57 + if (_initialized && o->is_klass()) { 1.58 + Klass* holder = ((Klass*)o); 1.59 + if (holder->oop_is_instance() && InstanceKlass::cast(holder)->is_anonymous()) { 1.60 + // Though ciInstanceKlass records class loader oop, it's not enough to keep 1.61 + // VM anonymous classes alive (loader == NULL). Klass holder should be used instead. 1.62 + // It is enough to record a ciObject, since cached elements are never removed 1.63 + // during ciObjectFactory lifetime. ciObjectFactory itself is created for 1.64 + // every compilation and lives for the whole duration of the compilation. 1.65 + ciObject* h = get(holder->klass_holder()); 1.66 + } 1.67 + } 1.68 + 1.69 if (o->is_klass()) { 1.70 KlassHandle h_k(THREAD, (Klass*)o); 1.71 Klass* k = (Klass*)o; 1.72 @@ -365,14 +378,16 @@ 1.73 } 1.74 } else if (o->is_method()) { 1.75 methodHandle h_m(THREAD, (Method*)o); 1.76 - return new (arena()) ciMethod(h_m); 1.77 + ciEnv *env = CURRENT_THREAD_ENV; 1.78 + ciInstanceKlass* holder = env->get_instance_klass(h_m()->method_holder()); 1.79 + return new (arena()) ciMethod(h_m, holder); 1.80 } else if (o->is_methodData()) { 1.81 // Hold methodHandle alive - might not be necessary ??? 1.82 methodHandle h_m(THREAD, ((MethodData*)o)->method()); 1.83 return new (arena()) ciMethodData((MethodData*)o); 1.84 } 1.85 1.86 - // The oop is of some type not supported by the compiler interface. 1.87 + // The Metadata* is of some type not supported by the compiler interface. 1.88 ShouldNotReachHere(); 1.89 return NULL; 1.90 } 1.91 @@ -701,7 +716,7 @@ 1.92 // If there is no entry in the cache corresponding to this oop, return 1.93 // the null tail of the bucket into which the oop should be inserted. 1.94 ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) { 1.95 - assert(Universe::heap()->is_in_reserved_or_null(key), "must be"); 1.96 + assert(Universe::heap()->is_in_reserved(key), "must be"); 1.97 ciMetadata* klass = get_metadata(key->klass()); 1.98 NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS]; 1.99 for (NonPermObject* p; (p = (*bp)) != NULL; bp = &p->next()) {