Skip to content

Commit 89a032d

Browse files
author
Sergey Kuksenko
committed
8300002: Performance regression caused by non-inlined hot methods due to post call noop instructions
Reviewed-by: kvn, iveresov, eosterlund
1 parent 7071397 commit 89a032d

File tree

14 files changed

+73
-21
lines changed

14 files changed

+73
-21
lines changed

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,7 @@ void MacroAssembler::post_call_nop() {
11011101
}
11021102
InstructionMark im(this);
11031103
relocate(post_call_nop_Relocation::spec());
1104+
InlineSkippedInstructionsCounter skipCounter(this);
11041105
nop();
11051106
movk(zr, 0);
11061107
movk(zr, 0);

src/hotspot/cpu/ppc/macroAssembler_ppc.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,7 @@ void MacroAssembler::post_call_nop() {
11851185
if (!Continuations::enabled()) {
11861186
return;
11871187
}
1188+
InlineSkippedInstructionsCounter skipCounter(this);
11881189
nop();
11891190
}
11901191

src/hotspot/cpu/x86/macroAssembler_x86.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2035,6 +2035,7 @@ void MacroAssembler::post_call_nop() {
20352035
}
20362036
InstructionMark im(this);
20372037
relocate(post_call_nop_Relocation::spec());
2038+
InlineSkippedInstructionsCounter skipCounter(this);
20382039
emit_int8((int8_t)0x0f);
20392040
emit_int8((int8_t)0x1f);
20402041
emit_int8((int8_t)0x84);

