From 107a359080a1eb3c216acc0912acccad8118ea8a Mon Sep 17 00:00:00 2001 From: "verwaest@chromium.org" Date: Thu, 17 Apr 2014 11:50:22 +0000 Subject: [PATCH] Select function map based on prototype and shared function info. BUG= R=ishell@chromium.org Review URL: https://codereview.chromium.org/237963024 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20840 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/factory.cc | 126 ++++++++++++++++++++++++------------------------- src/factory.h | 20 ++++---- 2 files changed, 72 insertions(+), 74 deletions(-) diff --git a/src/factory.cc b/src/factory.cc index 879b9b74ef..5e11b8d97d 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -975,35 +975,21 @@ Handle Factory::CopyConstantPoolArray( } -static Handle MapForNewFunction(Isolate *isolate, - Handle function_info) { - Context *context = isolate->context()->native_context(); - int map_index = Context::FunctionMapIndex(function_info->strict_mode(), - function_info->is_generator()); - return Handle(Map::cast(context->get(map_index))); -} - - Handle Factory::NewFunctionFromSharedFunctionInfo( - Handle function_info, + Handle info, Handle context, PretenureFlag pretenure) { - Handle result = NewFunctionHelper( - MapForNewFunction(isolate(), function_info), - function_info, - the_hole_value(), - pretenure); + Handle result = NewFunction( + info, context, the_hole_value(), pretenure); - if (function_info->ic_age() != isolate()->heap()->global_ic_age()) { - function_info->ResetForNewContext(isolate()->heap()->global_ic_age()); + if (info->ic_age() != isolate()->heap()->global_ic_age()) { + info->ResetForNewContext(isolate()->heap()->global_ic_age()); } - result->set_context(*context); - - int index = function_info->SearchOptimizedCodeMap(context->native_context(), - BailoutId::None()); - if (!function_info->bound() && index < 0) { - int number_of_literals = function_info->num_literals(); + int index = info->SearchOptimizedCodeMap(context->native_context(), + BailoutId::None()); + if (!info->bound() && index < 0) { + int number_of_literals = info->num_literals(); Handle literals = NewFixedArray(number_of_literals, pretenure); if (number_of_literals > 0) { // Store the native context in the literals array prefix. This @@ -1017,10 +1003,9 @@ Handle Factory::NewFunctionFromSharedFunctionInfo( if (index > 0) { // Caching of optimized code enabled and optimized code found. - FixedArray* literals = - function_info->GetLiteralsFromOptimizedCodeMap(index); + FixedArray* literals = info->GetLiteralsFromOptimizedCodeMap(index); if (literals != NULL) result->set_literals(literals); - Code* code = function_info->GetCodeFromOptimizedCodeMap(index); + Code* code = info->GetCodeFromOptimizedCodeMap(index); ASSERT(!code->marked_for_deoptimization()); result->ReplaceCode(code); return result; @@ -1029,9 +1014,9 @@ Handle Factory::NewFunctionFromSharedFunctionInfo( if (isolate()->use_crankshaft() && FLAG_always_opt && result->is_compiled() && - !function_info->is_toplevel() && - function_info->allows_lazy_compilation() && - !function_info->optimization_disabled() && + !info->is_toplevel() && + info->allows_lazy_compilation() && + !info->optimization_disabled() && !isolate()->DebuggerHasBreakPoints()) { result->MarkForOptimization(); } @@ -1752,8 +1737,9 @@ void Factory::ReinitializeJSReceiver(Handle object, if (type == JS_FUNCTION_TYPE) { map->set_function_with_prototype(true); Handle js_function = Handle::cast(object); - InitializeFunction(js_function, shared.ToHandleChecked(), the_hole_value()); - js_function->set_context(isolate()->context()->native_context()); + Handle context(isolate()->context()->native_context()); + InitializeFunction(js_function, shared.ToHandleChecked(), + context, null_value()); } // Put in filler if the new object is smaller than the old. @@ -1983,52 +1969,68 @@ Handle Factory::DictionaryAtNumberPut( void Factory::InitializeFunction(Handle function, - Handle shared, - Handle prototype) { - ASSERT(!prototype->IsMap()); + Handle info, + Handle context, + MaybeHandle maybe_prototype) { function->initialize_properties(); function->initialize_elements(); - function->set_shared(*shared); - function->set_code(shared->code()); + function->set_shared(*info); + function->set_code(info->code()); + function->set_context(*context); + Handle prototype; + if (maybe_prototype.ToHandle(&prototype)) { + ASSERT(!prototype->IsMap()); + } else { + prototype = the_hole_value(); + } function->set_prototype_or_initial_map(*prototype); - function->set_context(*undefined_value()); function->set_literals_or_bindings(*empty_fixed_array()); function->set_next_function_link(*undefined_value()); } -Handle Factory::NewFunctionHelper(Handle function_map, - Handle shared, - Handle prototype, - PretenureFlag pretenure) { - AllocationSpace space = - (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE; - Handle fun = New(function_map, space); - InitializeFunction(fun, shared, prototype); - return fun; +static Handle MapForNewFunction(Isolate* isolate, + Handle function_info, + MaybeHandle maybe_prototype) { + if (maybe_prototype.is_null()) { + return function_info->strict_mode() == SLOPPY + ? isolate->sloppy_function_without_prototype_map() + : isolate->strict_function_without_prototype_map(); + } + + Context* context = isolate->context()->native_context(); + int map_index = Context::FunctionMapIndex(function_info->strict_mode(), + function_info->is_generator()); + return Handle(Map::cast(context->get(map_index))); +} + + +Handle Factory::NewFunction(Handle info, + Handle context, + MaybeHandle maybe_prototype, + PretenureFlag pretenure) { + Handle map = MapForNewFunction(isolate(), info, maybe_prototype); + AllocationSpace space = pretenure == TENURED ? OLD_POINTER_SPACE : NEW_SPACE; + Handle result = New(map, space); + InitializeFunction(result, info, context, maybe_prototype); + return result; } Handle Factory::NewFunction(Handle name, Handle prototype) { - Handle function_share = NewSharedFunctionInfo(name); - Handle fun = NewFunctionHelper( - isolate()->sloppy_function_map(), function_share, prototype); - fun->set_context(isolate()->context()->native_context()); - return fun; + Handle info = NewSharedFunctionInfo(name); + Handle context(isolate()->context()->native_context()); + return NewFunction(info, context, prototype); } Handle Factory::NewFunctionWithoutPrototype( Handle name, StrictMode strict_mode) { - Handle function_share = NewSharedFunctionInfo(name); - Handle map = strict_mode == SLOPPY - ? isolate()->sloppy_function_without_prototype_map() - : isolate()->strict_function_without_prototype_map(); - Handle fun = - NewFunctionHelper(map, function_share, the_hole_value()); - fun->set_context(isolate()->context()->native_context()); + Handle info = NewSharedFunctionInfo(name); + Handle context(isolate()->context()->native_context()); + Handle fun = NewFunction(info, context, MaybeHandle()); return fun; } @@ -2111,12 +2113,8 @@ Handle Factory::CreateApiFunction( break; } - Handle result = - NewFunction(Factory::empty_string(), - type, - instance_size, - code, - true); + Handle result = NewFunction( + Factory::empty_string(), type, instance_size, code, true); // Set length. result->shared()->set_length(obj->length()); diff --git a/src/factory.h b/src/factory.h index d52e66e05f..0c850613bb 100644 --- a/src/factory.h +++ b/src/factory.h @@ -633,19 +633,19 @@ class Factory V8_FINAL { Handle allocation_site); // Initializes a function with a shared part and prototype. - // Note: this code was factored out of NewFunctionHelper such that - // other parts of the VM could use it. Specifically, a function that creates - // instances of type JS_FUNCTION_TYPE benefit from the use of this function. + // Note: this code was factored out of NewFunction such that other parts of + // the VM could use it. Specifically, a function that creates instances of + // type JS_FUNCTION_TYPE benefit from the use of this function. inline void InitializeFunction(Handle function, - Handle shared, - Handle prototype); + Handle info, + Handle context, + MaybeHandle maybe_prototype); // Creates a function initialized with a shared part. - inline Handle NewFunctionHelper( - Handle function_map, - Handle shared, - Handle prototype, - PretenureFlag pretenure = TENURED); + inline Handle NewFunction(Handle info, + Handle context, + MaybeHandle maybe_prototype, + PretenureFlag pretenure = TENURED); // Create a new map cache. Handle NewMapCache(int at_least_space_for);