237 // already been created, it is returned. Otherwise, a new ciObject |
237 // already been created, it is returned. Otherwise, a new ciObject |
238 // is created. |
238 // is created. |
239 ciObject* ciObjectFactory::get(oop key) { |
239 ciObject* ciObjectFactory::get(oop key) { |
240 ASSERT_IN_VM; |
240 ASSERT_IN_VM; |
241 |
241 |
242 assert(key == NULL || Universe::heap()->is_in_reserved(key), "must be"); |
242 assert(Universe::heap()->is_in_reserved(key), "must be"); |
243 |
243 |
244 NonPermObject* &bucket = find_non_perm(key); |
244 NonPermObject* &bucket = find_non_perm(key); |
245 if (bucket != NULL) { |
245 if (bucket != NULL) { |
246 return bucket->object(); |
246 return bucket->object(); |
247 } |
247 } |
258 insert_non_perm(bucket, keyHandle(), new_object); |
258 insert_non_perm(bucket, keyHandle(), new_object); |
259 return new_object; |
259 return new_object; |
260 } |
260 } |
261 |
261 |
262 // ------------------------------------------------------------------ |
262 // ------------------------------------------------------------------ |
263 // ciObjectFactory::get |
263 // ciObjectFactory::get_metadata |
264 // |
264 // |
265 // Get the ciObject corresponding to some oop. If the ciObject has |
265 // Get the ciMetadata corresponding to some Metadata. If the ciMetadata has |
266 // already been created, it is returned. Otherwise, a new ciObject |
266 // already been created, it is returned. Otherwise, a new ciMetadata |
267 // is created. |
267 // is created. |
268 ciMetadata* ciObjectFactory::get_metadata(Metadata* key) { |
268 ciMetadata* ciObjectFactory::get_metadata(Metadata* key) { |
269 ASSERT_IN_VM; |
269 ASSERT_IN_VM; |
270 |
270 |
271 #ifdef ASSERT |
271 #ifdef ASSERT |
288 } |
288 } |
289 } |
289 } |
290 } |
290 } |
291 #endif |
291 #endif |
292 if (!is_found_at(index, key, _ci_metadata)) { |
292 if (!is_found_at(index, key, _ci_metadata)) { |
293 // The ciObject does not yet exist. Create it and insert it |
293 // The ciMetadata does not yet exist. Create it and insert it |
294 // into the cache. |
294 // into the cache. |
295 ciMetadata* new_object = create_new_object(key); |
295 ciMetadata* new_object = create_new_metadata(key); |
296 init_ident_of(new_object); |
296 init_ident_of(new_object); |
297 assert(new_object->is_metadata(), "must be"); |
297 assert(new_object->is_metadata(), "must be"); |
298 |
298 |
299 if (len != _ci_metadata->length()) { |
299 if (len != _ci_metadata->length()) { |
300 // creating the new object has recursively entered new objects |
300 // creating the new object has recursively entered new objects |
342 ShouldNotReachHere(); |
342 ShouldNotReachHere(); |
343 return NULL; |
343 return NULL; |
344 } |
344 } |
345 |
345 |
346 // ------------------------------------------------------------------ |
346 // ------------------------------------------------------------------ |
347 // ciObjectFactory::create_new_object |
347 // ciObjectFactory::create_new_metadata |
348 // |
348 // |
349 // Create a new ciObject from a Metadata*. |
349 // Create a new ciMetadata from a Metadata*. |
350 // |
350 // |
351 // Implementation note: this functionality could be virtual behavior |
351 // Implementation note: in order to keep Metadata live, an auxiliary ciObject |
352 // of the oop itself. For now, we explicitly marshal the object. |
352 // is used, which points to it's holder. |
353 ciMetadata* ciObjectFactory::create_new_object(Metadata* o) { |
353 ciMetadata* ciObjectFactory::create_new_metadata(Metadata* o) { |
354 EXCEPTION_CONTEXT; |
354 EXCEPTION_CONTEXT; |
|
355 |
|
356 // Hold metadata from unloading by keeping it's holder alive. |
|
357 if (_initialized && o->is_klass()) { |
|
358 Klass* holder = ((Klass*)o); |
|
359 if (holder->oop_is_instance() && InstanceKlass::cast(holder)->is_anonymous()) { |
|
360 // Though ciInstanceKlass records class loader oop, it's not enough to keep |
|
361 // VM anonymous classes alive (loader == NULL). Klass holder should be used instead. |
|
362 // It is enough to record a ciObject, since cached elements are never removed |
|
363 // during ciObjectFactory lifetime. ciObjectFactory itself is created for |
|
364 // every compilation and lives for the whole duration of the compilation. |
|
365 ciObject* h = get(holder->klass_holder()); |
|
366 } |
|
367 } |
355 |
368 |
356 if (o->is_klass()) { |
369 if (o->is_klass()) { |
357 KlassHandle h_k(THREAD, (Klass*)o); |
370 KlassHandle h_k(THREAD, (Klass*)o); |
358 Klass* k = (Klass*)o; |
371 Klass* k = (Klass*)o; |
359 if (k->oop_is_instance()) { |
372 if (k->oop_is_instance()) { |
363 } else if (k->oop_is_typeArray()) { |
376 } else if (k->oop_is_typeArray()) { |
364 return new (arena()) ciTypeArrayKlass(h_k); |
377 return new (arena()) ciTypeArrayKlass(h_k); |
365 } |
378 } |
366 } else if (o->is_method()) { |
379 } else if (o->is_method()) { |
367 methodHandle h_m(THREAD, (Method*)o); |
380 methodHandle h_m(THREAD, (Method*)o); |
368 return new (arena()) ciMethod(h_m); |
381 ciEnv *env = CURRENT_THREAD_ENV; |
|
382 ciInstanceKlass* holder = env->get_instance_klass(h_m()->method_holder()); |
|
383 return new (arena()) ciMethod(h_m, holder); |
369 } else if (o->is_methodData()) { |
384 } else if (o->is_methodData()) { |
370 // Hold methodHandle alive - might not be necessary ??? |
385 // Hold methodHandle alive - might not be necessary ??? |
371 methodHandle h_m(THREAD, ((MethodData*)o)->method()); |
386 methodHandle h_m(THREAD, ((MethodData*)o)->method()); |
372 return new (arena()) ciMethodData((MethodData*)o); |
387 return new (arena()) ciMethodData((MethodData*)o); |
373 } |
388 } |
374 |
389 |
375 // The oop is of some type not supported by the compiler interface. |
390 // The Metadata* is of some type not supported by the compiler interface. |
376 ShouldNotReachHere(); |
391 ShouldNotReachHere(); |
377 return NULL; |
392 return NULL; |
378 } |
393 } |
379 |
394 |
380 // ------------------------------------------------------------------ |
395 // ------------------------------------------------------------------ |
699 // |
714 // |
700 // Use a small hash table, hashed on the klass of the key. |
715 // Use a small hash table, hashed on the klass of the key. |
701 // If there is no entry in the cache corresponding to this oop, return |
716 // If there is no entry in the cache corresponding to this oop, return |
702 // the null tail of the bucket into which the oop should be inserted. |
717 // the null tail of the bucket into which the oop should be inserted. |
703 ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) { |
718 ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) { |
704 assert(Universe::heap()->is_in_reserved_or_null(key), "must be"); |
719 assert(Universe::heap()->is_in_reserved(key), "must be"); |
705 ciMetadata* klass = get_metadata(key->klass()); |
720 ciMetadata* klass = get_metadata(key->klass()); |
706 NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS]; |
721 NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS]; |
707 for (NonPermObject* p; (p = (*bp)) != NULL; bp = &p->next()) { |
722 for (NonPermObject* p; (p = (*bp)) != NULL; bp = &p->next()) { |
708 if (is_equal(p, key)) break; |
723 if (is_equal(p, key)) break; |
709 } |
724 } |