Speed up function deoptimization by avoiding quadratic pass over optimized function list.
R=danno@chromium.org BUG=155270 Review URL: https://chromiumcodereview.appspot.com/11189091 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12780 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
d33cda9338
commit
18ff15ca8c
@ -104,19 +104,7 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
|
||||
// ignore all slots that might have been recorded on it.
|
||||
isolate->heap()->mark_compact_collector()->InvalidateCode(code);
|
||||
|
||||
// Iterate over all the functions which share the same code object
|
||||
// and make them use unoptimized version.
|
||||
Context* context = function->context()->native_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());
|
||||
}
|
||||
}
|
||||
ReplaceCodeForRelatedFunctions(function, code);
|
||||
|
||||
if (FLAG_trace_deopt) {
|
||||
PrintF("[forced deoptimization: ");
|
||||
|
@ -1443,6 +1443,54 @@ void Deoptimizer::RemoveDeoptimizingCode(Code* code) {
|
||||
}
|
||||
|
||||
|
||||
static Object* CutOutRelatedFunctionsList(Context* context,
|
||||
Code* code,
|
||||
Object* undefined) {
|
||||
Object* result_list_head = undefined;
|
||||
Object* head;
|
||||
Object* current;
|
||||
current = head = context->get(Context::OPTIMIZED_FUNCTIONS_LIST);
|
||||
JSFunction* prev = NULL;
|
||||
while (current != undefined) {
|
||||
JSFunction* func = JSFunction::cast(current);
|
||||
current = func->next_function_link();
|
||||
if (func->code() == code) {
|
||||
func->set_next_function_link(result_list_head);
|
||||
result_list_head = func;
|
||||
if (prev) {
|
||||
prev->set_next_function_link(current);
|
||||
} else {
|
||||
head = current;
|
||||
}
|
||||
} else {
|
||||
prev = func;
|
||||
}
|
||||
}
|
||||
if (head != context->get(Context::OPTIMIZED_FUNCTIONS_LIST)) {
|
||||
context->set(Context::OPTIMIZED_FUNCTIONS_LIST, head);
|
||||
}
|
||||
return result_list_head;
|
||||
}
|
||||
|
||||
|
||||
void Deoptimizer::ReplaceCodeForRelatedFunctions(JSFunction* function,
|
||||
Code* code) {
|
||||
Context* context = function->context()->native_context();
|
||||
|
||||
SharedFunctionInfo* shared = function->shared();
|
||||
|
||||
Object* undefined = Isolate::Current()->heap()->undefined_value();
|
||||
Object* current = CutOutRelatedFunctionsList(context, code, undefined);
|
||||
|
||||
while (current != undefined) {
|
||||
JSFunction* func = JSFunction::cast(current);
|
||||
current = func->next_function_link();
|
||||
func->set_code(shared->code());
|
||||
func->set_next_function_link(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FrameDescription::FrameDescription(uint32_t frame_size,
|
||||
JSFunction* function)
|
||||
: frame_size_(frame_size),
|
||||
|
@ -166,6 +166,10 @@ class Deoptimizer : public Malloced {
|
||||
// execution returns.
|
||||
static void DeoptimizeFunction(JSFunction* function);
|
||||
|
||||
// Iterate over all the functions which share the same code object
|
||||
// and make them use unoptimized version.
|
||||
static void ReplaceCodeForRelatedFunctions(JSFunction* function, Code* code);
|
||||
|
||||
// Deoptimize all functions in the heap.
|
||||
static void DeoptimizeAll();
|
||||
|
||||
|
@ -198,19 +198,7 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
|
||||
// ignore all slots that might have been recorded on it.
|
||||
isolate->heap()->mark_compact_collector()->InvalidateCode(code);
|
||||
|
||||
// Iterate over all the functions which share the same code object
|
||||
// and make them use unoptimized version.
|
||||
Context* context = function->context()->native_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());
|
||||
}
|
||||
}
|
||||
ReplaceCodeForRelatedFunctions(function, code);
|
||||
|
||||
if (FLAG_trace_deopt) {
|
||||
PrintF("[forced deoptimization: ");
|
||||
|
@ -100,19 +100,7 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
|
||||
// ignore all slots that might have been recorded on it.
|
||||
isolate->heap()->mark_compact_collector()->InvalidateCode(code);
|
||||
|
||||
// Iterate over all the functions which share the same code object
|
||||
// and make them use unoptimized version.
|
||||
Context* context = function->context()->native_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());
|
||||
}
|
||||
}
|
||||
ReplaceCodeForRelatedFunctions(function, code);
|
||||
|
||||
if (FLAG_trace_deopt) {
|
||||
PrintF("[forced deoptimization: ");
|
||||
|
@ -104,19 +104,7 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
|
||||
// ignore all slots that might have been recorded on it.
|
||||
isolate->heap()->mark_compact_collector()->InvalidateCode(code);
|
||||
|
||||
// Iterate over all the functions which share the same code object
|
||||
// and make them use unoptimized version.
|
||||
Context* context = function->context()->native_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());
|
||||
}
|
||||
}
|
||||
ReplaceCodeForRelatedFunctions(function, code);
|
||||
|
||||
if (FLAG_trace_deopt) {
|
||||
PrintF("[forced deoptimization: ");
|
||||
|
Loading…
Reference in New Issue
Block a user