< prev index next > src/hotspot/share/ci/ciObjectFactory.cpp
Print this page
#include "ci/ciTypeArray.hpp"
#include "ci/ciTypeArrayKlass.hpp"
#include "ci/ciUtilities.inline.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "classfile/vmClasses.hpp"
+ #include "compiler/compileTask.hpp"
#include "compiler/compiler_globals.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/universe.hpp"
#include "oops/oop.inline.hpp"
+ #include "oops/trainingData.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/signature.hpp"
#include "utilities/macros.hpp"
// ciObjectFactory
// already been created, it is returned. Otherwise, a new ciObject
// is created.
ciObject* ciObjectFactory::get(oop key) {
ASSERT_IN_VM;
! assert(Universe::heap()->is_in(key), "must be");
! NonPermObject* &bucket = find_non_perm(key);
if (bucket != nullptr) {
return bucket->object();
}
// The ciObject does not yet exist. Create it and insert it
// into the cache.
- Handle keyHandle(Thread::current(), key);
ciObject* new_object = create_new_object(keyHandle());
assert(keyHandle() == new_object->get_oop(), "must be properly recorded");
init_ident_of(new_object);
assert(Universe::heap()->is_in(new_object->get_oop()), "must be");
// Not a perm-space object.
! insert_non_perm(bucket, keyHandle(), new_object);
return new_object;
}
int ciObjectFactory::metadata_compare(Metadata* const& key, ciMetadata* const& elt) {
Metadata* value = elt->constant_encoding();
if (key < value) return -1;
else if (key > value) return 1;
else return 0;
// already been created, it is returned. Otherwise, a new ciObject
// is created.
ciObject* ciObjectFactory::get(oop key) {
ASSERT_IN_VM;
! Handle keyHandle(Thread::current(), key);
+ assert(Universe::heap()->is_in(keyHandle()), "must be");
! NonPermObject* &bucket = find_non_perm(keyHandle);
if (bucket != nullptr) {
return bucket->object();
}
// The ciObject does not yet exist. Create it and insert it
// into the cache.
ciObject* new_object = create_new_object(keyHandle());
assert(keyHandle() == new_object->get_oop(), "must be properly recorded");
init_ident_of(new_object);
assert(Universe::heap()->is_in(new_object->get_oop()), "must be");
// Not a perm-space object.
! insert_non_perm(bucket, keyHandle, new_object);
+ notice_new_object(new_object);
return new_object;
}
+ void ciObjectFactory::notice_new_object(ciBaseObject* new_object) {
+ if (TrainingData::need_data()) {
+ ciEnv* env = ciEnv::current();
+ if (env->task() != nullptr) {
+ // Note: task will be null during init_compiler_runtime.
+ CompileTrainingData* td = env->task()->training_data();
+ if (td != nullptr) {
+ td->notice_jit_observation(env, new_object);
+ }
+ }
+ }
+ }
+
int ciObjectFactory::metadata_compare(Metadata* const& key, ciMetadata* const& elt) {
Metadata* value = elt->constant_encoding();
if (key < value) return -1;
else if (key > value) return 1;
else return 0;
// into the table. We need to recompute our index.
index = _ci_metadata.find_sorted<Metadata*, ciObjectFactory::metadata_compare>(key, found);
}
assert(!found, "no double insert");
_ci_metadata.insert_before(index, new_object);
+ notice_new_object(new_object);
return new_object;
}
return _ci_metadata.at(index)->as_metadata();
}
// ciObjectFactory::find_non_perm
//
// Use a small hash table, hashed on the klass of the key.
// If there is no entry in the cache corresponding to this oop, return
// the null tail of the bucket into which the oop should be inserted.
! ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) {
! assert(Universe::heap()->is_in(key), "must be");
! ciMetadata* klass = get_metadata(key->klass());
NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS];
for (NonPermObject* p; (p = (*bp)) != nullptr; bp = &p->next()) {
! if (is_equal(p, key)) break;
}
return (*bp);
}
// ciObjectFactory::find_non_perm
//
// Use a small hash table, hashed on the klass of the key.
// If there is no entry in the cache corresponding to this oop, return
// the null tail of the bucket into which the oop should be inserted.
! ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(Handle keyHandle) {
! assert(Universe::heap()->is_in(keyHandle()), "must be");
! ciMetadata* klass = get_metadata(keyHandle->klass()); // This may safepoint!
NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS];
for (NonPermObject* p; (p = (*bp)) != nullptr; bp = &p->next()) {
! if (is_equal(p, keyHandle())) break;
}
return (*bp);
}
// ------------------------------------------------------------------
// ciObjectFactory::insert_non_perm
//
// Insert a ciObject into the non-perm table.
! void ciObjectFactory::insert_non_perm(ciObjectFactory::NonPermObject* &where, oop key, ciObject* obj) {
! assert(Universe::heap()->is_in_or_null(key), "must be");
assert(&where != &emptyBucket, "must not try to fill empty bucket");
! NonPermObject* p = new (arena()) NonPermObject(where, key, obj);
! assert(where == p && is_equal(p, key) && p->object() == obj, "entry must match");
! assert(find_non_perm(key) == p, "must find the same spot");
++_non_perm_count;
}
// ------------------------------------------------------------------
// ciObjectFactory::vm_symbol_at
// ------------------------------------------------------------------
// ciObjectFactory::insert_non_perm
//
// Insert a ciObject into the non-perm table.
! void ciObjectFactory::insert_non_perm(ciObjectFactory::NonPermObject* &where, Handle keyHandle, ciObject* obj) {
! assert(Universe::heap()->is_in_or_null(keyHandle()), "must be");
assert(&where != &emptyBucket, "must not try to fill empty bucket");
! NonPermObject* p = new (arena()) NonPermObject(where, keyHandle(), obj);
! assert(where == p && is_equal(p, keyHandle()) && p->object() == obj, "entry must match");
! assert(find_non_perm(keyHandle) == p, "must find the same spot");
++_non_perm_count;
}
// ------------------------------------------------------------------
// ciObjectFactory::vm_symbol_at
< prev index next >