| 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) {
|
|
|