[aarch64-port-dev ] Rewrite frame setup for template interpreter
Andrew Haley
aph at redhat.com
Mon Dec 30 07:40:38 PST 2013
This is really just about efficiency. It's a rewrite of the template
interpreter's frame building code, with a saving of space in most cases
and time.
Andrew.
# HG changeset patch
# User aph
# Date 1388417759 0
# Node ID 0dca803e21acce6d715414c4f4591f4eec53a4d2
# Parent c7ed7e848e0780f58dda80b6344450896ae00481
Rewrite frame setup for template interpreter.
diff -r c7ed7e848e07 -r 0dca803e21ac src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.hpp
--- a/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.hpp Mon Dec 30 15:33:39 2013 +0000
+++ b/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.hpp Mon Dec 30 15:35:59 2013 +0000
@@ -29,7 +29,7 @@
protected:
-void generate_fixed_frame(bool native_call, Register stack_pointer);
+void generate_fixed_frame(bool native_call);
// address generate_asm_interpreter_entry(bool synchronized);
diff -r c7ed7e848e07 -r 0dca803e21ac src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp
--- a/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp Mon Dec 30 15:33:39 2013 +0000
+++ b/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp Mon Dec 30 15:35:59 2013 +0000
@@ -169,8 +169,13 @@
return entry;
}
-address TemplateInterpreterGenerator::generate_continuation_for(TosState state) { __ call_Unimplemented(); return 0; }
-
+address TemplateInterpreterGenerator::generate_continuation_for(TosState state) {
+ address entry = __ pc();
+ // NULL last_sp until next java call
+ __ str(zr, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
+ __ dispatch_next(state);
+ return entry;
+}
address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size) {
address entry = __ pc();
@@ -191,7 +196,7 @@
__ add(esp, esp, r1, Assembler::LSL, 3);
- // Restore machine SP in case i2c adjusted it
+ // Restore machine SP
__ ldr(rscratch1, Address(rmethod, Method::const_offset()));
__ ldrh(rscratch1, Address(rscratch1, ConstMethod::max_stack_offset()));
__ add(rscratch1, rscratch1, frame::interpreter_frame_monitor_size()
@@ -601,50 +606,43 @@
// rlocals: pointer to locals
// rcpool: cp cache
// stack_pointer: previous sp
-void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Register stack_pointer) {
+void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
// initialize fixed part of activation frame
- // return address does not need pushing as it was never popped
- // from the stack. instead enter() will save lr and leave will
- // restore it later
+ if (native_call) {
+ __ sub(esp, sp, 12 * wordSize);
+ __ mov(rbcp, zr);
+ __ stp(esp, zr, Address(__ pre(sp, -12 * wordSize)));
+ // add 2 zero-initialized slots for native calls
+ __ stp(zr, zr, Address(sp, 10 * wordSize));
+ } else {
+ __ sub(esp, sp, 10 * wordSize);
+ __ ldr(rscratch1, Address(rmethod, Method::const_offset())); // get ConstMethod
+ __ add(rbcp, rscratch1, in_bytes(ConstMethod::codes_offset())); // get codebase
+ __ stp(esp, rbcp, Address(__ pre(sp, -10 * wordSize)));
+ }
- // Save previous sp. If this is a native call, the higher word of
- // this pair will be used for oop_temp so it must be zeroed.
- // FIXME: Should we not always push zr?
- if (native_call)
- __ stp(stack_pointer, zr, Address(__ pre(sp, -2 * wordSize)));
- else
- __ str(stack_pointer, Address(__ pre(sp, -2 * wordSize)));
-
- __ enter(); // save old & set new rfp
-
- // set sender sp
- // leave last_sp as null
- __ stp(zr, r13, Address(__ pre(sp, -2 * wordSize)));
- __ ldr(rscratch1, Address(rmethod, Method::const_offset())); // get ConstMethod
- __ add(rbcp, rscratch1, in_bytes(ConstMethod::codes_offset())); // get codebase
if (ProfileInterpreter) {
Label method_data_continue;
__ ldr(rscratch1, Address(rmethod, Method::method_data_offset()));
__ cbz(rscratch1, method_data_continue);
__ lea(rscratch1, Address(rscratch1, in_bytes(MethodData::data_offset())));
__ bind(method_data_continue);
- __ stp(rscratch1, rmethod, Address(__ pre(sp, -2 * wordSize))); // save Method* and mdp (method data pointer)
+ __ stp(rscratch1, rmethod, Address(sp, 4 * wordSize)); // save Method* and mdp (method data pointer)
} else {
- __ stp(zr, rmethod, Address(__ pre(sp, -2 * wordSize))); // save Method* (no mdp)
+ __ stp(zr, rmethod, Address(sp, 4 * wordSize)); // save Method* (no mdp)
}
__ ldr(rcpool, Address(rmethod, Method::const_offset()));
__ ldr(rcpool, Address(rcpool, ConstMethod::constants_offset()));
__ ldr(rcpool, Address(rcpool, ConstantPool::cache_offset_in_bytes()));
- __ stp(rlocals, rcpool, Address(__ pre(sp, -2 * wordSize)));
+ __ stp(rlocals, rcpool, Address(sp, 2 * wordSize));
- if (native_call) {
- __ stp(zr, zr, Address(__ pre(sp, -2 * wordSize))); // no bcp
- } else {
- __ stp(zr, rbcp, Address(__ pre(sp, -2 * wordSize))); // set bcp
- }
+ __ stp(rfp, lr, Address(sp, 8 * wordSize));
+ __ lea(rfp, Address(sp, 8 * wordSize));
- __ mov(esp, sp); // Initialize expression stack pointer
+ // set sender sp
+ // leave last_sp as null
+ __ stp(zr, r13, Address(sp, 6 * wordSize));
// Move SP out of the way
if (! native_call) {
@@ -655,8 +653,6 @@
__ sub(rscratch1, sp, rscratch1, ext::uxtw, 3);
__ andr(sp, rscratch1, -16);
}
-
- __ str(esp, Address(esp)); // Initial ESP
}
// End of helpers
@@ -727,12 +723,11 @@
__ add(rlocals, esp, r2, ext::uxtx, 3);
__ add(rlocals, rlocals, -wordSize);
- // save sp
- __ mov(rscratch1, sp);
+ // Pull SP back to minimum size: this avoids holes in the stack
__ andr(sp, esp, -16);
// initialize fixed part of activation frame
- generate_fixed_frame(true, rscratch1);
+ generate_fixed_frame(true);
#ifndef PRODUCT
// tell the simulator that a method has been entered
if (NotifySimulator) {
@@ -1167,9 +1162,6 @@
__ add(rlocals, esp, r2, ext::uxtx, 3);
__ sub(rlocals, rlocals, wordSize);
- // Pass previous SP to save in generate_fixed_frame()
- __ mov(r10, sp);
-
// Make room for locals
__ sub(rscratch1, esp, r3, ext::uxtx, 3);
__ andr(sp, rscratch1, -16);
@@ -1192,7 +1184,7 @@
__ get_dispatch();
// initialize fixed part of activation frame
- generate_fixed_frame(false, r10);
+ generate_fixed_frame(false);
#ifndef PRODUCT
// tell the simulator that a method has been entered
if (NotifySimulator) {
More information about the aarch64-port-dev
mailing list