27 #include "ci/ciInstance.hpp"
28 #include "ci/ciInstanceKlass.hpp"
29 #include "ci/ciMemberName.hpp"
30 #include "ci/ciMethod.hpp"
31 #include "ci/ciMethodData.hpp"
32 #include "ci/ciMethodHandle.hpp"
33 #include "ci/ciMethodType.hpp"
34 #include "ci/ciNullObject.hpp"
35 #include "ci/ciObjArray.hpp"
36 #include "ci/ciObjArrayKlass.hpp"
37 #include "ci/ciObject.hpp"
38 #include "ci/ciObjectFactory.hpp"
39 #include "ci/ciReplay.hpp"
40 #include "ci/ciSymbol.hpp"
41 #include "ci/ciSymbols.hpp"
42 #include "ci/ciTypeArray.hpp"
43 #include "ci/ciTypeArrayKlass.hpp"
44 #include "ci/ciUtilities.inline.hpp"
45 #include "classfile/javaClasses.inline.hpp"
46 #include "classfile/vmClasses.hpp"
47 #include "compiler/compiler_globals.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 "runtime/handles.inline.hpp"
53 #include "runtime/signature.hpp"
54 #include "utilities/macros.hpp"
55
56 // ciObjectFactory
57 //
58 // This class handles requests for the creation of new instances
59 // of ciObject and its subclasses. It contains a caching mechanism
60 // which ensures that for each oop, at most one ciObject is created.
61 // This invariant allows more efficient implementation of ciObject.
62 //
63 // Implementation note: the oop->ciObject mapping is represented as
64 // a table stored in an array. Even though objects are moved
65 // by the garbage collector, the compactor preserves their relative
66 // order; address comparison of oops (in perm space) is safe so long
67 // as we prohibit GC during our comparisons. We currently use binary
68 // search to find the oop in the table, and inserting a new oop
69 // into the table may be costly. If this cost ends up being
70 // problematic the underlying data structure can be switched to some
71 // sort of balanced binary tree.
233 ciObject* ciObjectFactory::get(oop key) {
234 ASSERT_IN_VM;
235
236 assert(Universe::heap()->is_in(key), "must be");
237
238 NonPermObject* &bucket = find_non_perm(key);
239 if (bucket != nullptr) {
240 return bucket->object();
241 }
242
243 // The ciObject does not yet exist. Create it and insert it
244 // into the cache.
245 Handle keyHandle(Thread::current(), key);
246 ciObject* new_object = create_new_object(keyHandle());
247 assert(keyHandle() == new_object->get_oop(), "must be properly recorded");
248 init_ident_of(new_object);
249 assert(Universe::heap()->is_in(new_object->get_oop()), "must be");
250
251 // Not a perm-space object.
252 insert_non_perm(bucket, keyHandle(), new_object);
253 return new_object;
254 }
255
256 int ciObjectFactory::metadata_compare(Metadata* const& key, ciMetadata* const& elt) {
257 Metadata* value = elt->constant_encoding();
258 if (key < value) return -1;
259 else if (key > value) return 1;
260 else return 0;
261 }
262
263 // ------------------------------------------------------------------
264 // ciObjectFactory::cached_metadata
265 //
266 // Get the ciMetadata corresponding to some Metadata. If the ciMetadata has
267 // already been created, it is returned. Otherwise, null is returned.
268 ciMetadata* ciObjectFactory::cached_metadata(Metadata* key) {
269 ASSERT_IN_VM;
270
271 bool found = false;
272 int index = _ci_metadata.find_sorted<Metadata*, ciObjectFactory::metadata_compare>(key, found);
273
274 if (!found) {
275 return nullptr;
315 assert(index == i, " bad lookup");
316 }
317 }
318 }
319 #endif
320
321 if (!found) {
322 // The ciMetadata does not yet exist. Create it and insert it
323 // into the cache.
324 ciMetadata* new_object = create_new_metadata(key);
325 init_ident_of(new_object);
326 assert(new_object->is_metadata(), "must be");
327
328 if (len != _ci_metadata.length()) {
329 // creating the new object has recursively entered new objects
330 // into the table. We need to recompute our index.
331 index = _ci_metadata.find_sorted<Metadata*, ciObjectFactory::metadata_compare>(key, found);
332 }
333 assert(!found, "no double insert");
334 _ci_metadata.insert_before(index, new_object);
335 return new_object;
336 }
337 return _ci_metadata.at(index)->as_metadata();
338 }
339
340 // ------------------------------------------------------------------
341 // ciObjectFactory::create_new_object
342 //
343 // Create a new ciObject from an oop.
344 //
345 // Implementation note: this functionality could be virtual behavior
346 // of the oop itself. For now, we explicitly marshal the object.
347 ciObject* ciObjectFactory::create_new_object(oop o) {
348 EXCEPTION_CONTEXT;
349
350 if (o->is_instance()) {
351 instanceHandle h_i(THREAD, (instanceOop)o);
352 if (java_lang_invoke_CallSite::is_instance(o))
353 return new (arena()) ciCallSite(h_i);
354 else if (java_lang_invoke_MemberName::is_instance(o))
|
27 #include "ci/ciInstance.hpp"
28 #include "ci/ciInstanceKlass.hpp"
29 #include "ci/ciMemberName.hpp"
30 #include "ci/ciMethod.hpp"
31 #include "ci/ciMethodData.hpp"
32 #include "ci/ciMethodHandle.hpp"
33 #include "ci/ciMethodType.hpp"
34 #include "ci/ciNullObject.hpp"
35 #include "ci/ciObjArray.hpp"
36 #include "ci/ciObjArrayKlass.hpp"
37 #include "ci/ciObject.hpp"
38 #include "ci/ciObjectFactory.hpp"
39 #include "ci/ciReplay.hpp"
40 #include "ci/ciSymbol.hpp"
41 #include "ci/ciSymbols.hpp"
42 #include "ci/ciTypeArray.hpp"
43 #include "ci/ciTypeArrayKlass.hpp"
44 #include "ci/ciUtilities.inline.hpp"
45 #include "classfile/javaClasses.inline.hpp"
46 #include "classfile/vmClasses.hpp"
47 #include "compiler/compileTask.hpp"
48 #include "compiler/compiler_globals.hpp"
49 #include "gc/shared/collectedHeap.inline.hpp"
50 #include "memory/allocation.inline.hpp"
51 #include "memory/universe.hpp"
52 #include "oops/oop.inline.hpp"
53 #include "oops/trainingData.hpp"
54 #include "runtime/handles.inline.hpp"
55 #include "runtime/signature.hpp"
56 #include "utilities/macros.hpp"
57
58 // ciObjectFactory
59 //
60 // This class handles requests for the creation of new instances
61 // of ciObject and its subclasses. It contains a caching mechanism
62 // which ensures that for each oop, at most one ciObject is created.
63 // This invariant allows more efficient implementation of ciObject.
64 //
65 // Implementation note: the oop->ciObject mapping is represented as
66 // a table stored in an array. Even though objects are moved
67 // by the garbage collector, the compactor preserves their relative
68 // order; address comparison of oops (in perm space) is safe so long
69 // as we prohibit GC during our comparisons. We currently use binary
70 // search to find the oop in the table, and inserting a new oop
71 // into the table may be costly. If this cost ends up being
72 // problematic the underlying data structure can be switched to some
73 // sort of balanced binary tree.
235 ciObject* ciObjectFactory::get(oop key) {
236 ASSERT_IN_VM;
237
238 assert(Universe::heap()->is_in(key), "must be");
239
240 NonPermObject* &bucket = find_non_perm(key);
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 Handle keyHandle(Thread::current(), key);
248 ciObject* new_object = create_new_object(keyHandle());
249 assert(keyHandle() == new_object->get_oop(), "must be properly recorded");
250 init_ident_of(new_object);
251 assert(Universe::heap()->is_in(new_object->get_oop()), "must be");
252
253 // Not a perm-space object.
254 insert_non_perm(bucket, keyHandle(), new_object);
255 notice_new_object(new_object);
256 return new_object;
257 }
258
259 void ciObjectFactory::notice_new_object(ciBaseObject* new_object) {
260 if (RecordTraining) {
261 ciEnv* env = ciEnv::current();
262 if (env->task() != nullptr) {
263 // Note: task will be null during init_compiler_runtime.
264 CompileTrainingData* tdata = env->task()->training_data();
265 if (tdata != nullptr) {
266 tdata->notice_jit_observation(env, new_object);
267 }
268 }
269 }
270 }
271
272 int ciObjectFactory::metadata_compare(Metadata* const& key, ciMetadata* const& elt) {
273 Metadata* value = elt->constant_encoding();
274 if (key < value) return -1;
275 else if (key > value) return 1;
276 else return 0;
277 }
278
279 // ------------------------------------------------------------------
280 // ciObjectFactory::cached_metadata
281 //
282 // Get the ciMetadata corresponding to some Metadata. If the ciMetadata has
283 // already been created, it is returned. Otherwise, null is returned.
284 ciMetadata* ciObjectFactory::cached_metadata(Metadata* key) {
285 ASSERT_IN_VM;
286
287 bool found = false;
288 int index = _ci_metadata.find_sorted<Metadata*, ciObjectFactory::metadata_compare>(key, found);
289
290 if (!found) {
291 return nullptr;
331 assert(index == i, " bad lookup");
332 }
333 }
334 }
335 #endif
336
337 if (!found) {
338 // The ciMetadata does not yet exist. Create it and insert it
339 // into the cache.
340 ciMetadata* new_object = create_new_metadata(key);
341 init_ident_of(new_object);
342 assert(new_object->is_metadata(), "must be");
343
344 if (len != _ci_metadata.length()) {
345 // creating the new object has recursively entered new objects
346 // into the table. We need to recompute our index.
347 index = _ci_metadata.find_sorted<Metadata*, ciObjectFactory::metadata_compare>(key, found);
348 }
349 assert(!found, "no double insert");
350 _ci_metadata.insert_before(index, new_object);
351 notice_new_object(new_object);
352 return new_object;
353 }
354 return _ci_metadata.at(index)->as_metadata();
355 }
356
357 // ------------------------------------------------------------------
358 // ciObjectFactory::create_new_object
359 //
360 // Create a new ciObject from an oop.
361 //
362 // Implementation note: this functionality could be virtual behavior
363 // of the oop itself. For now, we explicitly marshal the object.
364 ciObject* ciObjectFactory::create_new_object(oop o) {
365 EXCEPTION_CONTEXT;
366
367 if (o->is_instance()) {
368 instanceHandle h_i(THREAD, (instanceOop)o);
369 if (java_lang_invoke_CallSite::is_instance(o))
370 return new (arena()) ciCallSite(h_i);
371 else if (java_lang_invoke_MemberName::is_instance(o))
|