From af2be5b4befed644ce1136a7e3dbabbcba9d3e06 Mon Sep 17 00:00:00 2001 From: "verwaest@chromium.org" Date: Tue, 6 May 2014 11:26:35 +0000 Subject: [PATCH] Pass in the map while creating JSFunction, and set prototype in the client. BUG= R=ishell@chromium.org Review URL: https://codereview.chromium.org/263083008 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21166 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/factory.cc | 286 ++++++++++++++++++++++++++++----------------------------- src/factory.h | 7 +- 2 files changed, 141 insertions(+), 152 deletions(-) diff --git a/src/factory.cc b/src/factory.cc index 38243e7..0119896 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -906,36 +906,6 @@ Handle Factory::NewMap(InstanceType type, } -Handle Factory::NewFunctionPrototype(Handle function) { - // Make sure to use globals from the function's context, since the function - // can be from a different context. - Handle native_context(function->context()->native_context()); - Handle new_map; - if (function->shared()->is_generator()) { - // Generator prototypes can share maps since they don't have "constructor" - // properties. - new_map = handle(native_context->generator_object_prototype_map()); - } else { - // Each function prototype gets a fresh map to avoid unwanted sharing of - // maps between prototypes of different constructors. - Handle object_function(native_context->object_function()); - ASSERT(object_function->has_initial_map()); - new_map = Map::Copy(handle(object_function->initial_map())); - } - - Handle prototype = NewJSObjectFromMap(new_map); - - if (!function->shared()->is_generator()) { - JSObject::SetLocalPropertyIgnoreAttributes(prototype, - constructor_string(), - function, - DONT_ENUM).Assert(); - } - - return prototype; -} - - Handle Factory::CopyJSObject(Handle object) { CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->CopyJSObject(*object, NULL), @@ -994,55 +964,6 @@ Handle Factory::CopyConstantPoolArray( } -Handle Factory::NewFunctionFromSharedFunctionInfo( - Handle info, - Handle context, - PretenureFlag pretenure) { - Handle result = NewFunction( - info, context, the_hole_value(), pretenure); - - if (info->ic_age() != isolate()->heap()->global_ic_age()) { - info->ResetForNewContext(isolate()->heap()->global_ic_age()); - } - - 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 - // context will be used when creating object, regexp and array - // literals in this function. - literals->set(JSFunction::kLiteralNativeContextIndex, - context->native_context()); - } - result->set_literals(*literals); - } - - if (index > 0) { - // Caching of optimized code enabled and optimized code found. - FixedArray* literals = info->GetLiteralsFromOptimizedCodeMap(index); - if (literals != NULL) result->set_literals(literals); - Code* code = info->GetCodeFromOptimizedCodeMap(index); - ASSERT(!code->marked_for_deoptimization()); - result->ReplaceCode(code); - return result; - } - - if (isolate()->use_crankshaft() && - FLAG_always_opt && - result->is_compiled() && - !info->is_toplevel() && - info->allows_lazy_compilation() && - !info->optimization_disabled() && - !isolate()->DebuggerHasBreakPoints()) { - result->MarkForOptimization(); - } - return result; -} - - Handle Factory::NewNumber(double value, PretenureFlag pretenure) { // We need to distinguish the minus zero value and this cannot be @@ -1256,6 +1177,62 @@ Handle Factory::NewError(const char* constructor, } +void Factory::InitializeFunction(Handle function, + Handle info, + Handle context) { + function->initialize_properties(); + function->initialize_elements(); + function->set_shared(*info); + function->set_code(info->code()); + function->set_context(*context); + function->set_prototype_or_initial_map(*the_hole_value()); + function->set_literals_or_bindings(*empty_fixed_array()); + function->set_next_function_link(*undefined_value()); +} + + +Handle Factory::NewFunction(Handle map, + Handle info, + Handle context, + PretenureFlag pretenure) { + AllocationSpace space = pretenure == TENURED ? OLD_POINTER_SPACE : NEW_SPACE; + Handle result = New(map, space); + InitializeFunction(result, info, context); + return result; +} + + +Handle Factory::NewFunction(Handle name, + Handle code, + MaybeHandle maybe_prototype) { + Handle info = NewSharedFunctionInfo(name); + ASSERT(info->strict_mode() == SLOPPY); + info->set_code(*code); + Handle context(isolate()->context()->native_context()); + Handle map = maybe_prototype.is_null() + ? isolate()->sloppy_function_without_prototype_map() + : isolate()->sloppy_function_map(); + Handle result = NewFunction(map, info, context); + Handle prototype; + if (maybe_prototype.ToHandle(&prototype)) { + result->set_prototype_or_initial_map(*prototype); + } + return result; +} + + +Handle Factory::NewFunctionWithPrototype(Handle name, + Handle prototype) { + Handle info = NewSharedFunctionInfo(name); + ASSERT(info->strict_mode() == SLOPPY); + Handle context(isolate()->context()->native_context()); + Handle map = isolate()->sloppy_function_map(); + Handle result = NewFunction(map, info, context); + result->set_prototype_or_initial_map(*prototype); + return result; +} + + Handle Factory::NewFunction(MaybeHandle maybe_prototype, Handle name, InstanceType type, @@ -1326,6 +1303,87 @@ Handle Factory::NewFunctionWithPrototype(Handle name, } +Handle Factory::NewFunctionPrototype(Handle function) { + // Make sure to use globals from the function's context, since the function + // can be from a different context. + Handle native_context(function->context()->native_context()); + Handle new_map; + if (function->shared()->is_generator()) { + // Generator prototypes can share maps since they don't have "constructor" + // properties. + new_map = handle(native_context->generator_object_prototype_map()); + } else { + // Each function prototype gets a fresh map to avoid unwanted sharing of + // maps between prototypes of different constructors. + Handle object_function(native_context->object_function()); + ASSERT(object_function->has_initial_map()); + new_map = Map::Copy(handle(object_function->initial_map())); + } + + Handle prototype = NewJSObjectFromMap(new_map); + + if (!function->shared()->is_generator()) { + JSObject::SetLocalPropertyIgnoreAttributes(prototype, + constructor_string(), + function, + DONT_ENUM).Assert(); + } + + return prototype; +} + + +Handle Factory::NewFunctionFromSharedFunctionInfo( + Handle info, + Handle context, + PretenureFlag pretenure) { + int map_index = Context::FunctionMapIndex(info->strict_mode(), + info->is_generator()); + Handle map(Map::cast(context->native_context()->get(map_index))); + Handle result = NewFunction(map, info, context, pretenure); + + if (info->ic_age() != isolate()->heap()->global_ic_age()) { + info->ResetForNewContext(isolate()->heap()->global_ic_age()); + } + + 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 + // context will be used when creating object, regexp and array + // literals in this function. + literals->set(JSFunction::kLiteralNativeContextIndex, + context->native_context()); + } + result->set_literals(*literals); + } + + if (index > 0) { + // Caching of optimized code enabled and optimized code found. + FixedArray* literals = info->GetLiteralsFromOptimizedCodeMap(index); + if (literals != NULL) result->set_literals(literals); + Code* code = info->GetCodeFromOptimizedCodeMap(index); + ASSERT(!code->marked_for_deoptimization()); + result->ReplaceCode(code); + return result; + } + + if (isolate()->use_crankshaft() && + FLAG_always_opt && + result->is_compiled() && + !info->is_toplevel() && + info->allows_lazy_compilation() && + !info->optimization_disabled() && + !isolate()->DebuggerHasBreakPoints()) { + result->MarkForOptimization(); + } + return result; +} + + Handle Factory::NewIteratorResultObject(Handle value, bool done) { Handle map(isolate()->native_context()->iterator_result_map()); @@ -1759,8 +1817,7 @@ void Factory::ReinitializeJSReceiver(Handle object, map->set_function_with_prototype(true); Handle js_function = Handle::cast(object); Handle context(isolate()->context()->native_context()); - InitializeFunction(js_function, shared.ToHandleChecked(), - context, null_value()); + InitializeFunction(js_function, shared.ToHandleChecked(), context); } // Put in filler if the new object is smaller than the old. @@ -1994,73 +2051,6 @@ Handle Factory::NumberToString(Handle number, } -void Factory::InitializeFunction(Handle function, - Handle info, - Handle context, - MaybeHandle maybe_prototype) { - function->initialize_properties(); - function->initialize_elements(); - 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_literals_or_bindings(*empty_fixed_array()); - function->set_next_function_link(*undefined_value()); -} - - -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 code, - MaybeHandle maybe_prototype) { - Handle info = NewSharedFunctionInfo(name); - info->set_code(*code); - Handle context(isolate()->context()->native_context()); - return NewFunction(info, context, maybe_prototype); -} - - -Handle Factory::NewFunctionWithPrototype(Handle name, - Handle prototype) { - Handle info = NewSharedFunctionInfo(name); - Handle context(isolate()->context()->native_context()); - return NewFunction(info, context, prototype); -} - - Handle Factory::NewDebugInfo(Handle shared) { // Get the original code of the function. Handle code(shared->code()); diff --git a/src/factory.h b/src/factory.h index a525fd1..91a036c 100644 --- a/src/factory.h +++ b/src/factory.h @@ -676,13 +676,12 @@ class Factory V8_FINAL { // type JS_FUNCTION_TYPE benefit from the use of this function. inline void InitializeFunction(Handle function, Handle info, - Handle context, - MaybeHandle maybe_prototype); + Handle context); // Creates a function initialized with a shared part. - inline Handle NewFunction(Handle info, + inline Handle NewFunction(Handle map, + Handle info, Handle context, - MaybeHandle maybe_prototype, PretenureFlag pretenure = TENURED); // Create a new map cache. -- 2.7.4