 Chromium Code Reviews
 Chromium Code Reviews Issue 10103035:
  Share optimized code for closures.  (Closed) 
  Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
    
  
    Issue 10103035:
  Share optimized code for closures.  (Closed) 
  Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/| Index: src/ia32/deoptimizer-ia32.cc | 
| =================================================================== | 
| --- src/ia32/deoptimizer-ia32.cc (revision 11527) | 
| +++ 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()->set_optimized_code_map(Smi::FromInt(0)); | 
| 
Michael Starzinger
2012/05/23 11:16:29
I think it would make sense to have shared->ClearO
 
fschneider
2012/06/14 11:08:23
Done.
 | 
| + | 
| 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); | 
| @@ -436,15 +451,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()); | 
| } | 
| } | 
| @@ -662,7 +677,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) { |