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