diff options
Diffstat (limited to 'deps/v8/src/factory.cc')
-rw-r--r-- | deps/v8/src/factory.cc | 449 |
1 files changed, 274 insertions, 175 deletions
diff --git a/deps/v8/src/factory.cc b/deps/v8/src/factory.cc index 7f2eae35dd..45a08c9232 100644 --- a/deps/v8/src/factory.cc +++ b/deps/v8/src/factory.cc @@ -6,6 +6,7 @@ #include "src/accessors.h" #include "src/allocation-site-scopes.h" +#include "src/ast/ast-source-ranges.h" #include "src/ast/ast.h" #include "src/base/bits.h" #include "src/bootstrapper.h" @@ -13,6 +14,7 @@ #include "src/conversions.h" #include "src/isolate-inl.h" #include "src/macro-assembler.h" +#include "src/objects/debug-objects-inl.h" #include "src/objects/frame-array-inl.h" #include "src/objects/module-info.h" #include "src/objects/scope-info.h" @@ -152,6 +154,14 @@ Handle<FixedArray> Factory::NewFixedArray(int size, PretenureFlag pretenure) { FixedArray); } +Handle<PropertyArray> Factory::NewPropertyArray(int size, + PretenureFlag pretenure) { + DCHECK_LE(0, size); + CALL_HEAP_FUNCTION(isolate(), + isolate()->heap()->AllocatePropertyArray(size, pretenure), + PropertyArray); +} + MaybeHandle<FixedArray> Factory::TryNewFixedArray(int size, PretenureFlag pretenure) { DCHECK(0 <= size); @@ -174,10 +184,12 @@ Handle<FixedArray> Factory::NewFixedArrayWithHoles(int size, } Handle<FixedArray> Factory::NewUninitializedFixedArray(int size) { - CALL_HEAP_FUNCTION( - isolate(), - isolate()->heap()->AllocateUninitializedFixedArray(size), - FixedArray); + // TODO(ulan): As an experiment this temporarily returns an initialized fixed + // array. After getting canary/performance coverage, either remove the + // function or revert to returning uninitilized array. + CALL_HEAP_FUNCTION(isolate(), + isolate()->heap()->AllocateFixedArray(size, NOT_TENURED), + FixedArray); } Handle<BoilerplateDescription> Factory::NewBoilerplateDescription( @@ -239,6 +251,24 @@ Handle<FrameArray> Factory::NewFrameArray(int number_of_frames, return Handle<FrameArray>::cast(result); } +Handle<SmallOrderedHashSet> Factory::NewSmallOrderedHashSet( + int size, PretenureFlag pretenure) { + DCHECK_LE(0, size); + CALL_HEAP_FUNCTION( + isolate(), + isolate()->heap()->AllocateSmallOrderedHashSet(size, pretenure), + SmallOrderedHashSet); +} + +Handle<SmallOrderedHashMap> Factory::NewSmallOrderedHashMap( + int size, PretenureFlag pretenure) { + DCHECK_LE(0, size); + CALL_HEAP_FUNCTION( + isolate(), + isolate()->heap()->AllocateSmallOrderedHashMap(size, pretenure), + SmallOrderedHashMap); +} + Handle<OrderedHashSet> Factory::NewOrderedHashSet() { return OrderedHashSet::Allocate(isolate(), OrderedHashSet::kMinCapacity); } @@ -297,7 +327,6 @@ Handle<String> Factory::InternalizeStringWithKey(StringTableKey* key) { return StringTable::LookupKey(isolate(), key); } - MaybeHandle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string, PretenureFlag pretenure) { int length = string.length(); @@ -605,8 +634,8 @@ static inline Handle<String> MakeOrFindTwoCharacterString(Isolate* isolate, // when building the new string. if (static_cast<unsigned>(c1 | c2) <= String::kMaxOneByteCharCodeU) { // We can do this. - DCHECK(base::bits::IsPowerOfTwo32(String::kMaxOneByteCharCodeU + - 1)); // because of this. + DCHECK(base::bits::IsPowerOfTwo(String::kMaxOneByteCharCodeU + + 1)); // because of this. Handle<SeqOneByteString> str = isolate->factory()->NewRawOneByteString(2).ToHandleChecked(); uint8_t* dest = str->GetChars(); @@ -818,7 +847,6 @@ Handle<String> Factory::NewProperSubString(Handle<String> str, return slice; } - MaybeHandle<String> Factory::NewExternalStringFromOneByte( const ExternalOneByteString::Resource* resource) { size_t length = resource->length(); @@ -916,25 +944,6 @@ Handle<Symbol> Factory::NewPrivateSymbol() { return symbol; } -Handle<JSPromise> Factory::NewJSPromise() { - Handle<JSFunction> constructor( - isolate()->native_context()->promise_function(), isolate()); - DCHECK(constructor->has_initial_map()); - Handle<Map> map(constructor->initial_map(), isolate()); - - DCHECK(!map->is_prototype_map()); - Handle<JSObject> promise_obj = NewJSObjectFromMap(map); - Handle<JSPromise> promise = Handle<JSPromise>::cast(promise_obj); - promise->set_status(v8::Promise::kPending); - promise->set_flags(0); - for (int i = 0; i < v8::Promise::kEmbedderFieldCount; i++) { - promise->SetEmbedderField(i, Smi::kZero); - } - - isolate()->RunPromiseHook(PromiseHookType::kInit, promise, undefined_value()); - return promise; -} - Handle<Context> Factory::NewNativeContext() { Handle<FixedArray> array = NewFixedArray(Context::NATIVE_CONTEXT_SLOTS, TENURED); @@ -1130,8 +1139,6 @@ Handle<Script> Factory::NewScript(Handle<String> source) { script->set_eval_from_position(0); script->set_shared_function_infos(*empty_fixed_array(), SKIP_WRITE_BARRIER); script->set_flags(0); - script->set_preparsed_scope_data( - PodArray<uint32_t>::cast(heap->empty_byte_array())); heap->set_script_list(*WeakFixedArray::Add(script_list(), script)); return script; @@ -1216,11 +1223,9 @@ Handle<Cell> Factory::NewManyClosuresCell(Handle<Object> value) { return cell; } -Handle<PropertyCell> Factory::NewPropertyCell() { - CALL_HEAP_FUNCTION( - isolate(), - isolate()->heap()->AllocatePropertyCell(), - PropertyCell); +Handle<PropertyCell> Factory::NewPropertyCell(Handle<Name> name) { + CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocatePropertyCell(*name), + PropertyCell); } @@ -1279,7 +1284,6 @@ Handle<JSObject> Factory::CopyJSObjectWithAllocationSite( JSObject); } - Handle<FixedArray> Factory::CopyFixedArrayWithMap(Handle<FixedArray> array, Handle<Map> map) { CALL_HEAP_FUNCTION(isolate(), @@ -1287,13 +1291,21 @@ Handle<FixedArray> Factory::CopyFixedArrayWithMap(Handle<FixedArray> array, FixedArray); } - Handle<FixedArray> Factory::CopyFixedArrayAndGrow(Handle<FixedArray> array, int grow_by, PretenureFlag pretenure) { - CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->CopyFixedArrayAndGrow( - *array, grow_by, pretenure), - FixedArray); + CALL_HEAP_FUNCTION( + isolate(), + isolate()->heap()->CopyArrayAndGrow(*array, grow_by, pretenure), + FixedArray); +} + +Handle<PropertyArray> Factory::CopyPropertyArrayAndGrow( + Handle<PropertyArray> array, int grow_by, PretenureFlag pretenure) { + CALL_HEAP_FUNCTION( + isolate(), + isolate()->heap()->CopyArrayAndGrow(*array, grow_by, pretenure), + PropertyArray); } Handle<FixedArray> Factory::CopyFixedArrayUpTo(Handle<FixedArray> array, @@ -1460,66 +1472,92 @@ Handle<JSFunction> Factory::NewFunction(Handle<Map> map, return function; } - -Handle<JSFunction> Factory::NewFunction(Handle<Map> map, - Handle<String> name, - MaybeHandle<Code> code) { +Handle<JSFunction> Factory::NewFunction(Handle<Map> map, Handle<String> name, + MaybeHandle<Code> maybe_code) { + DCHECK(!name.is_null()); Handle<Context> context(isolate()->native_context()); Handle<SharedFunctionInfo> info = - NewSharedFunctionInfo(name, code, map->is_constructor()); + NewSharedFunctionInfo(name, maybe_code, map->is_constructor()); + // Proper language mode in shared function info will be set outside. DCHECK(is_sloppy(info->language_mode())); DCHECK(!map->IsUndefined(isolate())); - DCHECK( - map.is_identical_to(isolate()->sloppy_function_map()) || - map.is_identical_to(isolate()->sloppy_function_without_prototype_map()) || - map.is_identical_to( - isolate()->sloppy_function_with_readonly_prototype_map()) || - map.is_identical_to(isolate()->strict_function_map()) || - map.is_identical_to(isolate()->strict_function_without_prototype_map()) || - // TODO(titzer): wasm_function_map() could be undefined here. ugly. - (*map == context->get(Context::WASM_FUNCTION_MAP_INDEX)) || - (*map == context->get(Context::NATIVE_FUNCTION_MAP_INDEX)) || - map.is_identical_to(isolate()->proxy_function_map())); +#ifdef DEBUG + if (isolate()->bootstrapper()->IsActive()) { + Handle<Code> code; + bool has_code = maybe_code.ToHandle(&code); + DCHECK( + // During bootstrapping some of these maps could be not created yet. + (*map == context->get(Context::STRICT_FUNCTION_MAP_INDEX)) || + (*map == + context->get(Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX)) || + (*map == + context->get( + Context::STRICT_FUNCTION_WITH_READONLY_PROTOTYPE_MAP_INDEX)) || + // Check if it's a creation of an empty or Proxy function during + // bootstrapping. + (has_code && (code->builtin_index() == Builtins::kEmptyFunction || + code->builtin_index() == Builtins::kProxyConstructor))); + } else { + DCHECK( + (*map == *isolate()->sloppy_function_map()) || + (*map == *isolate()->sloppy_function_without_prototype_map()) || + (*map == *isolate()->sloppy_function_with_readonly_prototype_map()) || + (*map == *isolate()->strict_function_map()) || + (*map == *isolate()->strict_function_without_prototype_map()) || + (*map == *isolate()->native_function_map())); + } +#endif return NewFunction(map, info, context); } Handle<JSFunction> Factory::NewFunction(Handle<String> name) { - return NewFunction( - isolate()->sloppy_function_map(), name, MaybeHandle<Code>()); + Handle<JSFunction> result = + NewFunction(isolate()->sloppy_function_map(), name, MaybeHandle<Code>()); + DCHECK(is_sloppy(result->shared()->language_mode())); + return result; } - -Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name, - Handle<Code> code, - bool is_strict) { - Handle<Map> map = is_strict +Handle<JSFunction> Factory::NewFunctionWithoutPrototype( + Handle<String> name, Handle<Code> code, LanguageMode language_mode) { + Handle<Map> map = is_strict(language_mode) ? isolate()->strict_function_without_prototype_map() : isolate()->sloppy_function_without_prototype_map(); - return NewFunction(map, name, code); + Handle<JSFunction> result = NewFunction(map, name, code); + result->shared()->set_language_mode(language_mode); + return result; } - Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code, Handle<Object> prototype, - bool is_strict) { - Handle<Map> map = is_strict ? isolate()->strict_function_map() - : isolate()->sloppy_function_map(); + LanguageMode language_mode, + MutableMode prototype_mutability) { + Handle<Map> map; + if (prototype_mutability == MUTABLE) { + map = is_strict(language_mode) ? isolate()->strict_function_map() + : isolate()->sloppy_function_map(); + } else { + map = is_strict(language_mode) + ? isolate()->strict_function_with_readonly_prototype_map() + : isolate()->sloppy_function_with_readonly_prototype_map(); + } Handle<JSFunction> result = NewFunction(map, name, code); result->set_prototype_or_initial_map(*prototype); + result->shared()->set_language_mode(language_mode); return result; } - Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code, Handle<Object> prototype, InstanceType type, int instance_size, - bool is_strict) { + LanguageMode language_mode, + MutableMode prototype_mutability) { // Allocate the function - Handle<JSFunction> function = NewFunction(name, code, prototype, is_strict); + Handle<JSFunction> function = + NewFunction(name, code, prototype, language_mode, prototype_mutability); ElementsKind elements_kind = - type == JS_ARRAY_TYPE ? FAST_SMI_ELEMENTS : FAST_HOLEY_SMI_ELEMENTS; + type == JS_ARRAY_TYPE ? PACKED_SMI_ELEMENTS : HOLEY_SMI_ELEMENTS; Handle<Map> initial_map = NewMap(type, instance_size, elements_kind); // TODO(littledan): Why do we have this is_generator test when // NewFunctionPrototype already handles finding an appropriately @@ -1529,10 +1567,7 @@ Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code, prototype = NewFunctionPrototype(function); } } - - JSFunction::SetInitialMap(function, initial_map, - Handle<JSReceiver>::cast(prototype)); - + JSFunction::SetInitialMap(function, initial_map, prototype); return function; } @@ -1541,7 +1576,8 @@ Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code, InstanceType type, int instance_size) { - return NewFunction(name, code, the_hole_value(), type, instance_size); + DCHECK(isolate()->bootstrapper()->IsActive()); + return NewFunction(name, code, the_hole_value(), type, instance_size, STRICT); } @@ -1579,10 +1615,8 @@ Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo( Handle<SharedFunctionInfo> info, Handle<Context> context, PretenureFlag pretenure) { - int map_index = - Context::FunctionMapIndex(info->language_mode(), info->kind()); - Handle<Map> initial_map(Map::cast(context->native_context()->get(map_index))); - + Handle<Map> initial_map( + Map::cast(context->native_context()->get(info->function_map_index()))); return NewFunctionFromSharedFunctionInfo(initial_map, info, context, pretenure); } @@ -1590,10 +1624,8 @@ Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo( Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo( Handle<SharedFunctionInfo> info, Handle<Context> context, Handle<Cell> vector, PretenureFlag pretenure) { - int map_index = - Context::FunctionMapIndex(info->language_mode(), info->kind()); - Handle<Map> initial_map(Map::cast(context->native_context()->get(map_index))); - + Handle<Map> initial_map( + Map::cast(context->native_context()->get(info->function_map_index()))); return NewFunctionFromSharedFunctionInfo(initial_map, info, context, vector, pretenure); } @@ -1667,6 +1699,14 @@ Handle<ModuleInfo> Factory::NewModuleInfo() { return Handle<ModuleInfo>::cast(array); } +Handle<PreParsedScopeData> Factory::NewPreParsedScopeData() { + Handle<PreParsedScopeData> result = + Handle<PreParsedScopeData>::cast(NewStruct(PREPARSED_SCOPE_DATA_TYPE)); + result->set_scope_data(PodArray<uint32_t>::cast(*empty_byte_array())); + result->set_child_data(*empty_fixed_array()); + return result; +} + Handle<JSObject> Factory::NewExternal(void* value) { Handle<Foreign> foreign = NewForeign(static_cast<Address>(value)); Handle<JSObject> external = NewJSObjectFromMap(external_map()); @@ -1713,8 +1753,6 @@ Handle<Code> Factory::NewCode(const CodeDesc& desc, // The code object has not been fully initialized yet. We rely on the // fact that no allocation will happen from this point on. DisallowHeapAllocation no_gc; - code->set_gc_metadata(Smi::kZero); - code->set_ic_age(isolate()->heap()->global_ic_age()); code->set_instruction_size(desc.instr_size); code->set_relocation_info(*reloc_info); code->set_flags(flags); @@ -1833,10 +1871,10 @@ Handle<JSGlobalObject> Factory::NewJSGlobalObject( PropertyDetails details = descs->GetDetails(i); // Only accessors are expected. DCHECK_EQ(kAccessor, details.kind()); - PropertyDetails d(kAccessor, details.attributes(), i + 1, + PropertyDetails d(kAccessor, details.attributes(), PropertyCellType::kMutable); Handle<Name> name(descs->GetKey(i)); - Handle<PropertyCell> cell = NewPropertyCell(); + Handle<PropertyCell> cell = NewPropertyCell(name); cell->set_value(descs->GetValue(i)); // |dictionary| already contains enough space for all properties. USE(GlobalDictionary::Add(dictionary, name, cell, d)); @@ -1851,8 +1889,8 @@ Handle<JSGlobalObject> Factory::NewJSGlobalObject( new_map->set_dictionary_map(true); // Set up the global object as a normalized object. - global->set_map(*new_map); - global->set_properties(*dictionary); + global->set_global_dictionary(*dictionary); + global->synchronized_set_map(*new_map); // Make sure result is a global object with properties in dictionary. DCHECK(global->IsJSGlobalObject() && !global->HasFastProperties()); @@ -1876,10 +1914,10 @@ Handle<JSObject> Factory::NewJSObjectFromMap( Handle<JSObject> Factory::NewSlowJSObjectFromMap(Handle<Map> map, int capacity, PretenureFlag pretenure) { DCHECK(map->is_dictionary_map()); - Handle<FixedArray> object_properties = + Handle<NameDictionary> object_properties = NameDictionary::New(isolate(), capacity); Handle<JSObject> js_object = NewJSObjectFromMap(map, pretenure); - js_object->set_properties(*object_properties); + js_object->set_raw_properties_or_hash(*object_properties); return js_object; } @@ -1912,7 +1950,7 @@ Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements, array->set_elements(*elements); array->set_length(Smi::FromInt(length)); - JSObject::ValidateElements(array); + JSObject::ValidateElements(*array); return array; } @@ -1932,7 +1970,7 @@ void Factory::NewJSArrayStorage(Handle<JSArray> array, HandleScope inner_scope(isolate()); Handle<FixedArrayBase> elms; ElementsKind elements_kind = array->GetElementsKind(); - if (IsFastDoubleElementsKind(elements_kind)) { + if (IsDoubleElementsKind(elements_kind)) { if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) { elms = NewFixedDoubleArray(capacity); } else { @@ -1940,7 +1978,7 @@ void Factory::NewJSArrayStorage(Handle<JSArray> array, elms = NewFixedDoubleArrayWithHoles(capacity); } } else { - DCHECK(IsFastSmiOrObjectElementsKind(elements_kind)); + DCHECK(IsSmiOrObjectElementsKind(elements_kind)); if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) { elms = NewUninitializedFixedArray(capacity); } else { @@ -2001,9 +2039,11 @@ Handle<Module> Factory::NewModule(Handle<SharedFunctionInfo> code) { module->set_hash(isolate()->GenerateIdentityHash(Smi::kMaxValue)); module->set_module_namespace(isolate()->heap()->undefined_value()); module->set_requested_modules(*requested_modules); - module->set_status(Module::kUnprepared); - DCHECK(!module->instantiated()); - DCHECK(!module->evaluated()); + module->set_script(Script::cast(code->script())); + module->set_status(Module::kUninstantiated); + module->set_exception(isolate()->heap()->the_hole_value()); + module->set_dfs_index(-1); + module->set_dfs_ancestor_index(-1); return module; } @@ -2063,20 +2103,24 @@ Handle<JSSet> Factory::NewJSSet() { return js_set; } - -Handle<JSMapIterator> Factory::NewJSMapIterator() { - Handle<Map> map(isolate()->native_context()->map_iterator_map()); - CALL_HEAP_FUNCTION(isolate(), - isolate()->heap()->AllocateJSObjectFromMap(*map), - JSMapIterator); +Handle<JSMapIterator> Factory::NewJSMapIterator(Handle<Map> map, + Handle<OrderedHashMap> table, + int index) { + Handle<JSMapIterator> result = + Handle<JSMapIterator>::cast(NewJSObjectFromMap(map)); + result->set_table(*table); + result->set_index(Smi::FromInt(index)); + return result; } - -Handle<JSSetIterator> Factory::NewJSSetIterator() { - Handle<Map> map(isolate()->native_context()->set_iterator_map()); - CALL_HEAP_FUNCTION(isolate(), - isolate()->heap()->AllocateJSObjectFromMap(*map), - JSSetIterator); +Handle<JSSetIterator> Factory::NewJSSetIterator(Handle<Map> map, + Handle<OrderedHashSet> table, + int index) { + Handle<JSSetIterator> result = + Handle<JSSetIterator>::cast(NewJSObjectFromMap(map)); + result->set_table(*table); + result->set_index(Smi::FromInt(index)); + return result; } ExternalArrayType Factory::GetArrayTypeFromElementsKind(ElementsKind kind) { @@ -2087,7 +2131,6 @@ ExternalArrayType Factory::GetArrayTypeFromElementsKind(ElementsKind kind) { TYPED_ARRAYS(TYPED_ARRAY_CASE) default: UNREACHABLE(); - return kExternalInt8Array; } #undef TYPED_ARRAY_CASE } @@ -2100,7 +2143,6 @@ size_t Factory::GetExternalArrayElementSize(ExternalArrayType type) { TYPED_ARRAYS(TYPED_ARRAY_CASE) default: UNREACHABLE(); - return 0; } #undef TYPED_ARRAY_CASE } @@ -2115,7 +2157,6 @@ ElementsKind GetExternalArrayElementsKind(ExternalArrayType type) { TYPED_ARRAYS(TYPED_ARRAY_CASE) } UNREACHABLE(); - return FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND; #undef TYPED_ARRAY_CASE } @@ -2127,7 +2168,6 @@ size_t GetFixedTypedArraysElementSize(ElementsKind kind) { TYPED_ARRAYS(TYPED_ARRAY_CASE) default: UNREACHABLE(); - return 0; } #undef TYPED_ARRAY_CASE } @@ -2145,7 +2185,6 @@ JSFunction* GetTypedArrayFun(ExternalArrayType type, Isolate* isolate) { default: UNREACHABLE(); - return NULL; } } @@ -2162,7 +2201,6 @@ JSFunction* GetTypedArrayFun(ElementsKind elements_kind, Isolate* isolate) { default: UNREACHABLE(); - return NULL; } } @@ -2326,7 +2364,7 @@ MaybeHandle<JSBoundFunction> Factory::NewJSBoundFunction( ? isolate()->bound_function_with_constructor_map() : isolate()->bound_function_without_constructor_map(); if (map->prototype() != *prototype) { - map = Map::TransitionToPrototype(map, prototype, REGULAR_PROTOTYPE); + map = Map::TransitionToPrototype(map, prototype); } DCHECK_EQ(target_function->IsConstructor(), map->is_constructor()); @@ -2415,14 +2453,13 @@ void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object, } Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( - Handle<String> name, FunctionKind kind, Handle<Code> code, + MaybeHandle<String> name, FunctionKind kind, Handle<Code> code, Handle<ScopeInfo> scope_info) { DCHECK(IsValidFunctionKind(kind)); Handle<SharedFunctionInfo> shared = - NewSharedFunctionInfo(name, code, IsConstructable(kind)); + NewSharedFunctionInfo(name, code, IsConstructable(kind), kind); shared->set_scope_info(*scope_info); shared->set_outer_scope_info(*the_hole_value()); - shared->set_kind(kind); if (IsGeneratorFunction(kind)) { shared->set_instance_class_name(isolate()->heap()->Generator_string()); } @@ -2436,7 +2473,7 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForLiteral( Handle<SharedFunctionInfo> result = NewSharedFunctionInfo(literal->name(), literal->kind(), code, scope_info); SharedFunctionInfo::InitFromFunctionLiteral(result, literal); - SharedFunctionInfo::SetScript(result, script); + SharedFunctionInfo::SetScript(result, script, false); return result; } @@ -2446,7 +2483,8 @@ Handle<JSMessageObject> Factory::NewJSMessageObject( Handle<Object> stack_frames) { Handle<Map> map = message_object_map(); Handle<JSMessageObject> message_obj = New<JSMessageObject>(map, NEW_SPACE); - message_obj->set_properties(*empty_fixed_array(), SKIP_WRITE_BARRIER); + message_obj->set_raw_properties_or_hash(*empty_fixed_array(), + SKIP_WRITE_BARRIER); message_obj->initialize_elements(); message_obj->set_elements(*empty_fixed_array(), SKIP_WRITE_BARRIER); message_obj->set_type(message); @@ -2459,18 +2497,24 @@ Handle<JSMessageObject> Factory::NewJSMessageObject( return message_obj; } - Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( - Handle<String> name, MaybeHandle<Code> maybe_code, bool is_constructor) { + MaybeHandle<String> maybe_name, MaybeHandle<Code> maybe_code, + bool is_constructor, FunctionKind kind) { // Function names are assumed to be flat elsewhere. Must flatten before // allocating SharedFunctionInfo to avoid GC seeing the uninitialized SFI. - name = String::Flatten(name, TENURED); + Handle<String> shared_name; + bool has_shared_name = maybe_name.ToHandle(&shared_name); + if (has_shared_name) { + shared_name = String::Flatten(shared_name, TENURED); + } Handle<Map> map = shared_function_info_map(); Handle<SharedFunctionInfo> share = New<SharedFunctionInfo>(map, OLD_SPACE); // Set pointer fields. - share->set_name(*name); + share->set_raw_name(has_shared_name + ? *shared_name + : SharedFunctionInfo::kNoSharedNameSentinel); share->set_function_data(*undefined_value(), SKIP_WRITE_BARRIER); Handle<Code> code; if (!maybe_code.ToHandle(&code)) { @@ -2509,12 +2553,18 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( // All compiler hints default to false or 0. share->set_compiler_hints(0); share->set_opt_count_and_bailout_reason(0); + share->set_kind(kind); + + share->set_preparsed_scope_data(*null_value()); // Link into the list. Handle<Object> new_noscript_list = WeakFixedArray::Add(noscript_shared_function_infos(), share); isolate()->heap()->set_noscript_shared_function_infos(*new_noscript_list); +#ifdef VERIFY_HEAP + share->SharedFunctionInfoVerify(); +#endif return share; } @@ -2586,31 +2636,17 @@ Handle<String> Factory::NumberToString(Handle<Object> number, return js_string; } - Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) { DCHECK(!shared->HasDebugInfo()); - // Allocate initial fixed array for active break points before allocating the - // debug info object to avoid allocation while setting up the debug info - // object. - Handle<FixedArray> break_points( - NewFixedArray(DebugInfo::kEstimatedNofBreakPointsInFunction)); - - // Make a copy of the bytecode array if available. - Handle<Object> maybe_debug_bytecode_array = undefined_value(); - if (shared->HasBytecodeArray()) { - Handle<BytecodeArray> original(shared->bytecode_array()); - maybe_debug_bytecode_array = CopyBytecodeArray(original); - } - - // Create and set up the debug info object. Debug info contains function, a - // copy of the original code, the executing code and initial fixed array for - // active break points. + Heap* heap = isolate()->heap(); + Handle<DebugInfo> debug_info = Handle<DebugInfo>::cast(NewStruct(DEBUG_INFO_TYPE)); + debug_info->set_flags(DebugInfo::kNone); debug_info->set_shared(*shared); debug_info->set_debugger_hints(shared->debugger_hints()); - debug_info->set_debug_bytecode_array(*maybe_debug_bytecode_array); - debug_info->set_break_points(*break_points); + debug_info->set_debug_bytecode_array(heap->undefined_value()); + debug_info->set_break_points(heap->empty_fixed_array()); // Link debug info to function. shared->set_debug_info(*debug_info); @@ -2618,6 +2654,22 @@ Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) { return debug_info; } +Handle<CoverageInfo> Factory::NewCoverageInfo( + const ZoneVector<SourceRange>& slots) { + const int slot_count = static_cast<int>(slots.size()); + + const int length = CoverageInfo::FixedArrayLengthForSlotCount(slot_count); + Handle<CoverageInfo> info = + Handle<CoverageInfo>::cast(NewUninitializedFixedArray(length)); + + for (int i = 0; i < slot_count; i++) { + SourceRange range = slots[i]; + info->InitializeSlot(i, range.start, range.end); + } + + return info; +} + Handle<BreakPointInfo> Factory::NewBreakPointInfo(int source_position) { Handle<BreakPointInfo> new_break_point_info = Handle<BreakPointInfo>::cast(NewStruct(TUPLE2_TYPE)); @@ -2756,8 +2808,6 @@ void Factory::SetRegExpIrregexpData(Handle<JSRegExp> regexp, store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags)); store->set(JSRegExp::kIrregexpLatin1CodeIndex, uninitialized); store->set(JSRegExp::kIrregexpUC16CodeIndex, uninitialized); - store->set(JSRegExp::kIrregexpLatin1CodeSavedIndex, uninitialized); - store->set(JSRegExp::kIrregexpUC16CodeSavedIndex, uninitialized); store->set(JSRegExp::kIrregexpMaxRegisterCountIndex, Smi::kZero); store->set(JSRegExp::kIrregexpCaptureCountIndex, Smi::FromInt(capture_count)); @@ -2785,8 +2835,8 @@ Handle<RegExpMatchInfo> Factory::NewRegExpMatchInfo() { Handle<Object> Factory::GlobalConstantFor(Handle<Name> name) { if (Name::Equals(name, undefined_string())) return undefined_value(); - if (Name::Equals(name, nan_string())) return nan_value(); - if (Name::Equals(name, infinity_string())) return infinity_value(); + if (Name::Equals(name, NaN_string())) return nan_value(); + if (Name::Equals(name, Infinity_string())) return infinity_value(); return Handle<Object>::null(); } @@ -2805,68 +2855,91 @@ Handle<String> Factory::ToPrimitiveHintString(ToPrimitiveHint hint) { return string_string(); } UNREACHABLE(); - return Handle<String>::null(); } -Handle<Map> Factory::CreateSloppyFunctionMap(FunctionMode function_mode) { +Handle<Map> Factory::CreateSloppyFunctionMap( + FunctionMode function_mode, MaybeHandle<JSFunction> maybe_empty_function) { Handle<Map> map = NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); - SetFunctionInstanceDescriptor(map, function_mode); + SetSloppyFunctionInstanceDescriptor(map, function_mode); map->set_is_constructor(IsFunctionModeWithPrototype(function_mode)); map->set_is_callable(); + Handle<JSFunction> empty_function; + if (maybe_empty_function.ToHandle(&empty_function)) { + Map::SetPrototype(map, empty_function); + } return map; } -void Factory::SetFunctionInstanceDescriptor(Handle<Map> map, - FunctionMode function_mode) { +void Factory::SetSloppyFunctionInstanceDescriptor(Handle<Map> map, + FunctionMode function_mode) { int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4; + int inobject_properties_count = 0; + if (IsFunctionModeWithName(function_mode)) ++inobject_properties_count; + map->SetInObjectProperties(inobject_properties_count); + map->set_instance_size(JSFunction::kSize + + inobject_properties_count * kPointerSize); + Map::EnsureDescriptorSlack(map, size); PropertyAttributes ro_attribs = static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); + PropertyAttributes rw_attribs = + static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); PropertyAttributes roc_attribs = static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY); + int field_index = 0; STATIC_ASSERT(JSFunction::kLengthDescriptorIndex == 0); Handle<AccessorInfo> length = Accessors::FunctionLengthInfo(isolate(), roc_attribs); - { // Add length. + { // Add length accessor. Descriptor d = Descriptor::AccessorConstant( Handle<Name>(Name::cast(length->name())), length, roc_attribs); map->AppendDescriptor(&d); } STATIC_ASSERT(JSFunction::kNameDescriptorIndex == 1); - Handle<AccessorInfo> name = - Accessors::FunctionNameInfo(isolate(), roc_attribs); - { // Add name. + if (IsFunctionModeWithName(function_mode)) { + // Add name field. + Handle<Name> name = isolate()->factory()->name_string(); + Descriptor d = Descriptor::DataField(name, field_index++, roc_attribs, + Representation::Tagged()); + map->AppendDescriptor(&d); + + } else { + // Add name accessor. + Handle<AccessorInfo> name = + Accessors::FunctionNameInfo(isolate(), roc_attribs); Descriptor d = Descriptor::AccessorConstant( Handle<Name>(Name::cast(name->name())), name, roc_attribs); map->AppendDescriptor(&d); } Handle<AccessorInfo> args = Accessors::FunctionArgumentsInfo(isolate(), ro_attribs); - { // Add arguments. + { // Add arguments accessor. Descriptor d = Descriptor::AccessorConstant( Handle<Name>(Name::cast(args->name())), args, ro_attribs); map->AppendDescriptor(&d); } Handle<AccessorInfo> caller = Accessors::FunctionCallerInfo(isolate(), ro_attribs); - { // Add caller. + { // Add caller accessor. Descriptor d = Descriptor::AccessorConstant( Handle<Name>(Name::cast(caller->name())), caller, ro_attribs); map->AppendDescriptor(&d); } if (IsFunctionModeWithPrototype(function_mode)) { - if (function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE) { - ro_attribs = static_cast<PropertyAttributes>(ro_attribs & ~READ_ONLY); - } + // Add prototype accessor. + PropertyAttributes attribs = + IsFunctionModeWithWritablePrototype(function_mode) ? rw_attribs + : ro_attribs; Handle<AccessorInfo> prototype = - Accessors::FunctionPrototypeInfo(isolate(), ro_attribs); + Accessors::FunctionPrototypeInfo(isolate(), attribs); Descriptor d = Descriptor::AccessorConstant( - Handle<Name>(Name::cast(prototype->name())), prototype, ro_attribs); + Handle<Name>(Name::cast(prototype->name())), prototype, attribs); map->AppendDescriptor(&d); } + DCHECK_EQ(inobject_properties_count, field_index); } Handle<Map> Factory::CreateStrictFunctionMap( @@ -2881,7 +2954,17 @@ Handle<Map> Factory::CreateStrictFunctionMap( void Factory::SetStrictFunctionInstanceDescriptor(Handle<Map> map, FunctionMode function_mode) { - int size = IsFunctionModeWithPrototype(function_mode) ? 3 : 2; + DCHECK_EQ(JS_FUNCTION_TYPE, map->instance_type()); + int inobject_properties_count = 0; + if (IsFunctionModeWithName(function_mode)) ++inobject_properties_count; + if (IsFunctionModeWithHomeObject(function_mode)) ++inobject_properties_count; + map->SetInObjectProperties(inobject_properties_count); + map->set_instance_size(JSFunction::kSize + + inobject_properties_count * kPointerSize); + + int size = (IsFunctionModeWithPrototype(function_mode) ? 3 : 2) + + inobject_properties_count; + Map::EnsureDescriptorSlack(map, size); PropertyAttributes rw_attribs = @@ -2891,11 +2974,9 @@ void Factory::SetStrictFunctionInstanceDescriptor(Handle<Map> map, PropertyAttributes roc_attribs = static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY); - DCHECK(function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE || - function_mode == FUNCTION_WITH_READONLY_PROTOTYPE || - function_mode == FUNCTION_WITHOUT_PROTOTYPE); + int field_index = 0; STATIC_ASSERT(JSFunction::kLengthDescriptorIndex == 0); - { // Add length. + { // Add length accessor. Handle<AccessorInfo> length = Accessors::FunctionLengthInfo(isolate(), roc_attribs); Descriptor d = Descriptor::AccessorConstant( @@ -2904,17 +2985,26 @@ void Factory::SetStrictFunctionInstanceDescriptor(Handle<Map> map, } STATIC_ASSERT(JSFunction::kNameDescriptorIndex == 1); - { // Add name. + if (IsFunctionModeWithName(function_mode)) { + // Add name field. + Handle<Name> name = isolate()->factory()->name_string(); + Descriptor d = Descriptor::DataField(name, field_index++, roc_attribs, + Representation::Tagged()); + map->AppendDescriptor(&d); + + } else { + // Add name accessor. Handle<AccessorInfo> name = Accessors::FunctionNameInfo(isolate(), roc_attribs); Descriptor d = Descriptor::AccessorConstant( handle(Name::cast(name->name())), name, roc_attribs); map->AppendDescriptor(&d); } + if (IsFunctionModeWithPrototype(function_mode)) { - // Add prototype. + // Add prototype accessor. PropertyAttributes attribs = - function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ? rw_attribs + IsFunctionModeWithWritablePrototype(function_mode) ? rw_attribs : ro_attribs; Handle<AccessorInfo> prototype = Accessors::FunctionPrototypeInfo(isolate(), attribs); @@ -2922,6 +3012,15 @@ void Factory::SetStrictFunctionInstanceDescriptor(Handle<Map> map, Handle<Name>(Name::cast(prototype->name())), prototype, attribs); map->AppendDescriptor(&d); } + + if (IsFunctionModeWithHomeObject(function_mode)) { + // Add home object field. + Handle<Name> name = isolate()->factory()->home_object_symbol(); + Descriptor d = Descriptor::DataField(name, field_index++, DONT_ENUM, + Representation::Tagged()); + map->AppendDescriptor(&d); + } + DCHECK_EQ(inobject_properties_count, field_index); } Handle<Map> Factory::CreateClassFunctionMap(Handle<JSFunction> empty_function) { @@ -2942,7 +3041,7 @@ void Factory::SetClassFunctionInstanceDescriptor(Handle<Map> map) { static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY); STATIC_ASSERT(JSFunction::kLengthDescriptorIndex == 0); - { // Add length. + { // Add length accessor. Handle<AccessorInfo> length = Accessors::FunctionLengthInfo(isolate(), roc_attribs); Descriptor d = Descriptor::AccessorConstant( @@ -2951,7 +3050,7 @@ void Factory::SetClassFunctionInstanceDescriptor(Handle<Map> map) { } { - // Add prototype. + // Add prototype accessor. Handle<AccessorInfo> prototype = Accessors::FunctionPrototypeInfo(isolate(), rw_attribs); Descriptor d = Descriptor::AccessorConstant( |