Index: src/mips/deoptimizer-mips.cc |
diff --git a/src/mips/deoptimizer-mips.cc b/src/mips/deoptimizer-mips.cc |
index 62f3155eb34382708e8f3e9cac14e9c3746125c4..b57d2d3a964c8cbfa9e777219e0704e9aff2d81e 100644 |
--- a/src/mips/deoptimizer-mips.cc |
+++ b/src/mips/deoptimizer-mips.cc |
@@ -48,6 +48,10 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) { |
if (!function->IsOptimized()) return; |
+ // The optimized code is going to be patched, so we cannot use it |
+ // any more. Play safe and reset the whole cache. |
+ function->shared()->ClearOptimizedCodeMap(); |
+ |
// Get the optimized code. |
Code* code = function->code(); |
Address code_start_address = code->instruction_start(); |
@@ -96,8 +100,19 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) { |
// ignore all slots that might have been recorded on it. |
isolate->heap()->mark_compact_collector()->InvalidateCode(code); |
- // Set the code for the function to non-optimized version. |
- function->ReplaceCode(function->shared()->code()); |
+ // Iterate over all the functions which share the same code object |
+ // and make them use unoptimized version. |
+ Context* context = function->context()->global_context(); |
+ Object* element = context->get(Context::OPTIMIZED_FUNCTIONS_LIST); |
+ SharedFunctionInfo* shared = function->shared(); |
+ while (!element->IsUndefined()) { |
+ JSFunction* func = JSFunction::cast(element); |
+ // Grab element before code replacement as ReplaceCode alters the list. |
+ element = func->next_function_link(); |
+ if (func->code() == code) { |
+ func->ReplaceCode(shared->code()); |
+ } |
+ } |
if (FLAG_trace_deopt) { |
PrintF("[forced deoptimization: "); |
@@ -229,9 +244,9 @@ void Deoptimizer::DoComputeOsrOutputFrame() { |
unsigned node_id = iterator.Next(); |
USE(node_id); |
ASSERT(node_id == ast_id); |
- JSFunction* function = JSFunction::cast(ComputeLiteral(iterator.Next())); |
- USE(function); |
- ASSERT(function == function_); |
+ int closure_id = iterator.Next(); |
+ USE(closure_id); |
+ ASSERT_EQ(Translation::kSelfLiteralId, closure_id); |
unsigned height = iterator.Next(); |
unsigned height_in_bytes = height * kPointerSize; |
USE(height_in_bytes); |
@@ -342,8 +357,8 @@ void Deoptimizer::DoComputeOsrOutputFrame() { |
if (FLAG_trace_osr) { |
PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ", |
ok ? "finished" : "aborted", |
- reinterpret_cast<intptr_t>(function)); |
- function->PrintName(); |
+ reinterpret_cast<intptr_t>(function_)); |
+ function_->PrintName(); |
PrintF(" => pc=0x%0x]\n", output_[0]->GetPc()); |
} |
} |
@@ -573,7 +588,15 @@ void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, |
int frame_index) { |
// Read the ast node id, function, and frame height for this output frame. |
int node_id = iterator->Next(); |
- JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); |
+ JSFunction* function; |
+ if (frame_index != 0) { |
+ function = JSFunction::cast(ComputeLiteral(iterator->Next())); |
+ } else { |
+ int closure_id = iterator->Next(); |
+ USE(closure_id); |
+ ASSERT_EQ(Translation::kSelfLiteralId, closure_id); |
+ function = function_; |
+ } |
unsigned height = iterator->Next(); |
unsigned height_in_bytes = height * kPointerSize; |
if (FLAG_trace_deopt) { |