Chromium Code Reviews| Index: src/factory.cc |
| diff --git a/src/factory.cc b/src/factory.cc |
| index 864cf6729f7d262885e658f7392d55faa4e33ca0..bf0e7d0382b1d03265108bfb13dc492d9dafb363 100644 |
| --- a/src/factory.cc |
| +++ b/src/factory.cc |
| @@ -906,36 +906,6 @@ Handle<Map> Factory::NewMap(InstanceType type, |
| } |
| -Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) { |
| - // Make sure to use globals from the function's context, since the function |
| - // can be from a different context. |
| - Handle<Context> native_context(function->context()->native_context()); |
| - Handle<Map> 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<JSFunction> object_function(native_context->object_function()); |
| - ASSERT(object_function->has_initial_map()); |
| - new_map = Map::Copy(handle(object_function->initial_map())); |
| - } |
| - |
| - Handle<JSObject> prototype = NewJSObjectFromMap(new_map); |
| - |
| - if (!function->shared()->is_generator()) { |
| - JSObject::SetLocalPropertyIgnoreAttributes(prototype, |
| - constructor_string(), |
| - function, |
| - DONT_ENUM).Assert(); |
| - } |
| - |
| - return prototype; |
| -} |
| - |
| - |
| Handle<JSObject> Factory::CopyJSObject(Handle<JSObject> object) { |
| CALL_HEAP_FUNCTION(isolate(), |
| isolate()->heap()->CopyJSObject(*object, NULL), |
| @@ -994,55 +964,6 @@ Handle<ConstantPoolArray> Factory::CopyConstantPoolArray( |
| } |
| -Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo( |
| - Handle<SharedFunctionInfo> info, |
| - Handle<Context> context, |
| - PretenureFlag pretenure) { |
| - Handle<JSFunction> 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<FixedArray> 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<Object> Factory::NewNumber(double value, |
| PretenureFlag pretenure) { |
| // We need to distinguish the minus zero value and this cannot be |
| @@ -1256,6 +1177,60 @@ Handle<Object> Factory::NewError(const char* constructor, |
| } |
| +void Factory::InitializeFunction(Handle<JSFunction> function, |
| + Handle<SharedFunctionInfo> info, |
| + Handle<Context> 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<JSFunction> Factory::NewFunction(Handle<Map> map, |
| + Handle<SharedFunctionInfo> info, |
| + Handle<Context> context, |
| + PretenureFlag pretenure) { |
| + AllocationSpace space = pretenure == TENURED ? OLD_POINTER_SPACE : NEW_SPACE; |
| + Handle<JSFunction> result = New<JSFunction>(map, space); |
| + InitializeFunction(result, info, context); |
| + return result; |
| +} |
| + |
| + |
| +Handle<JSFunction> Factory::NewFunction(Handle<String> name, |
| + Handle<Code> code, |
| + MaybeHandle<Object> maybe_prototype) { |
| + Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name); |
| + info->set_code(*code); |
| + Handle<Context> context(isolate()->context()->native_context()); |
|
Igor Sheludko
2014/05/05 16:11:35
Does it make sense to add ASSERT(info->strict_mode
|
| + Handle<Map> map = maybe_prototype.is_null() |
| + ? isolate()->sloppy_function_without_prototype_map() |
| + : isolate()->sloppy_function_map(); |
| + Handle<JSFunction> result = NewFunction(map, info, context); |
| + Handle<Object> prototype; |
| + if (maybe_prototype.ToHandle(&prototype)) { |
| + result->set_prototype_or_initial_map(*prototype); |
| + } |
| + return result; |
| +} |
| + |
| + |
| +Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name, |
| + Handle<Object> prototype) { |
| + Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name); |
| + Handle<Context> context(isolate()->context()->native_context()); |
|
Igor Sheludko
2014/05/05 16:11:35
... and here?
|
| + Handle<Map> map = isolate()->sloppy_function_map(); |
| + Handle<JSFunction> result = NewFunction(map, info, context); |
| + result->set_prototype_or_initial_map(*prototype); |
| + return result; |
| +} |
| + |
| + |
| Handle<JSFunction> Factory::NewFunction(MaybeHandle<Object> maybe_prototype, |
| Handle<String> name, |
| InstanceType type, |
| @@ -1326,6 +1301,94 @@ Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name, |
| } |
| +Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) { |
| + // Make sure to use globals from the function's context, since the function |
| + // can be from a different context. |
| + Handle<Context> native_context(function->context()->native_context()); |
| + Handle<Map> 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<JSFunction> object_function(native_context->object_function()); |
| + ASSERT(object_function->has_initial_map()); |
| + new_map = Map::Copy(handle(object_function->initial_map())); |
| + } |
| + |
| + Handle<JSObject> prototype = NewJSObjectFromMap(new_map); |
| + |
| + if (!function->shared()->is_generator()) { |
| + JSObject::SetLocalPropertyIgnoreAttributes(prototype, |
| + constructor_string(), |
| + function, |
| + DONT_ENUM).Assert(); |
| + } |
| + |
| + return prototype; |
| +} |
| + |
| + |
| +static Handle<Map> MapForNewFunction(Isolate* isolate, |
| + Handle<SharedFunctionInfo> function_info) { |
| + Context* context = isolate->context()->native_context(); |
| + int map_index = Context::FunctionMapIndex(function_info->strict_mode(), |
| + function_info->is_generator()); |
| + return Handle<Map>(Map::cast(context->get(map_index))); |
| +} |
| + |
| + |
| +Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo( |
| + Handle<SharedFunctionInfo> info, |
| + Handle<Context> context, |
| + PretenureFlag pretenure) { |
| + Handle<Map> map = MapForNewFunction(isolate(), info); |
|
Igor Sheludko
2014/05/05 16:11:35
Since this is the only caller of MapForNewFunction
|
| + Handle<JSFunction> 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<FixedArray> 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<JSObject> Factory::NewIteratorResultObject(Handle<Object> value, |
| bool done) { |
| Handle<Map> map(isolate()->native_context()->iterator_result_map()); |
| @@ -1759,8 +1822,7 @@ void Factory::ReinitializeJSReceiver(Handle<JSReceiver> object, |
| map->set_function_with_prototype(true); |
| Handle<JSFunction> js_function = Handle<JSFunction>::cast(object); |
| Handle<Context> 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. |
| @@ -1988,73 +2050,6 @@ Handle<String> Factory::NumberToString(Handle<Object> number, |
| } |
| -void Factory::InitializeFunction(Handle<JSFunction> function, |
| - Handle<SharedFunctionInfo> info, |
| - Handle<Context> context, |
| - MaybeHandle<Object> maybe_prototype) { |
| - function->initialize_properties(); |
| - function->initialize_elements(); |
| - function->set_shared(*info); |
| - function->set_code(info->code()); |
| - function->set_context(*context); |
| - Handle<Object> 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<Map> MapForNewFunction(Isolate* isolate, |
| - Handle<SharedFunctionInfo> function_info, |
| - MaybeHandle<Object> 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>(Map::cast(context->get(map_index))); |
| -} |
| - |
| - |
| -Handle<JSFunction> Factory::NewFunction(Handle<SharedFunctionInfo> info, |
| - Handle<Context> context, |
| - MaybeHandle<Object> maybe_prototype, |
| - PretenureFlag pretenure) { |
| - Handle<Map> map = MapForNewFunction(isolate(), info, maybe_prototype); |
| - AllocationSpace space = pretenure == TENURED ? OLD_POINTER_SPACE : NEW_SPACE; |
| - Handle<JSFunction> result = New<JSFunction>(map, space); |
| - InitializeFunction(result, info, context, maybe_prototype); |
| - return result; |
| -} |
| - |
| - |
| -Handle<JSFunction> Factory::NewFunction(Handle<String> name, |
| - Handle<Code> code, |
| - MaybeHandle<Object> maybe_prototype) { |
| - Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name); |
| - info->set_code(*code); |
| - Handle<Context> context(isolate()->context()->native_context()); |
| - return NewFunction(info, context, maybe_prototype); |
| -} |
| - |
| - |
| -Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name, |
| - Handle<Object> prototype) { |
| - Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name); |
| - Handle<Context> context(isolate()->context()->native_context()); |
| - return NewFunction(info, context, prototype); |
| -} |
| - |
| - |
| Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) { |
| // Get the original code of the function. |
| Handle<Code> code(shared->code()); |