Skip to content

Commit 120aec7

Browse files
committed
8255720: Optimize bci_to_dp/-data by enabling iteration over raw DataLayouts
Reviewed-by: kvn, thartmann
1 parent 4b775e6 commit 120aec7

File tree

4 files changed

+98
-28
lines changed

4 files changed

+98
-28
lines changed

src/hotspot/share/ci/ciMethodData.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,10 @@ ciProfileData* ciMethodData::data_at(int data_index) {
335335
return NULL;
336336
}
337337
DataLayout* data_layout = data_layout_at(data_index);
338+
return data_from(data_layout);
339+
}
338340

341+
ciProfileData* ciMethodData::data_from(DataLayout* data_layout) {
339342
switch (data_layout->tag()) {
340343
case DataLayout::no_tag:
341344
default:
@@ -376,6 +379,16 @@ ciProfileData* ciMethodData::next_data(ciProfileData* current) {
376379
return next;
377380
}
378381

382+
DataLayout* ciMethodData::next_data_layout(DataLayout* current) {
383+
int current_index = dp_to_di((address)current);
384+
int next_index = current_index + current->size_in_bytes();
385+
if (out_of_bounds(next_index)) {
386+
return NULL;
387+
}
388+
DataLayout* next = data_layout_at(next_index);
389+
return next;
390+
}
391+
379392
ciProfileData* ciMethodData::bci_to_extra_data(int bci, ciMethod* m, bool& two_free_slots) {
380393
DataLayout* dp = extra_data_base();
381394
DataLayout* end = args_data_limit();
@@ -413,12 +426,12 @@ ciProfileData* ciMethodData::bci_to_extra_data(int bci, ciMethod* m, bool& two_f
413426
ciProfileData* ciMethodData::bci_to_data(int bci, ciMethod* m) {
414427
// If m is not NULL we look for a SpeculativeTrapData entry
415428
if (m == NULL) {
416-
ciProfileData* data = data_before(bci);
417-
for ( ; is_valid(data); data = next_data(data)) {
418-
if (data->bci() == bci) {
419-
set_hint_di(dp_to_di(data->dp()));
420-
return data;
421-
} else if (data->bci() > bci) {
429+
DataLayout* data_layout = data_layout_before(bci);
430+
for ( ; is_valid(data_layout); data_layout = next_data_layout(data_layout)) {
431+
if (data_layout->bci() == bci) {
432+
set_hint_di(dp_to_di((address)data_layout));
433+
return data_from(data_layout);
434+
} else if (data_layout->bci() > bci) {
422435
break;
423436
}
424437
}

src/hotspot/share/ci/ciMethodData.hpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ class ciMethodData : public ciMetadata {
379379
// Data entries
380380
intptr_t* _data;
381381

382-
// Cached hint for data_before()
382+
// Cached hint for data_layout_before()
383383
int _hint_di;
384384

385385
// Is data attached? And is it mature?
@@ -445,17 +445,17 @@ class ciMethodData : public ciMetadata {
445445
assert(!out_of_bounds(di), "hint_di out of bounds");
446446
_hint_di = di;
447447
}
448-
ciProfileData* data_before(int bci) {
448+
449+
DataLayout* data_layout_before(int bci) {
449450
// avoid SEGV on this edge case
450451
if (data_size() == 0)
451452
return NULL;
452-
int hint = hint_di();
453-
if (data_layout_at(hint)->bci() <= bci)
454-
return data_at(hint);
455-
return first_data();
453+
DataLayout* layout = data_layout_at(hint_di());
454+
if (layout->bci() <= bci)
455+
return layout;
456+
return data_layout_at(first_di());
456457
}
457458

458-
459459
// What is the index of the first data entry?
460460
int first_di() { return 0; }
461461

@@ -469,6 +469,7 @@ class ciMethodData : public ciMetadata {
469469
template<class T> void dump_replay_data_call_type_helper(outputStream* out, int round, int& count, T* call_type_data);
470470
template<class T> void dump_replay_data_receiver_type_helper(outputStream* out, int round, int& count, T* call_type_data);
471471
void dump_replay_data_extra_data_helper(outputStream* out, int round, int& count);
472+
ciProfileData* data_from(DataLayout* data_layout);
472473

473474
public:
474475
bool is_method_data() const { return true; }
@@ -519,7 +520,9 @@ class ciMethodData : public ciMetadata {
519520
// Walk through the data in order.
520521
ciProfileData* first_data() { return data_at(first_di()); }
521522
ciProfileData* next_data(ciProfileData* current);
523+
DataLayout* next_data_layout(DataLayout* current);
522524
bool is_valid(ciProfileData* current) { return current != NULL; }
525+
bool is_valid(DataLayout* current) { return current != NULL; }
523526

524527
DataLayout* extra_data_base() const { return data_layout_at(data_size()); }
525528
DataLayout* args_data_limit() const { return data_layout_at(data_size() + extra_data_size() -

src/hotspot/share/oops/methodData.cpp

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,6 +1099,40 @@ ProfileData* MethodData::data_at(int data_index) const {
10991099
return data_layout->data_in();
11001100
}
11011101

1102+
int DataLayout::cell_count() {
1103+
switch (tag()) {
1104+
case DataLayout::no_tag:
1105+
default:
1106+
ShouldNotReachHere();
1107+
return 0;
1108+
case DataLayout::bit_data_tag:
1109+
return BitData::static_cell_count();
1110+
case DataLayout::counter_data_tag:
1111+
return CounterData::static_cell_count();
1112+
case DataLayout::jump_data_tag:
1113+
return JumpData::static_cell_count();
1114+
case DataLayout::receiver_type_data_tag:
1115+
return ReceiverTypeData::static_cell_count();
1116+
case DataLayout::virtual_call_data_tag:
1117+
return VirtualCallData::static_cell_count();
1118+
case DataLayout::ret_data_tag:
1119+
return RetData::static_cell_count();
1120+
case DataLayout::branch_data_tag:
1121+
return BranchData::static_cell_count();
1122+
case DataLayout::multi_branch_data_tag:
1123+
return ((new MultiBranchData(this))->cell_count());
1124+
case DataLayout::arg_info_data_tag:
1125+
return ((new ArgInfoData(this))->cell_count());
1126+
case DataLayout::call_type_data_tag:
1127+
return ((new CallTypeData(this))->cell_count());
1128+
case DataLayout::virtual_call_type_data_tag:
1129+
return ((new VirtualCallTypeData(this))->cell_count());
1130+
case DataLayout::parameters_type_data_tag:
1131+
return ((new ParametersTypeData(this))->cell_count());
1132+
case DataLayout::speculative_trap_data_tag:
1133+
return SpeculativeTrapData::static_cell_count();
1134+
}
1135+
}
11021136
ProfileData* DataLayout::data_in() {
11031137
switch (tag()) {
11041138
case DataLayout::no_tag:
@@ -1142,6 +1176,16 @@ ProfileData* MethodData::next_data(ProfileData* current) const {
11421176
return next;
11431177
}
11441178

1179+
DataLayout* MethodData::next_data_layout(DataLayout* current) const {
1180+
int current_index = dp_to_di((address)current);
1181+
int next_index = current_index + current->size_in_bytes();
1182+
if (out_of_bounds(next_index)) {
1183+
return NULL;
1184+
}
1185+
DataLayout* next = data_layout_at(next_index);
1186+
return next;
1187+
}
1188+
11451189
// Give each of the data entries a chance to perform specific
11461190
// data initialization.
11471191
void MethodData::post_initialize(BytecodeStream* stream) {
@@ -1314,13 +1358,13 @@ bool MethodData::is_mature() const {
13141358
// Translate a bci to its corresponding data index (di).
13151359
address MethodData::bci_to_dp(int bci) {
13161360
ResourceMark rm;
1317-
ProfileData* data = data_before(bci);
1318-
ProfileData* prev = NULL;
1319-
for ( ; is_valid(data); data = next_data(data)) {
1361+
DataLayout* data = data_layout_before(bci);
1362+
DataLayout* prev = NULL;
1363+
for ( ; is_valid(data); data = next_data_layout(data)) {
13201364
if (data->bci() >= bci) {
1321-
if (data->bci() == bci) set_hint_di(dp_to_di(data->dp()));
1322-
else if (prev != NULL) set_hint_di(dp_to_di(prev->dp()));
1323-
return data->dp();
1365+
if (data->bci() == bci) set_hint_di(dp_to_di((address)data));
1366+
else if (prev != NULL) set_hint_di(dp_to_di((address)prev));
1367+
return (address)data;
13241368
}
13251369
prev = data;
13261370
}
@@ -1329,11 +1373,11 @@ address MethodData::bci_to_dp(int bci) {
13291373

13301374
// Translate a bci to its corresponding data, or NULL.
13311375
ProfileData* MethodData::bci_to_data(int bci) {
1332-
ProfileData* data = data_before(bci);
1333-
for ( ; is_valid(data); data = next_data(data)) {
1376+
DataLayout* data = data_layout_before(bci);
1377+
for ( ; is_valid(data); data = next_data_layout(data)) {
13341378
if (data->bci() == bci) {
1335-
set_hint_di(dp_to_di(data->dp()));
1336-
return data;
1379+
set_hint_di(dp_to_di((address)data));
1380+
return data->data_in();
13371381
} else if (data->bci() > bci) {
13381382
break;
13391383
}

src/hotspot/share/oops/methodData.hpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,13 @@ class DataLayout {
236236

237237
ProfileData* data_in();
238238

239+
int size_in_bytes() {
240+
int cells = cell_count();
241+
assert(cells >= 0, "invalid number of cells");
242+
return DataLayout::compute_size_in_bytes(cells);
243+
}
244+
int cell_count();
245+
239246
// GC support
240247
void clean_weak_klass_links(bool always_clean);
241248
};
@@ -2053,14 +2060,15 @@ class MethodData : public Metadata {
20532060
assert(!out_of_bounds(di), "hint_di out of bounds");
20542061
_hint_di = di;
20552062
}
2056-
ProfileData* data_before(int bci) {
2063+
2064+
DataLayout* data_layout_before(int bci) {
20572065
// avoid SEGV on this edge case
20582066
if (data_size() == 0)
20592067
return NULL;
2060-
int hint = hint_di();
2061-
if (data_layout_at(hint)->bci() <= bci)
2062-
return data_at(hint);
2063-
return first_data();
2068+
DataLayout* layout = data_layout_at(hint_di());
2069+
if (layout->bci() <= bci)
2070+
return layout;
2071+
return data_layout_at(first_di());
20642072
}
20652073

20662074
// What is the index of the first data entry?
@@ -2243,7 +2251,9 @@ class MethodData : public Metadata {
22432251
// Walk through the data in order.
22442252
ProfileData* first_data() const { return data_at(first_di()); }
22452253
ProfileData* next_data(ProfileData* current) const;
2254+
DataLayout* next_data_layout(DataLayout* current) const;
22462255
bool is_valid(ProfileData* current) const { return current != NULL; }
2256+
bool is_valid(DataLayout* current) const { return current != NULL; }
22472257

22482258
// Convert a dp (data pointer) to a di (data index).
22492259
int dp_to_di(address dp) const {

0 commit comments

Comments
 (0)