8255720: Optimize bci_to_dp/-data by enabling iteration over raw DataLayouts
Reviewed-by: kvn, thartmann
This commit is contained in:
parent
4b775e64bd
commit
120aec7054
@ -335,7 +335,10 @@ ciProfileData* ciMethodData::data_at(int data_index) {
|
||||
return NULL;
|
||||
}
|
||||
DataLayout* data_layout = data_layout_at(data_index);
|
||||
return data_from(data_layout);
|
||||
}
|
||||
|
||||
ciProfileData* ciMethodData::data_from(DataLayout* data_layout) {
|
||||
switch (data_layout->tag()) {
|
||||
case DataLayout::no_tag:
|
||||
default:
|
||||
@ -376,6 +379,16 @@ ciProfileData* ciMethodData::next_data(ciProfileData* current) {
|
||||
return next;
|
||||
}
|
||||
|
||||
DataLayout* ciMethodData::next_data_layout(DataLayout* current) {
|
||||
int current_index = dp_to_di((address)current);
|
||||
int next_index = current_index + current->size_in_bytes();
|
||||
if (out_of_bounds(next_index)) {
|
||||
return NULL;
|
||||
}
|
||||
DataLayout* next = data_layout_at(next_index);
|
||||
return next;
|
||||
}
|
||||
|
||||
ciProfileData* ciMethodData::bci_to_extra_data(int bci, ciMethod* m, bool& two_free_slots) {
|
||||
DataLayout* dp = extra_data_base();
|
||||
DataLayout* end = args_data_limit();
|
||||
@ -413,12 +426,12 @@ ciProfileData* ciMethodData::bci_to_extra_data(int bci, ciMethod* m, bool& two_f
|
||||
ciProfileData* ciMethodData::bci_to_data(int bci, ciMethod* m) {
|
||||
// If m is not NULL we look for a SpeculativeTrapData entry
|
||||
if (m == NULL) {
|
||||
ciProfileData* data = data_before(bci);
|
||||
for ( ; is_valid(data); data = next_data(data)) {
|
||||
if (data->bci() == bci) {
|
||||
set_hint_di(dp_to_di(data->dp()));
|
||||
return data;
|
||||
} else if (data->bci() > bci) {
|
||||
DataLayout* data_layout = data_layout_before(bci);
|
||||
for ( ; is_valid(data_layout); data_layout = next_data_layout(data_layout)) {
|
||||
if (data_layout->bci() == bci) {
|
||||
set_hint_di(dp_to_di((address)data_layout));
|
||||
return data_from(data_layout);
|
||||
} else if (data_layout->bci() > bci) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -379,7 +379,7 @@ private:
|
||||
// Data entries
|
||||
intptr_t* _data;
|
||||
|
||||
// Cached hint for data_before()
|
||||
// Cached hint for data_layout_before()
|
||||
int _hint_di;
|
||||
|
||||
// Is data attached? And is it mature?
|
||||
@ -445,17 +445,17 @@ private:
|
||||
assert(!out_of_bounds(di), "hint_di out of bounds");
|
||||
_hint_di = di;
|
||||
}
|
||||
ciProfileData* data_before(int bci) {
|
||||
|
||||
DataLayout* data_layout_before(int bci) {
|
||||
// avoid SEGV on this edge case
|
||||
if (data_size() == 0)
|
||||
return NULL;
|
||||
int hint = hint_di();
|
||||
if (data_layout_at(hint)->bci() <= bci)
|
||||
return data_at(hint);
|
||||
return first_data();
|
||||
DataLayout* layout = data_layout_at(hint_di());
|
||||
if (layout->bci() <= bci)
|
||||
return layout;
|
||||
return data_layout_at(first_di());
|
||||
}
|
||||
|
||||
|
||||
// What is the index of the first data entry?
|
||||
int first_di() { return 0; }
|
||||
|
||||
@ -469,6 +469,7 @@ private:
|
||||
template<class T> void dump_replay_data_call_type_helper(outputStream* out, int round, int& count, T* call_type_data);
|
||||
template<class T> void dump_replay_data_receiver_type_helper(outputStream* out, int round, int& count, T* call_type_data);
|
||||
void dump_replay_data_extra_data_helper(outputStream* out, int round, int& count);
|
||||
ciProfileData* data_from(DataLayout* data_layout);
|
||||
|
||||
public:
|
||||
bool is_method_data() const { return true; }
|
||||
@ -519,7 +520,9 @@ public:
|
||||
// Walk through the data in order.
|
||||
ciProfileData* first_data() { return data_at(first_di()); }
|
||||
ciProfileData* next_data(ciProfileData* current);
|
||||
DataLayout* next_data_layout(DataLayout* current);
|
||||
bool is_valid(ciProfileData* current) { return current != NULL; }
|
||||
bool is_valid(DataLayout* current) { return current != NULL; }
|
||||
|
||||
DataLayout* extra_data_base() const { return data_layout_at(data_size()); }
|
||||
DataLayout* args_data_limit() const { return data_layout_at(data_size() + extra_data_size() -
|
||||
|
@ -1099,6 +1099,40 @@ ProfileData* MethodData::data_at(int data_index) const {
|
||||
return data_layout->data_in();
|
||||
}
|
||||
|
||||
int DataLayout::cell_count() {
|
||||
switch (tag()) {
|
||||
case DataLayout::no_tag:
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
return 0;
|
||||
case DataLayout::bit_data_tag:
|
||||
return BitData::static_cell_count();
|
||||
case DataLayout::counter_data_tag:
|
||||
return CounterData::static_cell_count();
|
||||
case DataLayout::jump_data_tag:
|
||||
return JumpData::static_cell_count();
|
||||
case DataLayout::receiver_type_data_tag:
|
||||
return ReceiverTypeData::static_cell_count();
|
||||
case DataLayout::virtual_call_data_tag:
|
||||
return VirtualCallData::static_cell_count();
|
||||
case DataLayout::ret_data_tag:
|
||||
return RetData::static_cell_count();
|
||||
case DataLayout::branch_data_tag:
|
||||
return BranchData::static_cell_count();
|
||||
case DataLayout::multi_branch_data_tag:
|
||||
return ((new MultiBranchData(this))->cell_count());
|
||||
case DataLayout::arg_info_data_tag:
|
||||
return ((new ArgInfoData(this))->cell_count());
|
||||
case DataLayout::call_type_data_tag:
|
||||
return ((new CallTypeData(this))->cell_count());
|
||||
case DataLayout::virtual_call_type_data_tag:
|
||||
return ((new VirtualCallTypeData(this))->cell_count());
|
||||
case DataLayout::parameters_type_data_tag:
|
||||
return ((new ParametersTypeData(this))->cell_count());
|
||||
case DataLayout::speculative_trap_data_tag:
|
||||
return SpeculativeTrapData::static_cell_count();
|
||||
}
|
||||
}
|
||||
ProfileData* DataLayout::data_in() {
|
||||
switch (tag()) {
|
||||
case DataLayout::no_tag:
|
||||
@ -1142,6 +1176,16 @@ ProfileData* MethodData::next_data(ProfileData* current) const {
|
||||
return next;
|
||||
}
|
||||
|
||||
DataLayout* MethodData::next_data_layout(DataLayout* current) const {
|
||||
int current_index = dp_to_di((address)current);
|
||||
int next_index = current_index + current->size_in_bytes();
|
||||
if (out_of_bounds(next_index)) {
|
||||
return NULL;
|
||||
}
|
||||
DataLayout* next = data_layout_at(next_index);
|
||||
return next;
|
||||
}
|
||||
|
||||
// Give each of the data entries a chance to perform specific
|
||||
// data initialization.
|
||||
void MethodData::post_initialize(BytecodeStream* stream) {
|
||||
@ -1314,13 +1358,13 @@ bool MethodData::is_mature() const {
|
||||
// Translate a bci to its corresponding data index (di).
|
||||
address MethodData::bci_to_dp(int bci) {
|
||||
ResourceMark rm;
|
||||
ProfileData* data = data_before(bci);
|
||||
ProfileData* prev = NULL;
|
||||
for ( ; is_valid(data); data = next_data(data)) {
|
||||
DataLayout* data = data_layout_before(bci);
|
||||
DataLayout* prev = NULL;
|
||||
for ( ; is_valid(data); data = next_data_layout(data)) {
|
||||
if (data->bci() >= bci) {
|
||||
if (data->bci() == bci) set_hint_di(dp_to_di(data->dp()));
|
||||
else if (prev != NULL) set_hint_di(dp_to_di(prev->dp()));
|
||||
return data->dp();
|
||||
if (data->bci() == bci) set_hint_di(dp_to_di((address)data));
|
||||
else if (prev != NULL) set_hint_di(dp_to_di((address)prev));
|
||||
return (address)data;
|
||||
}
|
||||
prev = data;
|
||||
}
|
||||
@ -1329,11 +1373,11 @@ address MethodData::bci_to_dp(int bci) {
|
||||
|
||||
// Translate a bci to its corresponding data, or NULL.
|
||||
ProfileData* MethodData::bci_to_data(int bci) {
|
||||
ProfileData* data = data_before(bci);
|
||||
for ( ; is_valid(data); data = next_data(data)) {
|
||||
DataLayout* data = data_layout_before(bci);
|
||||
for ( ; is_valid(data); data = next_data_layout(data)) {
|
||||
if (data->bci() == bci) {
|
||||
set_hint_di(dp_to_di(data->dp()));
|
||||
return data;
|
||||
set_hint_di(dp_to_di((address)data));
|
||||
return data->data_in();
|
||||
} else if (data->bci() > bci) {
|
||||
break;
|
||||
}
|
||||
|
@ -236,6 +236,13 @@ public:
|
||||
|
||||
ProfileData* data_in();
|
||||
|
||||
int size_in_bytes() {
|
||||
int cells = cell_count();
|
||||
assert(cells >= 0, "invalid number of cells");
|
||||
return DataLayout::compute_size_in_bytes(cells);
|
||||
}
|
||||
int cell_count();
|
||||
|
||||
// GC support
|
||||
void clean_weak_klass_links(bool always_clean);
|
||||
};
|
||||
@ -2053,14 +2060,15 @@ private:
|
||||
assert(!out_of_bounds(di), "hint_di out of bounds");
|
||||
_hint_di = di;
|
||||
}
|
||||
ProfileData* data_before(int bci) {
|
||||
|
||||
DataLayout* data_layout_before(int bci) {
|
||||
// avoid SEGV on this edge case
|
||||
if (data_size() == 0)
|
||||
return NULL;
|
||||
int hint = hint_di();
|
||||
if (data_layout_at(hint)->bci() <= bci)
|
||||
return data_at(hint);
|
||||
return first_data();
|
||||
DataLayout* layout = data_layout_at(hint_di());
|
||||
if (layout->bci() <= bci)
|
||||
return layout;
|
||||
return data_layout_at(first_di());
|
||||
}
|
||||
|
||||
// What is the index of the first data entry?
|
||||
@ -2243,7 +2251,9 @@ public:
|
||||
// Walk through the data in order.
|
||||
ProfileData* first_data() const { return data_at(first_di()); }
|
||||
ProfileData* next_data(ProfileData* current) const;
|
||||
DataLayout* next_data_layout(DataLayout* current) const;
|
||||
bool is_valid(ProfileData* current) const { return current != NULL; }
|
||||
bool is_valid(DataLayout* current) const { return current != NULL; }
|
||||
|
||||
// Convert a dp (data pointer) to a di (data index).
|
||||
int dp_to_di(address dp) const {
|
||||
|
Loading…
Reference in New Issue
Block a user