Index: runtime/vm/code_generator.cc |
=================================================================== |
--- runtime/vm/code_generator.cc (revision 22714) |
+++ runtime/vm/code_generator.cc (working copy) |
@@ -1489,19 +1489,20 @@ |
// are copied into local space at method entry). |
const intptr_t num_args = |
function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); |
- // FP, PC-marker and return-address will be copied as well. |
+ // The fixed size section of the (fake) Dart frame called via a stub by the |
+ // optimized function contains FP, PP (ARM and MIPS only), PC-marker and |
+ // return-address. This section is copied as well, so that its contained |
+ // values can be updated before returning to the deoptimized function. |
const intptr_t frame_copy_size = |
- // Deoptimized function's return address: caller_frame->pc(). |
- - kSavedPcSlotFromSp |
- + ((frame.fp() - frame.sp()) / kWordSize) |
+ + kDartFrameFixedSize // For saved values below sp. |
+ + ((frame.fp() - frame.sp()) / kWordSize) // For frame size incl. sp. |
+ 1 // For fp. |
- + kParamEndSlotFromFp |
- + num_args; |
+ + kParamEndSlotFromFp // For saved values above fp. |
+ + num_args; // For arguments. |
intptr_t* frame_copy = new intptr_t[frame_copy_size]; |
ASSERT(frame_copy != NULL); |
- // Include the return address of optimized code. |
intptr_t* start = reinterpret_cast<intptr_t*>( |
- frame.sp() + (kSavedPcSlotFromSp * kWordSize)); |
+ frame.sp() - (kDartFrameFixedSize * kWordSize)); |
for (intptr_t i = 0; i < frame_copy_size; i++) { |
frame_copy[i] = *(start + i); |
} |
@@ -1517,12 +1518,11 @@ |
StackZone zone(isolate); |
HANDLESCOPE(isolate); |
- // All registers have been saved below last-fp. |
- // Note that the deopt stub is not allowed to save any other values (pc |
- // marker, pool pointer, alignment, etc...) below last-fp. |
- const uword last_fp = saved_registers_address + |
- kNumberOfCpuRegisters * kWordSize + |
- kNumberOfFpuRegisters * kFpuRegisterSize; |
+ // All registers have been saved below last-fp as if they were locals. |
+ const uword last_fp = saved_registers_address |
+ + (kNumberOfCpuRegisters * kWordSize) |
+ + (kNumberOfFpuRegisters * kFpuRegisterSize) |
+ - ((kFirstLocalSlotFromFp + 1) * kWordSize); |
CopySavedRegisters(saved_registers_address); |
// Get optimized code and frame that need to be deoptimized. |
@@ -1555,20 +1555,21 @@ |
const Function& function = Function::Handle(optimized_code.function()); |
const intptr_t num_args = |
function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); |
- intptr_t unoptimized_stack_size = |
+ const intptr_t unoptimized_stack_size = |
+ deopt_info.FrameSize() |
+ - kDartFrameFixedSize |
- num_args |
- kParamEndSlotFromFp |
- 1; // For fp. |
- return unoptimized_stack_size * kWordSize; |
+ return unoptimized_stack_size * kWordSize; // Stack size (FP - SP) in bytes. |
} |
END_LEAF_RUNTIME_ENTRY |
-static intptr_t DeoptimizeWithDeoptInfo(const Code& code, |
- const DeoptInfo& deopt_info, |
- const StackFrame& caller_frame, |
- intptr_t deopt_reason) { |
+static void DeoptimizeWithDeoptInfo(const Code& code, |
+ const DeoptInfo& deopt_info, |
+ const StackFrame& caller_frame, |
+ intptr_t deopt_reason) { |
const intptr_t len = deopt_info.TranslationLength(); |
GrowableArray<DeoptInstr*> deopt_instructions(len); |
const Array& deopt_table = Array::Handle(code.deopt_info_array()); |
@@ -1576,12 +1577,12 @@ |
deopt_info.ToInstructions(deopt_table, &deopt_instructions); |
intptr_t* start = reinterpret_cast<intptr_t*>( |
- caller_frame.sp() + (kSavedPcSlotFromSp * kWordSize)); |
+ caller_frame.sp() - (kDartFrameFixedSize * kWordSize)); |
const Function& function = Function::Handle(code.function()); |
const intptr_t num_args = |
function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); |
const intptr_t to_frame_size = |
- - kSavedPcSlotFromSp // Deoptimized function's return address. |
+ + kDartFrameFixedSize // For saved values below sp. |
+ (caller_frame.fp() - caller_frame.sp()) / kWordSize |
+ 1 // For fp. |
+ kParamEndSlotFromFp |
@@ -1603,7 +1604,7 @@ |
// right before control switches to the unoptimized code. |
const intptr_t num_materializations = len - frame_size; |
Isolate::Current()->PrepareForDeferredMaterialization(num_materializations); |
- for (intptr_t from_index = 0, to_index = 1; |
+ for (intptr_t from_index = 0, to_index = kDartFrameFixedSize; |
from_index < num_materializations; |
from_index++) { |
const intptr_t field_count = |
@@ -1631,13 +1632,12 @@ |
deopt_instructions[i + (len - frame_size)]->ToCString()); |
} |
} |
- return deopt_context.GetCallerFp(); |
} |
// The stack has been adjusted to fit all values for unoptimized frame. |
// Fill the unoptimized frame. |
-DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeFillFrame, uword last_fp) { |
+DEFINE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp) { |
Isolate* isolate = Isolate::Current(); |
StackZone zone(isolate); |
HANDLESCOPE(isolate); |
@@ -1661,10 +1661,10 @@ |
optimized_code.GetDeoptInfoAtPc(caller_frame->pc(), &deopt_reason)); |
ASSERT(!deopt_info.IsNull()); |
- const intptr_t caller_fp = DeoptimizeWithDeoptInfo(optimized_code, |
- deopt_info, |
- *caller_frame, |
- deopt_reason); |
+ DeoptimizeWithDeoptInfo(optimized_code, |
+ deopt_info, |
+ *caller_frame, |
+ deopt_reason); |
isolate->SetDeoptFrameCopy(NULL, 0); |
isolate->set_deopt_cpu_registers_copy(NULL); |
@@ -1672,8 +1672,6 @@ |
delete[] frame_copy; |
delete[] cpu_registers_copy; |
delete[] fpu_registers_copy; |
- |
- return caller_fp; |
} |
END_LEAF_RUNTIME_ENTRY |