Index: src/ia32/deoptimizer-ia32.cc |
diff --git a/src/ia32/deoptimizer-ia32.cc b/src/ia32/deoptimizer-ia32.cc |
index 72fdac8c6ce900dbd26d05325518a6e8b40e74b8..16805817136f53054e33a5ca873ee73ddae39002 100644 |
--- a/src/ia32/deoptimizer-ia32.cc |
+++ b/src/ia32/deoptimizer-ia32.cc |
@@ -134,6 +134,10 @@ void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) { |
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()->set_optimized_code_map(Smi::FromInt(0)); |
+ |
Isolate* isolate = function->GetIsolate(); |
HandleScope scope(isolate); |
AssertNoAllocation no_allocation; |
@@ -205,8 +209,19 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) { |
node->set_next(data->deoptimizing_code_list_); |
data->deoptimizing_code_list_ = node; |
- // 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->shared() == shared) { |
+ func->ReplaceCode(shared->code()); |
+ } |
+ } |
if (FLAG_trace_deopt) { |
PrintF("[forced deoptimization: "); |
@@ -316,9 +331,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); |
@@ -421,15 +436,15 @@ void Deoptimizer::DoComputeOsrOutputFrame() { |
output_[0]->SetPc(pc); |
} |
Code* continuation = |
- function->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR); |
+ function_->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR); |
output_[0]->SetContinuation( |
reinterpret_cast<uint32_t>(continuation->entry())); |
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()); |
} |
} |
@@ -443,7 +458,15 @@ void Deoptimizer::DoComputeFrame(TranslationIterator* iterator, |
USE(opcode); |
ASSERT(Translation::FRAME == opcode); |
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) { |