8255271: Avoid generating duplicate interpreter entries for subword types

Reviewed-by: iklam, coleenp
This commit is contained in:
Claes Redestad 2020-10-23 15:37:46 +00:00
parent 5ec1b80c4a
commit cc861134f4
5 changed files with 48 additions and 43 deletions

View File

@ -257,11 +257,6 @@ int CodeBuffer::locator(address addr) const {
return -1;
}
address CodeBuffer::locator_address(int locator) const {
if (locator < 0) return NULL;
address start = code_section(locator_sect(locator))->start();
return start + locator_pos(locator);
}
bool CodeBuffer::is_backward_branch(Label& L) {
return L.is_bound() && insts_end() <= locator_address(L.loc());

View File

@ -556,7 +556,11 @@ class CodeBuffer: public StackObj {
static int locator_sect(int locator) { return locator & sect_mask; }
static int locator(int pos, int sect) { return (pos << sect_bits) | sect; }
int locator(address addr) const;
address locator_address(int locator) const;
address locator_address(int locator) const {
if (locator < 0) return NULL;
address start = code_section(locator_sect(locator))->start();
return start + locator_pos(locator);
}
// Heuristic for pre-packing the taken/not-taken bit of a predicted branch.
bool is_backward_branch(Label& L);

View File

@ -104,6 +104,19 @@ EntryPoint::EntryPoint(address bentry, address zentry, address centry, address s
_entry[vtos] = ventry;
}
EntryPoint::EntryPoint(address aentry, address ientry, address lentry, address fentry, address dentry, address ventry) {
assert(number_of_states == 10, "check the code below");
_entry[btos] = ientry;
_entry[ztos] = ientry;
_entry[ctos] = ientry;
_entry[stos] = ientry;
_entry[atos] = aentry;
_entry[itos] = ientry;
_entry[ltos] = lentry;
_entry[ftos] = fentry;
_entry[dtos] = dentry;
_entry[vtos] = ventry;
}
void EntryPoint::set_entry(TosState state, address entry) {
assert(0 <= state && state < number_of_states, "state out of bounds");

View File

@ -48,7 +48,8 @@ class EntryPoint {
// Construction
EntryPoint();
EntryPoint(address bentry, address zentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry);
// Will use the ientry for each of [bzcs]entry
EntryPoint(address aentry, address ientry, address lentry, address fentry, address dentry, address ventry);
// Attributes
address entry(TosState state) const; // return target address for a given tosca state
void set_entry(TosState state, address entry); // set target address for a given tosca state

View File

@ -68,10 +68,6 @@ void TemplateInterpreterGenerator::generate_all() {
CodeletMark cm(_masm, "bytecode tracing support");
Interpreter::_trace_code =
EntryPoint(
generate_trace_code(btos),
generate_trace_code(ztos),
generate_trace_code(ctos),
generate_trace_code(stos),
generate_trace_code(atos),
generate_trace_code(itos),
generate_trace_code(ltos),
@ -83,50 +79,54 @@ void TemplateInterpreterGenerator::generate_all() {
#endif // !PRODUCT
{ CodeletMark cm(_masm, "return entry points");
const int index_size = sizeof(u2);
Interpreter::_return_entry[0] = EntryPoint();
for (int i = 1; i < Interpreter::number_of_return_entries; i++) {
address return_itos = generate_return_entry_for(itos, i, index_size);
Interpreter::_return_entry[i] =
EntryPoint(
return_itos,
return_itos,
return_itos,
return_itos,
generate_return_entry_for(atos, i, index_size),
return_itos,
generate_return_entry_for(ltos, i, index_size),
generate_return_entry_for(ftos, i, index_size),
generate_return_entry_for(dtos, i, index_size),
generate_return_entry_for(vtos, i, index_size)
generate_return_entry_for(atos, i, sizeof(u2)),
generate_return_entry_for(itos, i, sizeof(u2)),
generate_return_entry_for(ltos, i, sizeof(u2)),
generate_return_entry_for(ftos, i, sizeof(u2)),
generate_return_entry_for(dtos, i, sizeof(u2)),
generate_return_entry_for(vtos, i, sizeof(u2))
);
}
}
{ CodeletMark cm(_masm, "invoke return entry points");
// These states are in order specified in TosState, except btos/ztos/ctos/stos are
// really the same as itos since there is no top of stack optimization for these types
const TosState states[] = {itos, itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos, ilgl};
// These states are in order specified in TosState, except btos/ztos/ctos/stos which
// are the same as itos since there is no top of stack optimization for these types
const TosState states[] = {ilgl, ilgl, ilgl, ilgl, itos, ltos, ftos, dtos, atos, vtos, ilgl};
const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic);
const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface);
const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic);
for (int i = 0; i < Interpreter::number_of_return_addrs; i++) {
assert(invoke_length >= 0 && invoke_length < Interpreter::number_of_return_entries, "invariant");
assert(invokeinterface_length >= 0 && invokeinterface_length < Interpreter::number_of_return_entries, "invariant");
for (int i = itos; i < Interpreter::number_of_return_addrs; i++) {
TosState state = states[i];
assert(state != ilgl, "states array is wrong above");
Interpreter::_invoke_return_entry[i] = generate_return_entry_for(state, invoke_length, sizeof(u2));
Interpreter::_invokeinterface_return_entry[i] = generate_return_entry_for(state, invokeinterface_length, sizeof(u2));
Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4));
// Reuse generated entry points
Interpreter::_invoke_return_entry[i] = Interpreter::_return_entry[invoke_length].entry(state);
Interpreter::_invokeinterface_return_entry[i] = Interpreter::_return_entry[invokeinterface_length].entry(state);
Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4));
}
// set itos entry points for btos/ztos/ctos/stos
for (int i = 0; i < itos; i++) {
Interpreter::_invoke_return_entry[i] = Interpreter::_invoke_return_entry[itos];
Interpreter::_invokeinterface_return_entry[i] = Interpreter::_invokeinterface_return_entry[itos];
Interpreter::_invokedynamic_return_entry[i] = Interpreter::_invokedynamic_return_entry[itos];
}
}
{ CodeletMark cm(_masm, "earlyret entry points");
address earlyret_entry_itos = generate_earlyret_entry_for(itos);
Interpreter::_earlyret_entry =
EntryPoint(
generate_earlyret_entry_for(btos),
generate_earlyret_entry_for(ztos),
generate_earlyret_entry_for(ctos),
generate_earlyret_entry_for(stos),
generate_earlyret_entry_for(atos),
generate_earlyret_entry_for(itos),
generate_earlyret_entry_for(ltos),
@ -153,10 +153,6 @@ void TemplateInterpreterGenerator::generate_all() {
{ CodeletMark cm(_masm, "safepoint entry points");
Interpreter::_safept_entry =
EntryPoint(
generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
generate_safept_entry_for(ztos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
@ -242,12 +238,8 @@ void TemplateInterpreterGenerator::generate_all() {
address deopt_itos = generate_deopt_entry_for(itos, i);
Interpreter::_deopt_entry[i] =
EntryPoint(
deopt_itos, /* btos */
deopt_itos, /* ztos */
deopt_itos, /* ctos */
deopt_itos, /* stos */
generate_deopt_entry_for(atos, i),
deopt_itos, /* itos */
generate_deopt_entry_for(itos, i),
generate_deopt_entry_for(ltos, i),
generate_deopt_entry_for(ftos, i),
generate_deopt_entry_for(dtos, i),