src/hotspot/share/asm/assembler.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,19 @@ class AbstractAssembler : public ResourceObj {
241241
}
242242
};
243243
friend class InstructionMark;
244+
245+
// count size of instructions which are skipped from inline heuristics
246+
class InlineSkippedInstructionsCounter: public StackObj {
247+
private:
248+
AbstractAssembler* _assm;
249+
address _start;
250+
public:
251+
InlineSkippedInstructionsCounter(AbstractAssembler* assm) : _assm(assm), _start(assm->pc()) {
252+
}
253+
~InlineSkippedInstructionsCounter() {
254+
_assm->register_skipped(_assm->pc() - _start);
255+
}
256+
};
244257
#ifdef ASSERT
245258
// Make it return true on platforms which need to verify
246259
// instruction boundaries for some operations.
@@ -333,10 +346,13 @@ class AbstractAssembler : public ResourceObj {
333346
OopRecorder* oop_recorder() const { return _oop_recorder; }
334347
void set_oop_recorder(OopRecorder* r) { _oop_recorder = r; }
335348

349+
void register_skipped(int size) { code_section()->register_skipped(size); }
350+
336351
address inst_mark() const { return code_section()->mark(); }
337352
void set_inst_mark() { code_section()->set_mark(); }
338353
void clear_inst_mark() { code_section()->clear_mark(); }
339354

355+
340356
// Constants in code
341357
void relocate(RelocationHolder const& rspec, int format = 0) {
342358
assert(!pd_check_instruction_mark()

src/hotspot/share/asm/codeBuffer.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,17 @@ csize_t CodeBuffer::total_offset_of(const CodeSection* cs) const {
596596
return -1;
597597
}
598598

599+
int CodeBuffer::total_skipped_instructions_size() const {
600+
int total_skipped_size = 0;
601+
for (int n = (int) SECT_FIRST; n < (int) SECT_LIMIT; n++) {
602+
const CodeSection* cur_cs = code_section(n);
603+
if (!cur_cs->is_empty()) {
604+
total_skipped_size += cur_cs->_skipped_instructions_size;
605+
}
606+
}
607+
return total_skipped_size;
608+
}
609+
599610
csize_t CodeBuffer::total_relocation_size() const {
600611
csize_t total = copy_relocations_to(NULL); // dry run only
601612
return (csize_t) align_up(total, HeapWordSize);

src/hotspot/share/asm/codeBuffer.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ class CodeSection {
9898
address _locs_point; // last relocated position (grows upward)
9999
bool _locs_own; // did I allocate the locs myself?
100100
bool _scratch_emit; // Buffer is used for scratch emit, don't relocate.
101+
int _skipped_instructions_size;
101102
char _index; // my section number (SECT_INST, etc.)
102103
CodeBuffer* _outer; // enclosing CodeBuffer
103104

@@ -114,6 +115,7 @@ class CodeSection {
114115
_locs_point = NULL;
115116
_locs_own = false;
116117
_scratch_emit = false;
118+
_skipped_instructions_size = 0;
117119
debug_only(_index = (char)-1);
118120
debug_only(_outer = (CodeBuffer*)badAddress);
119121
}
@@ -144,6 +146,7 @@ class CodeSection {
144146
_end = cs->_end;
145147
_limit = cs->_limit;
146148
_locs_point = cs->_locs_point;
149+
_skipped_instructions_size = cs->_skipped_instructions_size;
147150
}
148151

149152
public:
@@ -204,6 +207,10 @@ class CodeSection {
204207
_locs_point = pc;
205208
}
206209

210+
void register_skipped(int size) {
211+
_skipped_instructions_size += size;
212+
}
213+
207214
// Code emission
208215
void emit_int8(uint8_t x1) {
209216
address curr = end();
@@ -638,6 +645,8 @@ class CodeBuffer: public StackObj DEBUG_ONLY(COMMA private Scrubber) {
638645
// allocated size of all relocation data, including index, rounded up
639646
csize_t total_relocation_size() const;
640647

648+
int total_skipped_instructions_size() const;
649+
641650
csize_t copy_relocations_to(address buf, csize_t buf_limit, bool only_inst) const;
642651

643652
// allocated size of any and all recorded oops

src/hotspot/share/ci/ciMethod.cpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ ciMethod::ciMethod(const methodHandle& h_m, ciInstanceKlass* holder) :
151151
}
152152
if (_interpreter_invocation_count == 0)
153153
_interpreter_invocation_count = 1;
154-
_instructions_size = -1;
154+
_inline_instructions_size = -1;
155155
if (ReplayCompiles) {
156156
ciReplay::initialize(this);
157157
}
@@ -172,7 +172,7 @@ ciMethod::ciMethod(ciInstanceKlass* holder,
172172
_method_data( NULL),
173173
_method_blocks( NULL),
174174
_intrinsic_id( vmIntrinsics::_none),
175-
_instructions_size(-1),
175+
_inline_instructions_size(-1),
176176
_can_be_statically_bound(false),
177177
_can_omit_stack_trace(true),
178178
_liveness( NULL)
@@ -1087,7 +1087,7 @@ bool ciMethod::can_be_compiled() {
10871087
// ------------------------------------------------------------------
10881088
// ciMethod::has_compiled_code
10891089
bool ciMethod::has_compiled_code() {
1090-
return instructions_size() > 0;
1090+
return inline_instructions_size() > 0;
10911091
}
10921092

10931093
int ciMethod::highest_osr_comp_level() {
@@ -1110,25 +1110,28 @@ int ciMethod::code_size_for_inlining() {
11101110
}
11111111

11121112
// ------------------------------------------------------------------
1113-
// ciMethod::instructions_size
1113+
// ciMethod::inline_instructions_size
11141114
//
11151115
// This is a rough metric for "fat" methods, compared before inlining
11161116
// with InlineSmallCode. The CodeBlob::code_size accessor includes
11171117
// junk like exception handler, stubs, and constant table, which are
11181118
// not highly relevant to an inlined method. So we use the more
11191119
// specific accessor nmethod::insts_size.
1120-
int ciMethod::instructions_size() {
1121-
if (_instructions_size == -1) {
1120+
// Also some instructions inside the code are excluded from inline
1121+
// heuristic (e.g. post call nop instructions; see InlineSkippedInstructionsCounter)
1122+
int ciMethod::inline_instructions_size() {
1123+
if (_inline_instructions_size == -1) {
11221124
GUARDED_VM_ENTRY(
1123-
CompiledMethod* code = get_Method()->code();
1124-
if (code != NULL && (code->comp_level() == CompLevel_full_optimization)) {
1125-
_instructions_size = code->insts_end() - code->verified_entry_point();
1126-
} else {
1127-
_instructions_size = 0;
1128-
}
1129-
);
1125+
CompiledMethod* code = get_Method()->code();
1126+
if (code != NULL && (code->comp_level() == CompLevel_full_optimization)) {
1127+
int isize = code->insts_end() - code->verified_entry_point() - code->skipped_instructions_size();
1128+
_inline_instructions_size = isize > 0 ? isize : 0;
1129+
} else {
1130+
_inline_instructions_size = 0;
1131+
}
1132+
);
11301133
}
1131-
return _instructions_size;
1134+
return _inline_instructions_size;
11321135
}
11331136

11341137
// ------------------------------------------------------------------
@@ -1315,7 +1318,7 @@ void ciMethod::dump_replay_data(outputStream* st) {
13151318
mcs == NULL ? 0 : mcs->backedge_counter()->raw_counter(),
13161319
interpreter_invocation_count(),
13171320
interpreter_throwout_count(),
1318-
_instructions_size);
1321+
_inline_instructions_size);
13191322
}
13201323

13211324
// ------------------------------------------------------------------

src/hotspot/share/ci/ciMethod.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class ciMethod : public ciMetadata {
8282
int _handler_count;
8383
int _interpreter_invocation_count;
8484
int _interpreter_throwout_count;
85-
int _instructions_size;
85+
int _inline_instructions_size;
8686
int _size_of_parameters;
8787

8888
bool _uses_monitors;
@@ -315,7 +315,8 @@ class ciMethod : public ciMetadata {
315315
bool check_call(int refinfo_index, bool is_static) const;
316316
bool ensure_method_data(); // make sure it exists in the VM also
317317
MethodCounters* ensure_method_counters();
318-
int instructions_size();
318+
319+
int inline_instructions_size();
319320
int scale_count(int count, float prof_factor = 1.); // make MDO count commensurate with IIC
320321

321322
// Stack walking support

src/hotspot/share/ci/ciReplay.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1529,7 +1529,7 @@ void ciReplay::initialize(ciMethod* m) {
15291529
} else {
15301530
EXCEPTION_CONTEXT;
15311531
// m->_instructions_size = rec->_instructions_size;
1532-
m->_instructions_size = -1;
1532+
m->_inline_instructions_size = -1;
15331533
m->_interpreter_invocation_count = rec->_interpreter_invocation_count;
15341534
m->_interpreter_throwout_count = rec->_interpreter_throwout_count;
15351535
MethodCounters* mcs = method->get_method_counters(CHECK_AND_CLEAR);

src/hotspot/share/code/compiledMethod.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,8 @@ class CompiledMethod : public CodeBlob {
281281
bool consts_contains(address addr) const { return consts_begin() <= addr && addr < consts_end(); }
282282
int consts_size() const { return consts_end() - consts_begin(); }
283283

284+
virtual int skipped_instructions_size() const = 0;
285+
284286
virtual address stub_begin() const = 0;
285287
virtual address stub_end() const = 0;
286288
bool stub_contains(address addr) const { return stub_begin() <= addr && addr < stub_end(); }

0 commit comments

Comments
 (0)