Mercurial > hg > truffle
comparison src/share/vm/ci/ciObjectFactory.cpp @ 20804:7848fc12602b
Merge with jdk8u40-b25
author | Gilles Duboscq <gilles.m.duboscq@oracle.com> |
---|---|
date | Tue, 07 Apr 2015 14:58:49 +0200 |
parents | 89152779163c 6a528388c7da |
children |
comparison
equal
deleted
inserted
replaced
20184:84105dcdb05b | 20804:7848fc12602b |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
44 #include "gc_interface/collectedHeap.inline.hpp" | 44 #include "gc_interface/collectedHeap.inline.hpp" |
45 #include "memory/allocation.inline.hpp" | 45 #include "memory/allocation.inline.hpp" |
46 #include "oops/oop.inline.hpp" | 46 #include "oops/oop.inline.hpp" |
47 #include "oops/oop.inline2.hpp" | 47 #include "oops/oop.inline2.hpp" |
48 #include "runtime/fieldType.hpp" | 48 #include "runtime/fieldType.hpp" |
49 #if INCLUDE_ALL_GCS | |
50 # include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" | |
51 #endif | |
49 | 52 |
50 // ciObjectFactory | 53 // ciObjectFactory |
51 // | 54 // |
52 // This class handles requests for the creation of new instances | 55 // This class handles requests for the creation of new instances |
53 // of ciObject and its subclasses. It contains a caching mechanism | 56 // of ciObject and its subclasses. It contains a caching mechanism |
107 HandleMark handle_mark(thread); | 110 HandleMark handle_mark(thread); |
108 | 111 |
109 // This Arena is long lived and exists in the resource mark of the | 112 // This Arena is long lived and exists in the resource mark of the |
110 // compiler thread that initializes the initial ciObjectFactory which | 113 // compiler thread that initializes the initial ciObjectFactory which |
111 // creates the shared ciObjects that all later ciObjectFactories use. | 114 // creates the shared ciObjects that all later ciObjectFactories use. |
112 Arena* arena = new (mtCompiler) Arena(); | 115 Arena* arena = new (mtCompiler) Arena(mtCompiler); |
113 ciEnv initial(arena); | 116 ciEnv initial(arena); |
114 ciEnv* env = ciEnv::current(); | 117 ciEnv* env = ciEnv::current(); |
115 env->_factory->init_shared_objects(); | 118 env->_factory->init_shared_objects(); |
116 | 119 |
117 _initialized = true; | 120 _initialized = true; |
234 // already been created, it is returned. Otherwise, a new ciObject | 237 // already been created, it is returned. Otherwise, a new ciObject |
235 // is created. | 238 // is created. |
236 ciObject* ciObjectFactory::get(oop key) { | 239 ciObject* ciObjectFactory::get(oop key) { |
237 ASSERT_IN_VM; | 240 ASSERT_IN_VM; |
238 | 241 |
239 assert(key == NULL || Universe::heap()->is_in_reserved(key), "must be"); | 242 assert(Universe::heap()->is_in_reserved(key), "must be"); |
240 | 243 |
241 NonPermObject* &bucket = find_non_perm(key); | 244 NonPermObject* &bucket = find_non_perm(key); |
242 if (bucket != NULL) { | 245 if (bucket != NULL) { |
243 return bucket->object(); | 246 return bucket->object(); |
244 } | 247 } |
255 insert_non_perm(bucket, keyHandle(), new_object); | 258 insert_non_perm(bucket, keyHandle(), new_object); |
256 return new_object; | 259 return new_object; |
257 } | 260 } |
258 | 261 |
259 // ------------------------------------------------------------------ | 262 // ------------------------------------------------------------------ |
260 // ciObjectFactory::get | 263 // ciObjectFactory::get_metadata |
261 // | 264 // |
262 // Get the ciObject corresponding to some oop. If the ciObject has | 265 // Get the ciMetadata corresponding to some Metadata. If the ciMetadata has |
263 // already been created, it is returned. Otherwise, a new ciObject | 266 // already been created, it is returned. Otherwise, a new ciMetadata |
264 // is created. | 267 // is created. |
265 ciMetadata* ciObjectFactory::get_metadata(Metadata* key) { | 268 ciMetadata* ciObjectFactory::get_metadata(Metadata* key) { |
266 ASSERT_IN_VM; | 269 ASSERT_IN_VM; |
267 | 270 |
268 #ifdef ASSERT | 271 #ifdef ASSERT |
285 } | 288 } |
286 } | 289 } |
287 } | 290 } |
288 #endif | 291 #endif |
289 if (!is_found_at(index, key, _ci_metadata)) { | 292 if (!is_found_at(index, key, _ci_metadata)) { |
290 // The ciObject does not yet exist. Create it and insert it | 293 // The ciMetadata does not yet exist. Create it and insert it |
291 // into the cache. | 294 // into the cache. |
292 ciMetadata* new_object = create_new_object(key); | 295 ciMetadata* new_object = create_new_metadata(key); |
293 init_ident_of(new_object); | 296 init_ident_of(new_object); |
294 assert(new_object->is_metadata(), "must be"); | 297 assert(new_object->is_metadata(), "must be"); |
295 | 298 |
296 if (len != _ci_metadata->length()) { | 299 if (len != _ci_metadata->length()) { |
297 // creating the new object has recursively entered new objects | 300 // creating the new object has recursively entered new objects |
339 ShouldNotReachHere(); | 342 ShouldNotReachHere(); |
340 return NULL; | 343 return NULL; |
341 } | 344 } |
342 | 345 |
343 // ------------------------------------------------------------------ | 346 // ------------------------------------------------------------------ |
344 // ciObjectFactory::create_new_object | 347 // ciObjectFactory::create_new_metadata |
345 // | 348 // |
346 // Create a new ciObject from a Metadata*. | 349 // Create a new ciMetadata from a Metadata*. |
347 // | 350 // |
348 // Implementation note: this functionality could be virtual behavior | 351 // Implementation note: in order to keep Metadata live, an auxiliary ciObject |
349 // of the oop itself. For now, we explicitly marshal the object. | 352 // is used, which points to it's holder. |
350 ciMetadata* ciObjectFactory::create_new_object(Metadata* o) { | 353 ciMetadata* ciObjectFactory::create_new_metadata(Metadata* o) { |
351 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 } | |
352 | 368 |
353 if (o->is_klass()) { | 369 if (o->is_klass()) { |
354 KlassHandle h_k(THREAD, (Klass*)o); | 370 KlassHandle h_k(THREAD, (Klass*)o); |
355 Klass* k = (Klass*)o; | 371 Klass* k = (Klass*)o; |
356 if (k->oop_is_instance()) { | 372 if (k->oop_is_instance()) { |
360 } else if (k->oop_is_typeArray()) { | 376 } else if (k->oop_is_typeArray()) { |
361 return new (arena()) ciTypeArrayKlass(h_k); | 377 return new (arena()) ciTypeArrayKlass(h_k); |
362 } | 378 } |
363 } else if (o->is_method()) { | 379 } else if (o->is_method()) { |
364 methodHandle h_m(THREAD, (Method*)o); | 380 methodHandle h_m(THREAD, (Method*)o); |
365 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); | |
366 } else if (o->is_methodData()) { | 384 } else if (o->is_methodData()) { |
367 // Hold methodHandle alive - might not be necessary ??? | 385 // Hold methodHandle alive - might not be necessary ??? |
368 methodHandle h_m(THREAD, ((MethodData*)o)->method()); | 386 methodHandle h_m(THREAD, ((MethodData*)o)->method()); |
369 return new (arena()) ciMethodData((MethodData*)o); | 387 return new (arena()) ciMethodData((MethodData*)o); |
370 } | 388 } |
371 | 389 |
372 // 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. |
373 ShouldNotReachHere(); | 391 ShouldNotReachHere(); |
374 return NULL; | 392 return NULL; |
393 } | |
394 | |
395 // ------------------------------------------------------------------ | |
396 // ciObjectFactory::ensure_metadata_alive | |
397 // | |
398 // Ensure that the metadata wrapped by the ciMetadata is kept alive by GC. | |
399 // This is primarily useful for metadata which is considered as weak roots | |
400 // by the GC but need to be strong roots if reachable from a current compilation. | |
401 // | |
402 void ciObjectFactory::ensure_metadata_alive(ciMetadata* m) { | |
403 ASSERT_IN_VM; // We're handling raw oops here. | |
404 | |
405 #if INCLUDE_ALL_GCS | |
406 if (!UseG1GC) { | |
407 return; | |
408 } | |
409 Klass* metadata_owner_klass; | |
410 if (m->is_klass()) { | |
411 metadata_owner_klass = m->as_klass()->get_Klass(); | |
412 } else if (m->is_method()) { | |
413 metadata_owner_klass = m->as_method()->get_Method()->constants()->pool_holder(); | |
414 } else { | |
415 fatal("Not implemented for other types of metadata"); | |
416 } | |
417 | |
418 oop metadata_holder = metadata_owner_klass->klass_holder(); | |
419 if (metadata_holder != NULL) { | |
420 G1SATBCardTableModRefBS::enqueue(metadata_holder); | |
421 } | |
422 | |
423 #endif | |
375 } | 424 } |
376 | 425 |
377 //------------------------------------------------------------------ | 426 //------------------------------------------------------------------ |
378 // ciObjectFactory::get_unloaded_method | 427 // ciObjectFactory::get_unloaded_method |
379 // | 428 // |
665 // | 714 // |
666 // 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. |
667 // 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 |
668 // 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. |
669 ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) { | 718 ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) { |
670 assert(Universe::heap()->is_in_reserved_or_null(key), "must be"); | 719 assert(Universe::heap()->is_in_reserved(key), "must be"); |
671 ciMetadata* klass = get_metadata(key->klass()); | 720 ciMetadata* klass = get_metadata(key->klass()); |
672 NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS]; | 721 NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS]; |
673 for (NonPermObject* p; (p = (*bp)) != NULL; bp = &p->next()) { | 722 for (NonPermObject* p; (p = (*bp)) != NULL; bp = &p->next()) { |
674 if (is_equal(p, key)) break; | 723 if (is_equal(p, key)) break; |
675 } | 724 } |