27 #include "ci/ciInstanceKlass.hpp"
28 #include "ci/ciMemberName.hpp"
29 #include "ci/ciMethod.hpp"
30 #include "ci/ciMethodData.hpp"
31 #include "ci/ciMethodHandle.hpp"
32 #include "ci/ciMethodType.hpp"
33 #include "ci/ciNullObject.hpp"
34 #include "ci/ciObjArray.hpp"
35 #include "ci/ciObjArrayKlass.hpp"
36 #include "ci/ciObject.hpp"
37 #include "ci/ciObjectFactory.hpp"
38 #include "ci/ciReplay.hpp"
39 #include "ci/ciSymbol.hpp"
40 #include "ci/ciSymbols.hpp"
41 #include "ci/ciTypeArray.hpp"
42 #include "ci/ciTypeArrayKlass.hpp"
43 #include "ci/ciUtilities.inline.hpp"
44 #include "classfile/javaClasses.inline.hpp"
45 #include "classfile/vmClasses.hpp"
46 #include "compiler/compiler_globals.hpp"
47 #include "gc/shared/collectedHeap.inline.hpp"
48 #include "memory/allocation.inline.hpp"
49 #include "memory/universe.hpp"
50 #include "oops/oop.inline.hpp"
51 #include "runtime/handles.inline.hpp"
52 #include "runtime/signature.hpp"
53 #include "utilities/macros.hpp"
54
55 // ciObjectFactory
56 //
57 // This class handles requests for the creation of new instances
58 // of ciObject and its subclasses. It contains a caching mechanism
59 // which ensures that for each oop, at most one ciObject is created.
60 // This invariant allows more efficient implementation of ciObject.
61 //
62 // Implementation note: the oop->ciObject mapping is represented as
63 // a table stored in an array. Even though objects are moved
64 // by the garbage collector, the compactor preserves their relative
65 // order; address comparison of oops (in perm space) is safe so long
66 // as we prohibit GC during our comparisons. We currently use binary
67 // search to find the oop in the table, and inserting a new oop
68 // into the table may be costly. If this cost ends up being
69 // problematic the underlying data structure can be switched to some
70 // sort of balanced binary tree.
215
216 // Decrement the refcount when done on symbols referenced by this compilation.
217 void ciObjectFactory::remove_symbols() {
218 for (int i = 0; i < _symbols.length(); i++) {
219 ciSymbol* s = _symbols.at(i);
220 s->get_symbol()->decrement_refcount();
221 }
222 // Since _symbols is resource allocated we're not allowed to delete it
223 // but it'll go away just the same.
224 }
225
226 // ------------------------------------------------------------------
227 // ciObjectFactory::get
228 //
229 // Get the ciObject corresponding to some oop. If the ciObject has
230 // already been created, it is returned. Otherwise, a new ciObject
231 // is created.
232 ciObject* ciObjectFactory::get(oop key) {
233 ASSERT_IN_VM;
234
235 assert(Universe::heap()->is_in(key), "must be");
236
237 NonPermObject* &bucket = find_non_perm(key);
238 if (bucket != nullptr) {
239 return bucket->object();
240 }
241
242 // The ciObject does not yet exist. Create it and insert it
243 // into the cache.
244 Handle keyHandle(Thread::current(), key);
245 ciObject* new_object = create_new_object(keyHandle());
246 assert(keyHandle() == new_object->get_oop(), "must be properly recorded");
247 init_ident_of(new_object);
248 assert(Universe::heap()->is_in(new_object->get_oop()), "must be");
249
250 // Not a perm-space object.
251 insert_non_perm(bucket, keyHandle(), new_object);
252 return new_object;
253 }
254
255 int ciObjectFactory::metadata_compare(Metadata* const& key, ciMetadata* const& elt) {
256 Metadata* value = elt->constant_encoding();
257 if (key < value) return -1;
258 else if (key > value) return 1;
259 else return 0;
260 }
261
262 // ------------------------------------------------------------------
263 // ciObjectFactory::cached_metadata
264 //
265 // Get the ciMetadata corresponding to some Metadata. If the ciMetadata has
266 // already been created, it is returned. Otherwise, null is returned.
267 ciMetadata* ciObjectFactory::cached_metadata(Metadata* key) {
268 ASSERT_IN_VM;
269
270 bool found = false;
271 int index = _ci_metadata.find_sorted<Metadata*, ciObjectFactory::metadata_compare>(key, found);
272
273 if (!found) {
274 return nullptr;
314 assert(index == i, " bad lookup");
315 }
316 }
317 }
318 #endif
319
320 if (!found) {
321 // The ciMetadata does not yet exist. Create it and insert it
322 // into the cache.
323 ciMetadata* new_object = create_new_metadata(key);
324 init_ident_of(new_object);
325 assert(new_object->is_metadata(), "must be");
326
327 if (len != _ci_metadata.length()) {
328 // creating the new object has recursively entered new objects
329 // into the table. We need to recompute our index.
330 index = _ci_metadata.find_sorted<Metadata*, ciObjectFactory::metadata_compare>(key, found);
331 }
332 assert(!found, "no double insert");
333 _ci_metadata.insert_before(index, new_object);
334 return new_object;
335 }
336 return _ci_metadata.at(index)->as_metadata();
337 }
338
339 // ------------------------------------------------------------------
340 // ciObjectFactory::create_new_object
341 //
342 // Create a new ciObject from an oop.
343 //
344 // Implementation note: this functionality could be virtual behavior
345 // of the oop itself. For now, we explicitly marshal the object.
346 ciObject* ciObjectFactory::create_new_object(oop o) {
347 EXCEPTION_CONTEXT;
348
349 if (o->is_instance()) {
350 instanceHandle h_i(THREAD, (instanceOop)o);
351 if (java_lang_invoke_CallSite::is_instance(o))
352 return new (arena()) ciCallSite(h_i);
353 else if (java_lang_invoke_MemberName::is_instance(o))
619 ciReturnAddress* new_ret_addr = new (arena()) ciReturnAddress(bci);
620 init_ident_of(new_ret_addr);
621 _return_addresses.append(new_ret_addr);
622 return new_ret_addr;
623 }
624
625 // ------------------------------------------------------------------
626 // ciObjectFactory::init_ident_of
627 void ciObjectFactory::init_ident_of(ciBaseObject* obj) {
628 obj->set_ident(_next_ident++);
629 }
630
631 static ciObjectFactory::NonPermObject* emptyBucket = nullptr;
632
633 // ------------------------------------------------------------------
634 // ciObjectFactory::find_non_perm
635 //
636 // Use a small hash table, hashed on the klass of the key.
637 // If there is no entry in the cache corresponding to this oop, return
638 // the null tail of the bucket into which the oop should be inserted.
639 ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) {
640 assert(Universe::heap()->is_in(key), "must be");
641 ciMetadata* klass = get_metadata(key->klass());
642 NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS];
643 for (NonPermObject* p; (p = (*bp)) != nullptr; bp = &p->next()) {
644 if (is_equal(p, key)) break;
645 }
646 return (*bp);
647 }
648
649
650
651 // ------------------------------------------------------------------
652 // Code for for NonPermObject
653 //
654 inline ciObjectFactory::NonPermObject::NonPermObject(ciObjectFactory::NonPermObject* &bucket, oop key, ciObject* object) {
655 assert(ciObjectFactory::is_initialized(), "");
656 _object = object;
657 _next = bucket;
658 bucket = this;
659 }
660
661
662
663 // ------------------------------------------------------------------
664 // ciObjectFactory::insert_non_perm
665 //
666 // Insert a ciObject into the non-perm table.
667 void ciObjectFactory::insert_non_perm(ciObjectFactory::NonPermObject* &where, oop key, ciObject* obj) {
668 assert(Universe::heap()->is_in_or_null(key), "must be");
669 assert(&where != &emptyBucket, "must not try to fill empty bucket");
670 NonPermObject* p = new (arena()) NonPermObject(where, key, obj);
671 assert(where == p && is_equal(p, key) && p->object() == obj, "entry must match");
672 assert(find_non_perm(key) == p, "must find the same spot");
673 ++_non_perm_count;
674 }
675
676 // ------------------------------------------------------------------
677 // ciObjectFactory::vm_symbol_at
678 // Get the ciSymbol corresponding to some index in vmSymbols.
679 ciSymbol* ciObjectFactory::vm_symbol_at(vmSymbolID sid) {
680 int index = vmSymbols::as_int(sid);
681 return _shared_ci_symbols[index];
682 }
683
684 // ------------------------------------------------------------------
685 // ciObjectFactory::metadata_do
686 void ciObjectFactory::metadata_do(MetadataClosure* f) {
687 for (int j = 0; j < _ci_metadata.length(); j++) {
688 Metadata* o = _ci_metadata.at(j)->constant_encoding();
689 f->do_metadata(o);
690 }
691 }
692
|
27 #include "ci/ciInstanceKlass.hpp"
28 #include "ci/ciMemberName.hpp"
29 #include "ci/ciMethod.hpp"
30 #include "ci/ciMethodData.hpp"
31 #include "ci/ciMethodHandle.hpp"
32 #include "ci/ciMethodType.hpp"
33 #include "ci/ciNullObject.hpp"
34 #include "ci/ciObjArray.hpp"
35 #include "ci/ciObjArrayKlass.hpp"
36 #include "ci/ciObject.hpp"
37 #include "ci/ciObjectFactory.hpp"
38 #include "ci/ciReplay.hpp"
39 #include "ci/ciSymbol.hpp"
40 #include "ci/ciSymbols.hpp"
41 #include "ci/ciTypeArray.hpp"
42 #include "ci/ciTypeArrayKlass.hpp"
43 #include "ci/ciUtilities.inline.hpp"
44 #include "classfile/javaClasses.inline.hpp"
45 #include "classfile/vmClasses.hpp"
46 #include "compiler/compiler_globals.hpp"
47 #include "compiler/compileTask.hpp"
48 #include "gc/shared/collectedHeap.inline.hpp"
49 #include "memory/allocation.inline.hpp"
50 #include "memory/universe.hpp"
51 #include "oops/oop.inline.hpp"
52 #include "oops/trainingData.hpp"
53 #include "runtime/handles.inline.hpp"
54 #include "runtime/signature.hpp"
55 #include "utilities/macros.hpp"
56
57 // ciObjectFactory
58 //
59 // This class handles requests for the creation of new instances
60 // of ciObject and its subclasses. It contains a caching mechanism
61 // which ensures that for each oop, at most one ciObject is created.
62 // This invariant allows more efficient implementation of ciObject.
63 //
64 // Implementation note: the oop->ciObject mapping is represented as
65 // a table stored in an array. Even though objects are moved
66 // by the garbage collector, the compactor preserves their relative
67 // order; address comparison of oops (in perm space) is safe so long
68 // as we prohibit GC during our comparisons. We currently use binary
69 // search to find the oop in the table, and inserting a new oop
70 // into the table may be costly. If this cost ends up being
71 // problematic the underlying data structure can be switched to some
72 // sort of balanced binary tree.
217
218 // Decrement the refcount when done on symbols referenced by this compilation.
219 void ciObjectFactory::remove_symbols() {
220 for (int i = 0; i < _symbols.length(); i++) {
221 ciSymbol* s = _symbols.at(i);
222 s->get_symbol()->decrement_refcount();
223 }
224 // Since _symbols is resource allocated we're not allowed to delete it
225 // but it'll go away just the same.
226 }
227
228 // ------------------------------------------------------------------
229 // ciObjectFactory::get
230 //
231 // Get the ciObject corresponding to some oop. If the ciObject has
232 // already been created, it is returned. Otherwise, a new ciObject
233 // is created.
234 ciObject* ciObjectFactory::get(oop key) {
235 ASSERT_IN_VM;
236
237 Handle keyHandle(Thread::current(), key);
238 assert(Universe::heap()->is_in(keyHandle()), "must be");
239
240 NonPermObject* &bucket = find_non_perm(keyHandle);
241 if (bucket != nullptr) {
242 return bucket->object();
243 }
244
245 // The ciObject does not yet exist. Create it and insert it
246 // into the cache.
247 ciObject* new_object = create_new_object(keyHandle());
248 assert(keyHandle() == new_object->get_oop(), "must be properly recorded");
249 init_ident_of(new_object);
250 assert(Universe::heap()->is_in(new_object->get_oop()), "must be");
251
252 // Not a perm-space object.
253 insert_non_perm(bucket, keyHandle, new_object);
254 notice_new_object(new_object);
255 return new_object;
256 }
257
258 void ciObjectFactory::notice_new_object(ciBaseObject* new_object) {
259 if (TrainingData::need_data()) {
260 ciEnv* env = ciEnv::current();
261 if (env->task() != nullptr) {
262 // Note: task will be null during init_compiler_runtime.
263 CompileTrainingData* td = env->task()->training_data();
264 if (td != nullptr) {
265 td->notice_jit_observation(env, new_object);
266 }
267 }
268 }
269 }
270
271 int ciObjectFactory::metadata_compare(Metadata* const& key, ciMetadata* const& elt) {
272 Metadata* value = elt->constant_encoding();
273 if (key < value) return -1;
274 else if (key > value) return 1;
275 else return 0;
276 }
277
278 // ------------------------------------------------------------------
279 // ciObjectFactory::cached_metadata
280 //
281 // Get the ciMetadata corresponding to some Metadata. If the ciMetadata has
282 // already been created, it is returned. Otherwise, null is returned.
283 ciMetadata* ciObjectFactory::cached_metadata(Metadata* key) {
284 ASSERT_IN_VM;
285
286 bool found = false;
287 int index = _ci_metadata.find_sorted<Metadata*, ciObjectFactory::metadata_compare>(key, found);
288
289 if (!found) {
290 return nullptr;
330 assert(index == i, " bad lookup");
331 }
332 }
333 }
334 #endif
335
336 if (!found) {
337 // The ciMetadata does not yet exist. Create it and insert it
338 // into the cache.
339 ciMetadata* new_object = create_new_metadata(key);
340 init_ident_of(new_object);
341 assert(new_object->is_metadata(), "must be");
342
343 if (len != _ci_metadata.length()) {
344 // creating the new object has recursively entered new objects
345 // into the table. We need to recompute our index.
346 index = _ci_metadata.find_sorted<Metadata*, ciObjectFactory::metadata_compare>(key, found);
347 }
348 assert(!found, "no double insert");
349 _ci_metadata.insert_before(index, new_object);
350 notice_new_object(new_object);
351 return new_object;
352 }
353 return _ci_metadata.at(index)->as_metadata();
354 }
355
356 // ------------------------------------------------------------------
357 // ciObjectFactory::create_new_object
358 //
359 // Create a new ciObject from an oop.
360 //
361 // Implementation note: this functionality could be virtual behavior
362 // of the oop itself. For now, we explicitly marshal the object.
363 ciObject* ciObjectFactory::create_new_object(oop o) {
364 EXCEPTION_CONTEXT;
365
366 if (o->is_instance()) {
367 instanceHandle h_i(THREAD, (instanceOop)o);
368 if (java_lang_invoke_CallSite::is_instance(o))
369 return new (arena()) ciCallSite(h_i);
370 else if (java_lang_invoke_MemberName::is_instance(o))
636 ciReturnAddress* new_ret_addr = new (arena()) ciReturnAddress(bci);
637 init_ident_of(new_ret_addr);
638 _return_addresses.append(new_ret_addr);
639 return new_ret_addr;
640 }
641
642 // ------------------------------------------------------------------
643 // ciObjectFactory::init_ident_of
644 void ciObjectFactory::init_ident_of(ciBaseObject* obj) {
645 obj->set_ident(_next_ident++);
646 }
647
648 static ciObjectFactory::NonPermObject* emptyBucket = nullptr;
649
650 // ------------------------------------------------------------------
651 // ciObjectFactory::find_non_perm
652 //
653 // Use a small hash table, hashed on the klass of the key.
654 // If there is no entry in the cache corresponding to this oop, return
655 // the null tail of the bucket into which the oop should be inserted.
656 ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(Handle keyHandle) {
657 assert(Universe::heap()->is_in(keyHandle()), "must be");
658 ciMetadata* klass = get_metadata(keyHandle->klass()); // This may safepoint!
659 NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS];
660 for (NonPermObject* p; (p = (*bp)) != nullptr; bp = &p->next()) {
661 if (is_equal(p, keyHandle())) break;
662 }
663 return (*bp);
664 }
665
666
667
668 // ------------------------------------------------------------------
669 // Code for for NonPermObject
670 //
671 inline ciObjectFactory::NonPermObject::NonPermObject(ciObjectFactory::NonPermObject* &bucket, oop key, ciObject* object) {
672 assert(ciObjectFactory::is_initialized(), "");
673 _object = object;
674 _next = bucket;
675 bucket = this;
676 }
677
678
679
680 // ------------------------------------------------------------------
681 // ciObjectFactory::insert_non_perm
682 //
683 // Insert a ciObject into the non-perm table.
684 void ciObjectFactory::insert_non_perm(ciObjectFactory::NonPermObject* &where, Handle keyHandle, ciObject* obj) {
685 assert(Universe::heap()->is_in_or_null(keyHandle()), "must be");
686 assert(&where != &emptyBucket, "must not try to fill empty bucket");
687 NonPermObject* p = new (arena()) NonPermObject(where, keyHandle(), obj);
688 assert(where == p && is_equal(p, keyHandle()) && p->object() == obj, "entry must match");
689 assert(find_non_perm(keyHandle) == p, "must find the same spot");
690 ++_non_perm_count;
691 }
692
693 // ------------------------------------------------------------------
694 // ciObjectFactory::vm_symbol_at
695 // Get the ciSymbol corresponding to some index in vmSymbols.
696 ciSymbol* ciObjectFactory::vm_symbol_at(vmSymbolID sid) {
697 int index = vmSymbols::as_int(sid);
698 return _shared_ci_symbols[index];
699 }
700
701 // ------------------------------------------------------------------
702 // ciObjectFactory::metadata_do
703 void ciObjectFactory::metadata_do(MetadataClosure* f) {
704 for (int j = 0; j < _ci_metadata.length(); j++) {
705 Metadata* o = _ci_metadata.at(j)->constant_encoding();
706 f->do_metadata(o);
707 }
708 }
709
|