| Index: src/ia32/deoptimizer-ia32.cc
|
| ===================================================================
|
| --- src/ia32/deoptimizer-ia32.cc (revision 11812)
|
| +++ src/ia32/deoptimizer-ia32.cc (working copy)
|
| @@ -117,6 +117,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();
|
| +
|
| Isolate* isolate = function->GetIsolate();
|
| HandleScope scope(isolate);
|
| AssertNoAllocation no_allocation;
|
| @@ -194,8 +198,19 @@
|
| // 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: ");
|
| @@ -330,9 +345,9 @@
|
| 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);
|
| @@ -456,15 +471,15 @@
|
| 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());
|
| }
|
| }
|
| @@ -682,7 +697,15 @@
|
| void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
|
| int frame_index) {
|
| 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) {
|
|
|