< prev index next >

src/hotspot/share/ci/ciObjectFactory.cpp

Print this page

 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))
< prev index next >