Skip to content
Permalink
Browse files
8255271: Avoid generating duplicate interpreter entries for subword t…
…ypes

Reviewed-by: iklam, coleenp
  • Loading branch information
cl4es committed Oct 23, 2020
1 parent 5ec1b80 commit cc86113
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 43 deletions.
@@ -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());
@@ -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);
@@ -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");
@@ -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
@@ -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),

1 comment on commit cc86113

@bridgekeeper
Copy link

@bridgekeeper bridgekeeper bot commented on cc86113 Oct 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.