diff options
Diffstat (limited to 'deps/v8/src/builtins/builtins-object-gen.cc')
-rw-r--r-- | deps/v8/src/builtins/builtins-object-gen.cc | 204 |
1 files changed, 36 insertions, 168 deletions
diff --git a/deps/v8/src/builtins/builtins-object-gen.cc b/deps/v8/src/builtins/builtins-object-gen.cc index a8d83e641f..fbac2e1abc 100644 --- a/deps/v8/src/builtins/builtins-object-gen.cc +++ b/deps/v8/src/builtins/builtins-object-gen.cc @@ -46,11 +46,6 @@ class ObjectBuiltinsAssembler : public CodeStubAssembler { TNode<Word32T> IsStringWrapperElementsKind(TNode<Map> map); - // Checks that |map| has only simple properties, returns bitfield3. - TNode<Uint32T> EnsureOnlyHasSimpleProperties(TNode<Map> map, - TNode<Int32T> instance_type, - Label* bailout); - void ObjectAssignFast(TNode<Context> context, TNode<JSReceiver> to, TNode<Object> from, Label* slow); }; @@ -96,8 +91,7 @@ void ObjectBuiltinsAssembler::ReturnToStringFormat(Node* context, Node* lhs = StringConstant("[object "); Node* rhs = StringConstant("]"); - Callable callable = - CodeFactory::StringAdd(isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED); + Callable callable = CodeFactory::StringAdd(isolate(), STRING_ADD_CHECK_NONE); Return(CallStub(callable, context, CallStub(callable, context, lhs, string), rhs)); @@ -304,7 +298,7 @@ TNode<JSArray> ObjectEntriesValuesBuiltinsAssembler::FastGetOwnValuesOrEntries( // So the array filled by the-hole even if enum_cache exists. FillFixedArrayWithValue(PACKED_ELEMENTS, values_or_entries, IntPtrConstant(0), object_enum_length, - Heap::kTheHoleValueRootIndex); + RootIndex::kTheHoleValue); TVARIABLE(IntPtrT, var_result_index, IntPtrConstant(0)); TVARIABLE(IntPtrT, var_descriptor_number, IntPtrConstant(0)); @@ -524,18 +518,6 @@ TF_BUILTIN(ObjectAssign, ObjectBuiltinsAssembler) { args.PopAndReturn(to); } -TNode<Uint32T> ObjectBuiltinsAssembler::EnsureOnlyHasSimpleProperties( - TNode<Map> map, TNode<Int32T> instance_type, Label* bailout) { - GotoIf(IsCustomElementsReceiverInstanceType(instance_type), bailout); - - TNode<Uint32T> bit_field3 = LoadMapBitField3(map); - GotoIf(IsSetWord32(bit_field3, Map::IsDictionaryMapBit::kMask | - Map::HasHiddenPrototypeBit::kMask), - bailout); - - return bit_field3; -} - // This function mimics what FastAssign() function does for C++ implementation. void ObjectBuiltinsAssembler::ObjectAssignFast(TNode<Context> context, TNode<JSReceiver> to, @@ -553,8 +535,9 @@ void ObjectBuiltinsAssembler::ObjectAssignFast(TNode<Context> context, GotoIf(IsJSReceiverInstanceType(from_instance_type), &cont); GotoIfNot(IsStringInstanceType(from_instance_type), &done); { - Branch(SmiEqual(LoadStringLengthAsSmi(CAST(from)), SmiConstant(0)), &done, - slow); + Branch( + Word32Equal(LoadStringLengthAsWord32(CAST(from)), Int32Constant(0)), + &done, slow); } BIND(&cont); } @@ -567,132 +550,18 @@ void ObjectBuiltinsAssembler::ObjectAssignFast(TNode<Context> context, TNode<BoolT> to_is_simple_receiver = IsSimpleObjectMap(to_map); GotoIfNot(IsJSObjectInstanceType(from_instance_type), slow); - TNode<Uint32T> from_bit_field3 = - EnsureOnlyHasSimpleProperties(from_map, from_instance_type, slow); - GotoIfNot(IsEmptyFixedArray(LoadElements(CAST(from))), slow); - TNode<DescriptorArray> from_descriptors = LoadMapDescriptors(from_map); - TNode<Uint32T> nof_descriptors = - DecodeWord32<Map::NumberOfOwnDescriptorsBits>(from_bit_field3); - - TVARIABLE(BoolT, var_stable, Int32TrueConstant()); - VariableList list({&var_stable}, zone()); - - DescriptorArrayForEach( - list, Unsigned(Int32Constant(0)), nof_descriptors, - [=, &var_stable](TNode<UintPtrT> descriptor_key_index) { - TNode<Name> next_key = CAST( - LoadWeakFixedArrayElement(from_descriptors, descriptor_key_index)); - - TVARIABLE(Object, var_value, SmiConstant(0)); - Label do_store(this), next_iteration(this); - - { - TVARIABLE(Map, var_from_map); - TVARIABLE(HeapObject, var_meta_storage); - TVARIABLE(IntPtrT, var_entry); - TVARIABLE(Uint32T, var_details); - Label if_found(this); - - Label if_found_fast(this), if_found_dict(this); - - Label if_stable(this), if_not_stable(this); - Branch(var_stable.value(), &if_stable, &if_not_stable); - BIND(&if_stable); - { - // Directly decode from the descriptor array if |from| did not - // change shape. - var_from_map = from_map; - var_meta_storage = from_descriptors; - var_entry = Signed(descriptor_key_index); - Goto(&if_found_fast); - } - BIND(&if_not_stable); - { - // If the map did change, do a slower lookup. We are still - // guaranteed that the object has a simple shape, and that the key - // is a name. - var_from_map = LoadMap(CAST(from)); - TryLookupPropertyInSimpleObject( - CAST(from), var_from_map.value(), next_key, &if_found_fast, - &if_found_dict, &var_meta_storage, &var_entry, &next_iteration); - } - - BIND(&if_found_fast); - { - TNode<DescriptorArray> descriptors = CAST(var_meta_storage.value()); - TNode<IntPtrT> name_index = var_entry.value(); - - // Skip non-enumerable properties. - var_details = LoadDetailsByKeyIndex(descriptors, name_index); - GotoIf(IsSetWord32(var_details.value(), - PropertyDetails::kAttributesDontEnumMask), - &next_iteration); - - LoadPropertyFromFastObject(from, var_from_map.value(), descriptors, - name_index, var_details.value(), - &var_value); - Goto(&if_found); - } - BIND(&if_found_dict); - { - Node* dictionary = var_meta_storage.value(); - Node* entry = var_entry.value(); - - TNode<Uint32T> details = - LoadDetailsByKeyIndex<NameDictionary>(dictionary, entry); - // Skip non-enumerable properties. - GotoIf( - IsSetWord32(details, PropertyDetails::kAttributesDontEnumMask), - &next_iteration); - - var_details = details; - var_value = LoadValueByKeyIndex<NameDictionary>(dictionary, entry); - Goto(&if_found); - } - - // Here we have details and value which could be an accessor. - BIND(&if_found); - { - Label slow_load(this, Label::kDeferred); - - var_value = - CallGetterIfAccessor(var_value.value(), var_details.value(), - context, from, &slow_load, kCallJSGetter); - Goto(&do_store); - - BIND(&slow_load); - { - var_value = - CallRuntime(Runtime::kGetProperty, context, from, next_key); - Goto(&do_store); - } - } - } - - // Store property to target object. - BIND(&do_store); - { - KeyedStoreGenericGenerator::SetProperty( - state(), context, to, to_is_simple_receiver, next_key, - var_value.value(), LanguageMode::kStrict); - - // Check if the |from| object is still stable, i.e. we can proceed - // using property details from preloaded |from_descriptors|. - var_stable = Select<BoolT>( - var_stable.value(), - [=] { return WordEqual(LoadMap(CAST(from)), from_map); }, - [=] { return Int32FalseConstant(); }); - - Goto(&next_iteration); - } - - BIND(&next_iteration); - }); + ForEachEnumerableOwnProperty(context, from_map, CAST(from), + [=](TNode<Name> key, TNode<Object> value) { + KeyedStoreGenericGenerator::SetProperty( + state(), context, to, + to_is_simple_receiver, key, value, + LanguageMode::kStrict); + }, + slow); Goto(&done); - BIND(&done); } @@ -1008,13 +877,13 @@ TF_BUILTIN(ObjectPrototypeToString, ObjectBuiltinsAssembler) { BIND(&if_arguments); { - var_default.Bind(LoadRoot(Heap::karguments_to_stringRootIndex)); + var_default.Bind(LoadRoot(RootIndex::karguments_to_string)); Goto(&checkstringtag); } BIND(&if_array); { - var_default.Bind(LoadRoot(Heap::karray_to_stringRootIndex)); + var_default.Bind(LoadRoot(RootIndex::karray_to_string)); Goto(&checkstringtag); } @@ -1027,26 +896,26 @@ TF_BUILTIN(ObjectPrototypeToString, ObjectBuiltinsAssembler) { boolean_constructor, JSFunction::kPrototypeOrInitialMapOffset); Node* boolean_prototype = LoadObjectField(boolean_initial_map, Map::kPrototypeOffset); - var_default.Bind(LoadRoot(Heap::kboolean_to_stringRootIndex)); + var_default.Bind(LoadRoot(RootIndex::kboolean_to_string)); var_holder.Bind(boolean_prototype); Goto(&checkstringtag); } BIND(&if_date); { - var_default.Bind(LoadRoot(Heap::kdate_to_stringRootIndex)); + var_default.Bind(LoadRoot(RootIndex::kdate_to_string)); Goto(&checkstringtag); } BIND(&if_error); { - var_default.Bind(LoadRoot(Heap::kerror_to_stringRootIndex)); + var_default.Bind(LoadRoot(RootIndex::kerror_to_string)); Goto(&checkstringtag); } BIND(&if_function); { - var_default.Bind(LoadRoot(Heap::kfunction_to_stringRootIndex)); + var_default.Bind(LoadRoot(RootIndex::kfunction_to_string)); Goto(&checkstringtag); } @@ -1059,7 +928,7 @@ TF_BUILTIN(ObjectPrototypeToString, ObjectBuiltinsAssembler) { number_constructor, JSFunction::kPrototypeOrInitialMapOffset); Node* number_prototype = LoadObjectField(number_initial_map, Map::kPrototypeOffset); - var_default.Bind(LoadRoot(Heap::knumber_to_stringRootIndex)); + var_default.Bind(LoadRoot(RootIndex::knumber_to_string)); var_holder.Bind(number_prototype); Goto(&checkstringtag); } @@ -1067,7 +936,7 @@ TF_BUILTIN(ObjectPrototypeToString, ObjectBuiltinsAssembler) { BIND(&if_object); { CSA_ASSERT(this, IsJSReceiver(receiver)); - var_default.Bind(LoadRoot(Heap::kobject_to_stringRootIndex)); + var_default.Bind(LoadRoot(RootIndex::kobject_to_string)); Goto(&checkstringtag); } @@ -1082,10 +951,10 @@ TF_BUILTIN(ObjectPrototypeToString, ObjectBuiltinsAssembler) { GotoIf(IsSymbolMap(receiver_map), &if_symbol); GotoIf(IsUndefined(receiver), &return_undefined); CSA_ASSERT(this, IsNull(receiver)); - Return(LoadRoot(Heap::knull_to_stringRootIndex)); + Return(LoadRoot(RootIndex::knull_to_string)); BIND(&return_undefined); - Return(LoadRoot(Heap::kundefined_to_stringRootIndex)); + Return(LoadRoot(RootIndex::kundefined_to_string)); } BIND(&if_proxy); @@ -1099,12 +968,12 @@ TF_BUILTIN(ObjectPrototypeToString, ObjectBuiltinsAssembler) { CallRuntime(Runtime::kArrayIsArray, context, receiver); TNode<String> builtin_tag = Select<String>( IsTrue(receiver_is_array), - [=] { return CAST(LoadRoot(Heap::kArray_stringRootIndex)); }, + [=] { return CAST(LoadRoot(RootIndex::kArray_string)); }, [=] { return Select<String>( IsCallableMap(receiver_map), - [=] { return CAST(LoadRoot(Heap::kFunction_stringRootIndex)); }, - [=] { return CAST(LoadRoot(Heap::kObject_stringRootIndex)); }); + [=] { return CAST(LoadRoot(RootIndex::kFunction_string)); }, + [=] { return CAST(LoadRoot(RootIndex::kObject_string)); }); }); // Lookup the @@toStringTag property on the {receiver}. @@ -1125,7 +994,7 @@ TF_BUILTIN(ObjectPrototypeToString, ObjectBuiltinsAssembler) { BIND(&if_regexp); { - var_default.Bind(LoadRoot(Heap::kregexp_to_stringRootIndex)); + var_default.Bind(LoadRoot(RootIndex::kregexp_to_string)); Goto(&checkstringtag); } @@ -1138,7 +1007,7 @@ TF_BUILTIN(ObjectPrototypeToString, ObjectBuiltinsAssembler) { string_constructor, JSFunction::kPrototypeOrInitialMapOffset); Node* string_prototype = LoadObjectField(string_initial_map, Map::kPrototypeOffset); - var_default.Bind(LoadRoot(Heap::kstring_to_stringRootIndex)); + var_default.Bind(LoadRoot(RootIndex::kstring_to_string)); var_holder.Bind(string_prototype); Goto(&checkstringtag); } @@ -1152,7 +1021,7 @@ TF_BUILTIN(ObjectPrototypeToString, ObjectBuiltinsAssembler) { symbol_constructor, JSFunction::kPrototypeOrInitialMapOffset); Node* symbol_prototype = LoadObjectField(symbol_initial_map, Map::kPrototypeOffset); - var_default.Bind(LoadRoot(Heap::kobject_to_stringRootIndex)); + var_default.Bind(LoadRoot(RootIndex::kobject_to_string)); var_holder.Bind(symbol_prototype); Goto(&checkstringtag); } @@ -1166,7 +1035,7 @@ TF_BUILTIN(ObjectPrototypeToString, ObjectBuiltinsAssembler) { bigint_constructor, JSFunction::kPrototypeOrInitialMapOffset); Node* bigint_prototype = LoadObjectField(bigint_initial_map, Map::kPrototypeOffset); - var_default.Bind(LoadRoot(Heap::kobject_to_stringRootIndex)); + var_default.Bind(LoadRoot(RootIndex::kobject_to_string)); var_holder.Bind(bigint_prototype); Goto(&checkstringtag); } @@ -1209,7 +1078,7 @@ TF_BUILTIN(ObjectPrototypeToString, ObjectBuiltinsAssembler) { BIND(&return_generic); { Node* tag = GetProperty(context, ToObject(context, receiver), - LoadRoot(Heap::kto_string_tag_symbolRootIndex)); + LoadRoot(RootIndex::kto_string_tag_symbol)); GotoIf(TaggedIsSmi(tag), &return_default); GotoIfNot(IsString(tag), &return_default); ReturnToStringFormat(context, tag); @@ -1271,7 +1140,7 @@ TF_BUILTIN(CreateObjectWithoutProperties, ObjectBuiltinsAssembler) { TNode<MaybeObject> maybe_map = LoadMaybeWeakObjectField( prototype_info, PrototypeInfo::kObjectCreateMapOffset); GotoIf(IsStrongReferenceTo(maybe_map, UndefinedConstant()), &call_runtime); - map.Bind(ToWeakHeapObject(maybe_map, &call_runtime)); + map.Bind(GetHeapObjectAssumeWeak(maybe_map, &call_runtime)); Goto(&instantiate_map); } @@ -1323,7 +1192,7 @@ TF_BUILTIN(ObjectCreate, ObjectBuiltinsAssembler) { GotoIf(IsSpecialReceiverMap(properties_map), &call_runtime); // Stay on the fast path only if there are no elements. GotoIfNot(WordEqual(LoadElements(properties), - LoadRoot(Heap::kEmptyFixedArrayRootIndex)), + LoadRoot(RootIndex::kEmptyFixedArray)), &call_runtime); // Handle dictionary objects or fast objects with properties in runtime. Node* bit_field3 = LoadMapBitField3(properties_map); @@ -1367,7 +1236,7 @@ TF_BUILTIN(ObjectCreate, ObjectBuiltinsAssembler) { prototype_info, PrototypeInfo::kObjectCreateMapOffset); GotoIf(IsStrongReferenceTo(maybe_map, UndefinedConstant()), &call_runtime); - map.Bind(ToWeakHeapObject(maybe_map, &call_runtime)); + map.Bind(GetHeapObjectAssumeWeak(maybe_map, &call_runtime)); Goto(&instantiate_map); } @@ -1476,8 +1345,7 @@ TF_BUILTIN(CreateGeneratorObject, ObjectBuiltinsAssembler) { formal_parameter_count); Node* parameters_and_registers = AllocateFixedArray(HOLEY_ELEMENTS, size); FillFixedArrayWithValue(HOLEY_ELEMENTS, parameters_and_registers, - IntPtrConstant(0), size, - Heap::kUndefinedValueRootIndex); + IntPtrConstant(0), size, RootIndex::kUndefinedValue); // TODO(cbruni): support start_offset to avoid double initialization. Node* result = AllocateJSObjectFromMap(maybe_map, nullptr, nullptr, kNone, kWithSlackTracking); @@ -1522,7 +1390,7 @@ TF_BUILTIN(ObjectGetOwnPropertyDescriptor, ObjectBuiltinsAssembler) { object = ToObject_Inline(CAST(context), CAST(object)); // 2. Let key be ? ToPropertyKey(P). - key = ToName(context, key); + key = CallBuiltin(Builtins::kToName, context, key); // 3. Let desc be ? obj.[[GetOwnProperty]](key). Label if_keyisindex(this), if_iskeyunique(this), |