< prev index next >
src/hotspot/cpu/x86/frame_x86.cpp
Print this page
@@ -142,17 +142,20 @@
sender_sp = _unextended_sp + _cb->frame_size();
// Is sender_sp safe?
if ((address)sender_sp >= thread->stack_base()) {
return false;
}
- sender_unextended_sp = sender_sp;
// On Intel the return_address is always the word on the stack
sender_pc = (address) *(sender_sp-1);
// Note: frame::sender_sp_offset is only valid for compiled frame
- saved_fp = (intptr_t*) *(sender_sp - frame::sender_sp_offset);
- }
+ intptr_t** saved_fp_addr = (intptr_t**) (sender_sp - frame::sender_sp_offset);
+ saved_fp = *saved_fp_addr;
+ // Repair the sender sp if this is a method with scalarized value type args
+ sender_sp = repair_sender_sp(sender_sp, saved_fp_addr);
+ sender_unextended_sp = sender_sp;
+ }
// If the potential sender is the interpreter then we can do some more checking
if (Interpreter::contains(sender_pc)) {
// ebp is always saved in a recognizable place in any code we generate. However
@@ -452,19 +455,21 @@
assert(map != NULL, "map must be set");
// frame owned by optimizing compiler
assert(_cb->frame_size() >= 0, "must have non-zero frame size");
intptr_t* sender_sp = unextended_sp() + _cb->frame_size();
- intptr_t* unextended_sp = sender_sp;
// On Intel the return_address is always the word on the stack
address sender_pc = (address) *(sender_sp-1);
// This is the saved value of EBP which may or may not really be an FP.
// It is only an FP if the sender is an interpreter frame (or C1?).
intptr_t** saved_fp_addr = (intptr_t**) (sender_sp - frame::sender_sp_offset);
+ // Repair the sender sp if this is a method with scalarized value type args
+ sender_sp = repair_sender_sp(sender_sp, saved_fp_addr);
+
if (map->update_map()) {
// Tell GC to use argument oopmaps for some runtime stubs that need it.
// For C1, the runtime stub might not have oop maps, so set this flag
// outside of update_register_map.
map->set_include_argument_oops(_cb->caller_must_gc_arguments(map->thread()));
@@ -477,11 +482,11 @@
// since if our caller was compiled code there could be live jvm state in it.
update_map_with_saved_link(map, saved_fp_addr);
}
assert(sender_sp != sp(), "must have changed");
- return frame(sender_sp, unextended_sp, *saved_fp_addr, sender_pc);
+ return frame(sender_sp, sender_sp, *saved_fp_addr, sender_pc);
}
//------------------------------------------------------------------------------
// frame::sender
@@ -583,10 +588,11 @@
tos_addr = (intptr_t*)interpreter_frame_tos_address();
}
switch (type) {
case T_OBJECT :
+ case T_VALUETYPE:
case T_ARRAY : {
oop obj;
if (method->is_native()) {
obj = cast_to_oop(at(interpreter_frame_oop_temp_offset));
} else {
@@ -684,10 +690,26 @@
}
void frame::pd_ps() {}
#endif
+// Check for a method with scalarized value type arguments that needs
+// a stack repair and return the repaired sender stack pointer.
+intptr_t* frame::repair_sender_sp(intptr_t* sender_sp, intptr_t** saved_fp_addr) const {
+ CompiledMethod* cm = _cb->as_compiled_method_or_null();
+ if (cm != NULL && cm->method()->needs_stack_repair()) {
+ // The stack increment resides just below the saved rbp on the stack
+ // and does not account for the return address.
+ intptr_t* sp_inc_addr = (intptr_t*) (saved_fp_addr - 1);
+ int sp_inc = (*sp_inc_addr) / wordSize;
+ int real_frame_size = sp_inc + 1; // Add size of return address
+ assert(real_frame_size >= _cb->frame_size(), "invalid frame size");
+ sender_sp = unextended_sp() + real_frame_size;
+ }
+ return sender_sp;
+}
+
void JavaFrameAnchor::make_walkable(JavaThread* thread) {
// last frame set?
if (last_Java_sp() == NULL) return;
// already walkable?
if (walkable()) return;
< prev index next >