< prev index next > src/hotspot/share/oops/trainingData.hpp
Print this page
#include "oops/instanceKlass.hpp"
#include "oops/method.hpp"
#include "oops/objArrayKlass.hpp"
#include "runtime/handles.hpp"
#include "runtime/mutexLocker.hpp"
+ #include "utilities/count_leading_zeros.hpp"
#include "utilities/resizableHashTable.hpp"
class ciEnv;
class ciBaseObject;
class CompileTask;
static void iterate(const Function& fn) { iterate(const_cast<Function&>(fn)); }
template<typename Function>
static void iterate(Function& fn) { // lambda enabled API
TrainingDataLocker l;
- if (have_data()) {
- archived_training_data_dictionary()->iterate(fn);
+ if (have_data() && !need_data()) {
+ archived_training_data_dictionary()->iterate_all([&](TrainingData* td) { fn(td); });
}
if (need_data()) {
training_data_set()->iterate(fn);
}
}
virtual void prepare(Visitor& visitor) = 0;
virtual void cleanup(Visitor& visitor) = 0;
static void initialize() NOT_CDS_RETURN;
- static void verify();
+ static void verify() NOT_CDS_RETURN;
// Widget for recording dependencies, as an N-to-M graph relation,
// possibly cyclic.
template<typename E>
class DepList : public StackObj {
+ static const int INITIAL_CAPACITY = 10;
+
GrowableArrayCHeap<E, mtCompiler>* _deps_dyn;
Array<E>* _deps;
+
+ void copy_on_write_if_necessary() {
+ TrainingDataLocker::assert_locked_or_snapshotted();
+ if (_deps != nullptr && _deps_dyn == nullptr) {
+ _deps_dyn = new GrowableArrayCHeap<E, mtCompiler>(length() + INITIAL_CAPACITY);
+ for (int i = 0; _deps->length(); i++) {
+ _deps_dyn->append(_deps->at(i));
+ }
+ _deps = nullptr;
+ }
+ }
public:
DepList() {
_deps_dyn = nullptr;
_deps = nullptr;
}
TrainingDataLocker::assert_locked_or_snapshotted();
return (_deps_dyn != nullptr ? _deps_dyn->length()
: _deps != nullptr ? _deps->length()
: 0);
}
- E* adr_at(int i) const {
- TrainingDataLocker::assert_locked_or_snapshotted();
- return (_deps_dyn != nullptr ? _deps_dyn->adr_at(i)
- : _deps != nullptr ? _deps->adr_at(i)
- : nullptr);
- }
E at(int i) const {
TrainingDataLocker::assert_locked_or_snapshotted();
assert(i >= 0 && i < length(), "oob");
- return *adr_at(i);
+ if (_deps_dyn != nullptr) {
+ return _deps_dyn->at(i);
+ } else if (_deps != nullptr) {
+ return _deps->at(i);
+ } else ShouldNotReachHere();
}
bool append_if_missing(E dep) {
TrainingDataLocker::assert_can_add();
+ copy_on_write_if_necessary();
if (_deps_dyn == nullptr) {
- _deps_dyn = new GrowableArrayCHeap<E, mtCompiler>(10);
+ _deps_dyn = new GrowableArrayCHeap<E, mtCompiler>(INITIAL_CAPACITY);
_deps_dyn->append(dep);
return true;
} else {
return _deps_dyn->append_if_missing(dep);
}
}
bool remove_if_existing(E dep) {
TrainingDataLocker::assert_can_add();
+ copy_on_write_if_necessary();
if (_deps_dyn != nullptr) {
return _deps_dyn->remove_if_existing(dep);
}
return false;
}
void clear() {
TrainingDataLocker::assert_can_add();
if (_deps_dyn != nullptr) {
_deps_dyn->clear();
}
+ _deps = nullptr;
}
void append(E dep) {
TrainingDataLocker::assert_can_add();
+ copy_on_write_if_necessary();
if (_deps_dyn == nullptr) {
- _deps_dyn = new GrowableArrayCHeap<E, mtCompiler>(10);
+ _deps_dyn = new GrowableArrayCHeap<E, mtCompiler>(INITIAL_CAPACITY);
}
_deps_dyn->append(dep);
}
bool contains(E dep) {
TrainingDataLocker::assert_locked();
}
static int level_mask(int level) {
return ((level & 0xF) != level ? 0 : 1 << level);
}
+ static CompLevel highest_level(int mask) {
+ if (mask == 0) return (CompLevel) 0;
+ int diff = (count_leading_zeros(level_mask(0)) - count_leading_zeros(mask));
+ return (CompLevel) diff;
+ }
public:
KlassTrainingData* klass() const { return _klass; }
bool has_holder() const { return _holder != nullptr; }
Method* holder() const { return _holder; }
bool only_inlined() const { return !_was_toplevel; }
bool saw_level(CompLevel l) const { return (_level_mask & level_mask(l)) != 0; }
+ int highest_level() const { return highest_level(_level_mask); }
int highest_top_level() const { return _highest_top_level; }
MethodData* final_profile() const { return _final_profile; }
int invocation_count() const { return _invocation_count; }
int backedge_count() const { return _backedge_count; }
< prev index next >