aboutsummaryrefslogtreecommitdiff
path: root/src/share/vm/interpreter
diff options
context:
space:
mode:
authoramurillo <none@none>2013-11-01 08:26:54 -0700
committeramurillo <none@none>2013-11-01 08:26:54 -0700
commit275be0d8f1c7556f4fa608e0e039baa6a00e1db3 (patch)
tree3050a23093402c125d5e6ffcdc7227a72a33e292 /src/share/vm/interpreter
parentd3e86f60571bc6e9dc0b09b96003d56970d68fb1 (diff)
parent21c86c80ce5e2b00f63338dadf8a78a5ce625c4d (diff)
Diffstat (limited to 'src/share/vm/interpreter')
-rw-r--r--src/share/vm/interpreter/abstractInterpreter.hpp4
-rw-r--r--src/share/vm/interpreter/cppInterpreter.hpp2
-rw-r--r--src/share/vm/interpreter/interpreter.cpp18
-rw-r--r--src/share/vm/interpreter/templateInterpreter.cpp86
-rw-r--r--src/share/vm/interpreter/templateInterpreter.hpp18
-rw-r--r--src/share/vm/interpreter/templateInterpreterGenerator.hpp2
6 files changed, 93 insertions, 37 deletions
diff --git a/src/share/vm/interpreter/abstractInterpreter.hpp b/src/share/vm/interpreter/abstractInterpreter.hpp
index 4d7647ce0..0ebfd1cdf 100644
--- a/src/share/vm/interpreter/abstractInterpreter.hpp
+++ b/src/share/vm/interpreter/abstractInterpreter.hpp
@@ -158,8 +158,8 @@ class AbstractInterpreter: AllStatic {
// Runtime support
// length = invoke bytecode length (to advance to next bytecode)
- static address deopt_entry (TosState state, int length) { ShouldNotReachHere(); return NULL; }
- static address return_entry (TosState state, int length) { ShouldNotReachHere(); return NULL; }
+ static address deopt_entry(TosState state, int length) { ShouldNotReachHere(); return NULL; }
+ static address return_entry(TosState state, int length, Bytecodes::Code code) { ShouldNotReachHere(); return NULL; }
static address rethrow_exception_entry() { return _rethrow_exception_entry; }
diff --git a/src/share/vm/interpreter/cppInterpreter.hpp b/src/share/vm/interpreter/cppInterpreter.hpp
index 4997a4432..71f78840b 100644
--- a/src/share/vm/interpreter/cppInterpreter.hpp
+++ b/src/share/vm/interpreter/cppInterpreter.hpp
@@ -78,7 +78,7 @@ class CppInterpreter: public AbstractInterpreter {
static address stack_result_to_stack(int index) { return _stack_to_stack[index]; }
static address stack_result_to_native(int index) { return _stack_to_native_abi[index]; }
- static address return_entry (TosState state, int length);
+ static address return_entry (TosState state, int length, Bytecodes::Code code);
static address deopt_entry (TosState state, int length);
#ifdef TARGET_ARCH_x86
diff --git a/src/share/vm/interpreter/interpreter.cpp b/src/share/vm/interpreter/interpreter.cpp
index dfd8b5b14..60246e901 100644
--- a/src/share/vm/interpreter/interpreter.cpp
+++ b/src/share/vm/interpreter/interpreter.cpp
@@ -329,15 +329,21 @@ void AbstractInterpreter::print_method_kind(MethodKind kind) {
//------------------------------------------------------------------------------------------------------------------------
// Deoptimization support
-// If deoptimization happens, this function returns the point of next bytecode to continue execution
+/**
+ * If a deoptimization happens, this function returns the point of next bytecode to continue execution.
+ */
address AbstractInterpreter::deopt_continue_after_entry(Method* method, address bcp, int callee_parameters, bool is_top_frame) {
assert(method->contains(bcp), "just checkin'");
- Bytecodes::Code code = Bytecodes::java_code_at(method, bcp);
+
+ // Get the original and rewritten bytecode.
+ Bytecodes::Code code = Bytecodes::java_code_at(method, bcp);
assert(!Interpreter::bytecode_should_reexecute(code), "should not reexecute");
- int bci = method->bci_from(bcp);
- int length = -1; // initial value for debugging
+
+ const int bci = method->bci_from(bcp);
+
// compute continuation length
- length = Bytecodes::length_at(method, bcp);
+ const int length = Bytecodes::length_at(method, bcp);
+
// compute result type
BasicType type = T_ILLEGAL;
@@ -393,7 +399,7 @@ address AbstractInterpreter::deopt_continue_after_entry(Method* method, address
return
is_top_frame
? Interpreter::deopt_entry (as_TosState(type), length)
- : Interpreter::return_entry(as_TosState(type), length);
+ : Interpreter::return_entry(as_TosState(type), length, code);
}
// If deoptimization happens, this function returns the point where the interpreter reexecutes
diff --git a/src/share/vm/interpreter/templateInterpreter.cpp b/src/share/vm/interpreter/templateInterpreter.cpp
index 9f7ed4c7e..e3e89e8ee 100644
--- a/src/share/vm/interpreter/templateInterpreter.cpp
+++ b/src/share/vm/interpreter/templateInterpreter.cpp
@@ -184,8 +184,9 @@ EntryPoint TemplateInterpreter::_deopt_entry [TemplateInterpreter::number_of_deo
EntryPoint TemplateInterpreter::_continuation_entry;
EntryPoint TemplateInterpreter::_safept_entry;
-address TemplateInterpreter::_return_3_addrs_by_index[TemplateInterpreter::number_of_return_addrs];
-address TemplateInterpreter::_return_5_addrs_by_index[TemplateInterpreter::number_of_return_addrs];
+address TemplateInterpreter::_invoke_return_entry[TemplateInterpreter::number_of_return_addrs];
+address TemplateInterpreter::_invokeinterface_return_entry[TemplateInterpreter::number_of_return_addrs];
+address TemplateInterpreter::_invokedynamic_return_entry[TemplateInterpreter::number_of_return_addrs];
DispatchTable TemplateInterpreter::_active_table;
DispatchTable TemplateInterpreter::_normal_table;
@@ -237,22 +238,37 @@ void TemplateInterpreterGenerator::generate_all() {
#endif // !PRODUCT
{ CodeletMark cm(_masm, "return entry points");
+ const int index_size = sizeof(u2);
for (int i = 0; i < Interpreter::number_of_return_entries; i++) {
Interpreter::_return_entry[i] =
EntryPoint(
- generate_return_entry_for(itos, i),
- generate_return_entry_for(itos, i),
- generate_return_entry_for(itos, i),
- generate_return_entry_for(atos, i),
- generate_return_entry_for(itos, i),
- generate_return_entry_for(ltos, i),
- generate_return_entry_for(ftos, i),
- generate_return_entry_for(dtos, i),
- generate_return_entry_for(vtos, i)
+ generate_return_entry_for(itos, i, index_size),
+ generate_return_entry_for(itos, i, index_size),
+ generate_return_entry_for(itos, i, index_size),
+ generate_return_entry_for(atos, i, index_size),
+ generate_return_entry_for(itos, i, index_size),
+ 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)
);
}
}
+ { CodeletMark cm(_masm, "invoke return entry points");
+ const TosState states[] = {itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos};
+ 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++) {
+ TosState state = states[i];
+ 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));
+ }
+ }
+
{ CodeletMark cm(_masm, "earlyret entry points");
Interpreter::_earlyret_entry =
EntryPoint(
@@ -298,13 +314,6 @@ void TemplateInterpreterGenerator::generate_all() {
}
}
- for (int j = 0; j < number_of_states; j++) {
- const TosState states[] = {btos, ctos, stos, itos, ltos, ftos, dtos, atos, vtos};
- int index = Interpreter::TosState_as_index(states[j]);
- Interpreter::_return_3_addrs_by_index[index] = Interpreter::return_entry(states[j], 3);
- Interpreter::_return_5_addrs_by_index[index] = Interpreter::return_entry(states[j], 5);
- }
-
{ CodeletMark cm(_masm, "continuation entry points");
Interpreter::_continuation_entry =
EntryPoint(
@@ -534,9 +543,46 @@ void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState t
//------------------------------------------------------------------------------------------------------------------------
// Entry points
-address TemplateInterpreter::return_entry(TosState state, int length) {
+/**
+ * Returns the return entry table for the given invoke bytecode.
+ */
+address* TemplateInterpreter::invoke_return_entry_table_for(Bytecodes::Code code) {
+ switch (code) {
+ case Bytecodes::_invokestatic:
+ case Bytecodes::_invokespecial:
+ case Bytecodes::_invokevirtual:
+ case Bytecodes::_invokehandle:
+ return Interpreter::invoke_return_entry_table();
+ case Bytecodes::_invokeinterface:
+ return Interpreter::invokeinterface_return_entry_table();
+ case Bytecodes::_invokedynamic:
+ return Interpreter::invokedynamic_return_entry_table();
+ default:
+ fatal(err_msg("invalid bytecode: %s", Bytecodes::name(code)));
+ return NULL;
+ }
+}
+
+/**
+ * Returns the return entry address for the given top-of-stack state and bytecode.
+ */
+address TemplateInterpreter::return_entry(TosState state, int length, Bytecodes::Code code) {
guarantee(0 <= length && length < Interpreter::number_of_return_entries, "illegal length");
- return _return_entry[length].entry(state);
+ const int index = TosState_as_index(state);
+ switch (code) {
+ case Bytecodes::_invokestatic:
+ case Bytecodes::_invokespecial:
+ case Bytecodes::_invokevirtual:
+ case Bytecodes::_invokehandle:
+ return _invoke_return_entry[index];
+ case Bytecodes::_invokeinterface:
+ return _invokeinterface_return_entry[index];
+ case Bytecodes::_invokedynamic:
+ return _invokedynamic_return_entry[index];
+ default:
+ assert(!Bytecodes::is_invoke(code), err_msg("invoke instructions should be handled separately: %s", Bytecodes::name(code)));
+ return _return_entry[length].entry(state);
+ }
}
diff --git a/src/share/vm/interpreter/templateInterpreter.hpp b/src/share/vm/interpreter/templateInterpreter.hpp
index 43fe4bdb1..838e2e084 100644
--- a/src/share/vm/interpreter/templateInterpreter.hpp
+++ b/src/share/vm/interpreter/templateInterpreter.hpp
@@ -120,8 +120,9 @@ class TemplateInterpreter: public AbstractInterpreter {
static EntryPoint _continuation_entry;
static EntryPoint _safept_entry;
- static address _return_3_addrs_by_index[number_of_return_addrs]; // for invokevirtual return entries
- static address _return_5_addrs_by_index[number_of_return_addrs]; // for invokeinterface return entries
+ static address _invoke_return_entry[number_of_return_addrs]; // for invokestatic, invokespecial, invokevirtual return entries
+ static address _invokeinterface_return_entry[number_of_return_addrs]; // for invokeinterface return entries
+ static address _invokedynamic_return_entry[number_of_return_addrs]; // for invokedynamic return entries
static DispatchTable _active_table; // the active dispatch table (used by the interpreter for dispatch)
static DispatchTable _normal_table; // the normal dispatch table (used to set the active table in normal mode)
@@ -161,12 +162,15 @@ class TemplateInterpreter: public AbstractInterpreter {
static address* normal_table() { return _normal_table.table_for(); }
// Support for invokes
- static address* return_3_addrs_by_index_table() { return _return_3_addrs_by_index; }
- static address* return_5_addrs_by_index_table() { return _return_5_addrs_by_index; }
- static int TosState_as_index(TosState state); // computes index into return_3_entry_by_index table
+ static address* invoke_return_entry_table() { return _invoke_return_entry; }
+ static address* invokeinterface_return_entry_table() { return _invokeinterface_return_entry; }
+ static address* invokedynamic_return_entry_table() { return _invokedynamic_return_entry; }
+ static int TosState_as_index(TosState state);
- static address return_entry (TosState state, int length);
- static address deopt_entry (TosState state, int length);
+ static address* invoke_return_entry_table_for(Bytecodes::Code code);
+
+ static address deopt_entry(TosState state, int length);
+ static address return_entry(TosState state, int length, Bytecodes::Code code);
// Safepoint support
static void notice_safepoints(); // stops the thread when reaching a safepoint
diff --git a/src/share/vm/interpreter/templateInterpreterGenerator.hpp b/src/share/vm/interpreter/templateInterpreterGenerator.hpp
index fb7bdc5b6..a80caa964 100644
--- a/src/share/vm/interpreter/templateInterpreterGenerator.hpp
+++ b/src/share/vm/interpreter/templateInterpreterGenerator.hpp
@@ -53,7 +53,7 @@ class TemplateInterpreterGenerator: public AbstractInterpreterGenerator {
address generate_ClassCastException_handler();
address generate_ArrayIndexOutOfBounds_handler(const char* name);
address generate_continuation_for(TosState state);
- address generate_return_entry_for(TosState state, int step);
+ address generate_return_entry_for(TosState state, int step, size_t index_size);
address generate_earlyret_entry_for(TosState state);
address generate_deopt_entry_for(TosState state, int step);
address generate_safept_entry_for(TosState state, address runtime_entry);