diff options
author | Myles Borins <mylesborins@google.com> | 2019-09-24 11:56:38 -0400 |
---|---|---|
committer | Myles Borins <myles.borins@gmail.com> | 2019-10-07 03:19:23 -0400 |
commit | f7f6c928c1c9c136b7926f892b8a2fda11d8b4b2 (patch) | |
tree | f5edbccb3ffda2573d70a6e291e7157f290e0ae0 /deps/v8/src/ic | |
parent | ffd22e81983056d09c064c59343a0e488236272d (diff) | |
download | node-new-f7f6c928c1c9c136b7926f892b8a2fda11d8b4b2.tar.gz |
deps: update V8 to 7.8.279.9
PR-URL: https://github.com/nodejs/node/pull/29694
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Diffstat (limited to 'deps/v8/src/ic')
-rw-r--r-- | deps/v8/src/ic/OWNERS | 1 | ||||
-rw-r--r-- | deps/v8/src/ic/accessor-assembler.cc | 803 | ||||
-rw-r--r-- | deps/v8/src/ic/accessor-assembler.h | 50 | ||||
-rw-r--r-- | deps/v8/src/ic/binary-op-assembler.cc | 33 | ||||
-rw-r--r-- | deps/v8/src/ic/handler-configuration-inl.h | 4 | ||||
-rw-r--r-- | deps/v8/src/ic/handler-configuration.cc | 41 | ||||
-rw-r--r-- | deps/v8/src/ic/handler-configuration.h | 76 | ||||
-rw-r--r-- | deps/v8/src/ic/ic.cc | 90 | ||||
-rw-r--r-- | deps/v8/src/ic/keyed-store-generic.cc | 309 | ||||
-rw-r--r-- | deps/v8/src/ic/keyed-store-generic.h | 2 |
10 files changed, 698 insertions, 711 deletions
diff --git a/deps/v8/src/ic/OWNERS b/deps/v8/src/ic/OWNERS index 51788b41e4..816ddb52c5 100644 --- a/deps/v8/src/ic/OWNERS +++ b/deps/v8/src/ic/OWNERS @@ -3,5 +3,6 @@ ishell@chromium.org jkummerow@chromium.org mvstanton@chromium.org verwaest@chromium.org +mythria@chromium.org # COMPONENT: Blink>JavaScript>Runtime diff --git a/deps/v8/src/ic/accessor-assembler.cc b/deps/v8/src/ic/accessor-assembler.cc index 7aebf857a2..f9efcba05f 100644 --- a/deps/v8/src/ic/accessor-assembler.cc +++ b/deps/v8/src/ic/accessor-assembler.cc @@ -35,7 +35,7 @@ TNode<MaybeObject> AccessorAssembler::LoadHandlerDataField( SloppyTNode<DataHandler> handler, int data_index) { #ifdef DEBUG TNode<Map> handler_map = LoadMap(handler); - TNode<Int32T> instance_type = LoadMapInstanceType(handler_map); + TNode<Uint16T> instance_type = LoadMapInstanceType(handler_map); #endif CSA_ASSERT(this, Word32Or(InstanceTypeEqual(instance_type, LOAD_HANDLER_TYPE), @@ -78,7 +78,8 @@ TNode<MaybeObject> AccessorAssembler::TryMonomorphicCase( // Adding |header_size| with a separate IntPtrAdd rather than passing it // into ElementOffsetFromIndex() allows it to be folded into a single // [base, index, offset] indirect memory access on x64. - Node* offset = ElementOffsetFromIndex(slot, HOLEY_ELEMENTS, SMI_PARAMETERS); + TNode<IntPtrT> offset = + ElementOffsetFromIndex(slot, HOLEY_ELEMENTS, SMI_PARAMETERS); TNode<MaybeObject> feedback = ReinterpretCast<MaybeObject>( Load(MachineType::AnyTagged(), vector, IntPtrAdd(offset, IntPtrConstant(header_size)))); @@ -207,7 +208,7 @@ void AccessorAssembler::HandleLoadAccessor( CSA_ASSERT(this, IsWeakOrCleared(maybe_context)); CSA_CHECK(this, IsNotCleared(maybe_context)); - TNode<Object> context = GetHeapObjectAssumeWeak(maybe_context); + TNode<HeapObject> context = GetHeapObjectAssumeWeak(maybe_context); TNode<Foreign> foreign = CAST( LoadObjectField(call_handler_info, CallHandlerInfo::kJsCallbackOffset)); @@ -241,8 +242,9 @@ void AccessorAssembler::HandleLoadField(Node* holder, Node* handler_word, Label* rebox_double, ExitPoint* exit_point) { Comment("field_load"); - Node* index = DecodeWord<LoadHandler::FieldIndexBits>(handler_word); - Node* offset = IntPtrMul(index, IntPtrConstant(kTaggedSize)); + TNode<IntPtrT> index = + Signed(DecodeWord<LoadHandler::FieldIndexBits>(handler_word)); + TNode<IntPtrT> offset = IntPtrMul(index, IntPtrConstant(kTaggedSize)); Label inobject(this), out_of_object(this); Branch(IsSetWord<LoadHandler::IsInobjectBits>(handler_word), &inobject, @@ -259,8 +261,8 @@ void AccessorAssembler::HandleLoadField(Node* holder, Node* handler_word, var_double_value->Bind( LoadObjectField(holder, offset, MachineType::Float64())); } else { - Node* mutable_heap_number = LoadObjectField(holder, offset); - var_double_value->Bind(LoadHeapNumberValue(mutable_heap_number)); + TNode<HeapNumber> heap_number = CAST(LoadObjectField(holder, offset)); + var_double_value->Bind(LoadHeapNumberValue(heap_number)); } Goto(rebox_double); } @@ -268,13 +270,13 @@ void AccessorAssembler::HandleLoadField(Node* holder, Node* handler_word, BIND(&out_of_object); { Label is_double(this); - Node* properties = LoadFastProperties(holder); - Node* value = LoadObjectField(properties, offset); + TNode<HeapObject> properties = LoadFastProperties(holder); + TNode<Object> value = LoadObjectField(properties, offset); GotoIf(IsSetWord<LoadHandler::IsDoubleBits>(handler_word), &is_double); exit_point->Return(value); BIND(&is_double); - var_double_value->Bind(LoadHeapNumberValue(value)); + var_double_value->Bind(LoadHeapNumberValue(CAST(value))); Goto(rebox_double); } } @@ -298,9 +300,10 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( VARIABLE(var_double_value, MachineRepresentation::kFloat64); Label rebox_double(this, &var_double_value); - TNode<WordT> handler_word = SmiUntag(smi_handler); + TNode<IntPtrT> handler_word = SmiUntag(smi_handler); TNode<IntPtrT> handler_kind = Signed(DecodeWord<LoadHandler::KindBits>(handler_word)); + if (support_elements == kSupportElements) { Label if_element(this), if_indexed_string(this), if_property(this); GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kElement)), @@ -319,10 +322,10 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( BIND(&if_element); Comment("element_load"); - Node* intptr_index = TryToIntptr(p->name(), miss); - Node* is_jsarray_condition = + TNode<IntPtrT> intptr_index = TryToIntptr(p->name(), miss); + TNode<BoolT> is_jsarray_condition = IsSetWord<LoadHandler::IsJsArrayBits>(handler_word); - Node* elements_kind = + TNode<Uint32T> elements_kind = DecodeWord32FromWord<LoadHandler::ElementsKindBits>(handler_word); Label if_hole(this), unimplemented_elements_kind(this), if_oob(this, Label::kDeferred); @@ -345,7 +348,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( Label return_undefined(this); // Check if we're allowed to handle OOB accesses. - Node* allow_out_of_bounds = + TNode<BoolT> allow_out_of_bounds = IsSetWord<LoadHandler::AllowOutOfBoundsBits>(handler_word); GotoIfNot(allow_out_of_bounds, miss); @@ -385,15 +388,15 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( Label if_oob(this, Label::kDeferred); Comment("indexed string"); - Node* intptr_index = TryToIntptr(p->name(), miss); - Node* length = LoadStringLengthAsWord(holder); + TNode<IntPtrT> intptr_index = TryToIntptr(p->name(), miss); + TNode<IntPtrT> length = LoadStringLengthAsWord(holder); GotoIf(UintPtrGreaterThanOrEqual(intptr_index, length), &if_oob); TNode<Int32T> code = StringCharCodeAt(holder, intptr_index); TNode<String> result = StringFromSingleCharCode(code); Return(result); BIND(&if_oob); - Node* allow_out_of_bounds = + TNode<BoolT> allow_out_of_bounds = IsSetWord<LoadHandler::AllowOutOfBoundsBits>(handler_word); GotoIfNot(allow_out_of_bounds, miss); GotoIf(IsNoElementsProtectorCellInvalid(), miss); @@ -426,9 +429,11 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( module_export(this, Label::kDeferred), proxy(this, Label::kDeferred), native_data_property(this, Label::kDeferred), api_getter(this, Label::kDeferred); + GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kField)), &field); - GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kConstant)), + GotoIf(WordEqual(handler_kind, + IntPtrConstant(LoadHandler::kConstantFromPrototype)), &constant); GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kNonExistent)), @@ -476,11 +481,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( BIND(&constant); { Comment("constant_load"); - TNode<IntPtrT> descriptor = - Signed(DecodeWord<LoadHandler::DescriptorBits>(handler_word)); - Node* value = LoadDescriptorValue(LoadMap(holder), descriptor); - - exit_point->Return(value); + exit_point->Return(holder); } BIND(&normal); @@ -497,8 +498,9 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( VARIABLE(var_value, MachineRepresentation::kTagged); LoadPropertyFromNameDictionary(properties, var_name_index.value(), &var_details, &var_value); - Node* value = CallGetterIfAccessor(var_value.value(), var_details.value(), - p->context(), p->receiver(), miss); + TNode<Object> value = + CallGetterIfAccessor(var_value.value(), var_details.value(), + p->context(), p->receiver(), miss); exit_point->Return(value); } } @@ -508,9 +510,10 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( Comment("accessor_load"); TNode<IntPtrT> descriptor = Signed(DecodeWord<LoadHandler::DescriptorBits>(handler_word)); - Node* accessor_pair = LoadDescriptorValue(LoadMap(holder), descriptor); - CSA_ASSERT(this, IsAccessorPair(accessor_pair)); - Node* getter = LoadObjectField(accessor_pair, AccessorPair::kGetterOffset); + TNode<AccessorPair> accessor_pair = + CAST(LoadDescriptorValue(LoadMap(holder), descriptor)); + TNode<Object> getter = + LoadObjectField(accessor_pair, AccessorPair::kGetterOffset); CSA_ASSERT(this, Word32BinaryNot(IsTheHole(getter))); Callable callable = CodeFactory::Call(isolate()); @@ -567,8 +570,8 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( { CSA_ASSERT(this, IsPropertyCell(holder)); // Ensure the property cell doesn't contain the hole. - Node* value = LoadObjectField(holder, PropertyCell::kValueOffset); - Node* details = LoadAndUntagToWord32ObjectField( + TNode<Object> value = LoadObjectField(holder, PropertyCell::kValueOffset); + TNode<Int32T> details = LoadAndUntagToWord32ObjectField( holder, PropertyCell::kPropertyDetailsRawOffset); GotoIf(IsTheHole(value), miss); @@ -587,15 +590,15 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( BIND(&module_export); { Comment("module export"); - Node* index = DecodeWord<LoadHandler::ExportsIndexBits>(handler_word); + TNode<UintPtrT> index = + DecodeWord<LoadHandler::ExportsIndexBits>(handler_word); Node* module = LoadObjectField(p->receiver(), JSModuleNamespace::kModuleOffset, MachineType::TaggedPointer()); TNode<ObjectHashTable> exports = CAST(LoadObjectField( module, Module::kExportsOffset, MachineType::TaggedPointer())); - Node* cell = LoadFixedArrayElement(exports, index); + TNode<Cell> cell = CAST(LoadFixedArrayElement(exports, index)); // The handler is only installed for exports that exist. - CSA_ASSERT(this, IsCell(cell)); Node* value = LoadCellValue(cell); Label is_the_hole(this, Label::kDeferred); GotoIf(IsTheHole(value), &is_the_hole); @@ -603,7 +606,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( BIND(&is_the_hole); { - Node* message = SmiConstant(MessageTemplate::kNotDefined); + TNode<Smi> message = SmiConstant(MessageTemplate::kNotDefined); exit_point->ReturnCallRuntime(Runtime::kThrowReferenceError, p->context(), message, p->name()); } @@ -622,7 +625,8 @@ void AccessorAssembler::HandleLoadICSmiHandlerHasNamedCase( GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kField)), &return_true); - GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kConstant)), + GotoIf(WordEqual(handler_kind, + IntPtrConstant(LoadHandler::kConstantFromPrototype)), &return_true); GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kNonExistent)), @@ -686,7 +690,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerHasNamedCase( { CSA_ASSERT(this, IsPropertyCell(holder)); // Ensure the property cell doesn't contain the hole. - Node* value = LoadObjectField(holder, PropertyCell::kValueOffset); + TNode<Object> value = LoadObjectField(holder, PropertyCell::kValueOffset); GotoIf(IsTheHole(value), miss); exit_point->Return(TrueConstant()); @@ -719,7 +723,7 @@ Node* AccessorAssembler::HandleProtoHandler( // Check prototype validity cell. // { - Node* maybe_validity_cell = + TNode<Object> maybe_validity_cell = LoadObjectField(handler, ICHandler::kValidityCellOffset); CheckPrototypeValidityCell(maybe_validity_cell, miss); } @@ -728,20 +732,18 @@ Node* AccessorAssembler::HandleProtoHandler( // Check smi handler bits. // { - Node* smi_or_code_handler = + TNode<Object> smi_or_code_handler = LoadObjectField(handler, ICHandler::kSmiHandlerOffset); if (on_code_handler) { Label if_smi_handler(this); GotoIf(TaggedIsSmi(smi_or_code_handler), &if_smi_handler); - CSA_ASSERT(this, IsCodeMap(LoadMap(smi_or_code_handler))); + CSA_ASSERT(this, IsCodeMap(LoadMap(CAST(smi_or_code_handler)))); on_code_handler(smi_or_code_handler); BIND(&if_smi_handler); - } else { - CSA_ASSERT(this, TaggedIsSmi(smi_or_code_handler)); } - Node* handler_flags = SmiUntag(smi_or_code_handler); + TNode<IntPtrT> handler_flags = SmiUntag(CAST(smi_or_code_handler)); // Lookup on receiver and access checks are not necessary for global ICs // because in the former case the validity cell check guards modifications @@ -767,8 +769,8 @@ Node* AccessorAssembler::HandleProtoHandler( { TNode<MaybeObject> data2 = LoadHandlerDataField(handler, 2); CSA_ASSERT(this, IsWeakOrCleared(data2)); - TNode<Object> expected_native_context = - GetHeapObjectAssumeWeak(data2, miss); + TNode<Context> expected_native_context = + CAST(GetHeapObjectAssumeWeak(data2, miss)); EmitAccessCheck(expected_native_context, p->context(), p->receiver(), &done, miss); } @@ -824,7 +826,7 @@ void AccessorAssembler::HandleLoadICProtoHandler( VARIABLE(var_value, MachineRepresentation::kTagged); LoadPropertyFromNameDictionary(properties, name_index, &var_details, &var_value); - Node* value = + TNode<Object> value = CallGetterIfAccessor(var_value.value(), var_details.value(), p->context(), p->receiver(), miss); exit_point->Return(value); @@ -832,21 +834,38 @@ void AccessorAssembler::HandleLoadICProtoHandler( }, miss, ic_mode); - TNode<MaybeObject> maybe_holder = LoadHandlerDataField(handler, 1); + TNode<MaybeObject> maybe_holder_or_constant = + LoadHandlerDataField(handler, 1); - Label load_from_cached_holder(this), done(this); + Label load_from_cached_holder(this), is_smi(this), done(this); - Branch(IsStrongReferenceTo(maybe_holder, NullConstant()), &done, + GotoIf(TaggedIsSmi(maybe_holder_or_constant), &is_smi); + Branch(IsStrongReferenceTo(maybe_holder_or_constant, NullConstant()), &done, &load_from_cached_holder); - BIND(&load_from_cached_holder); + BIND(&is_smi); { - // For regular holders, having passed the receiver map check and the - // validity cell check implies that |holder| is alive. However, for global - // object receivers, |maybe_holder| may be cleared. - CSA_ASSERT(this, IsWeakOrCleared(maybe_holder)); - Node* holder = GetHeapObjectAssumeWeak(maybe_holder, miss); + CSA_ASSERT( + this, + WordEqual( + Signed(DecodeWord<LoadHandler::KindBits>(SmiUntag(smi_handler))), + IntPtrConstant(LoadHandler::kConstantFromPrototype))); + if (access_mode == LoadAccessMode::kHas) { + exit_point->Return(TrueConstant()); + } else { + exit_point->Return(maybe_holder_or_constant); + } + } + BIND(&load_from_cached_holder); + { + // For regular holders, having passed the receiver map check and + // the validity cell check implies that |holder| is + // alive. However, for global object receivers, |maybe_holder| may + // be cleared. + CSA_ASSERT(this, IsWeakOrCleared(maybe_holder_or_constant)); + TNode<HeapObject> holder = + GetHeapObjectAssumeWeak(maybe_holder_or_constant, miss); var_holder->Bind(holder); Goto(&done); } @@ -858,22 +877,22 @@ void AccessorAssembler::HandleLoadICProtoHandler( } } -void AccessorAssembler::EmitAccessCheck(Node* expected_native_context, - Node* context, Node* receiver, +void AccessorAssembler::EmitAccessCheck(TNode<Context> expected_native_context, + TNode<Context> context, Node* receiver, Label* can_access, Label* miss) { CSA_ASSERT(this, IsNativeContext(expected_native_context)); - Node* native_context = LoadNativeContext(context); - GotoIf(WordEqual(expected_native_context, native_context), can_access); + TNode<Context> native_context = LoadNativeContext(context); + GotoIf(TaggedEqual(expected_native_context, native_context), can_access); // If the receiver is not a JSGlobalProxy then we miss. GotoIfNot(IsJSGlobalProxy(receiver), miss); // For JSGlobalProxy receiver try to compare security tokens of current // and expected native contexts. - Node* expected_token = LoadContextElement(expected_native_context, - Context::SECURITY_TOKEN_INDEX); - Node* current_token = + TNode<Object> expected_token = LoadContextElement( + expected_native_context, Context::SECURITY_TOKEN_INDEX); + TNode<Object> current_token = LoadContextElement(native_context, Context::SECURITY_TOKEN_INDEX); - Branch(WordEqual(expected_token, current_token), can_access, miss); + Branch(TaggedEqual(expected_token, current_token), can_access, miss); } void AccessorAssembler::JumpIfDataProperty(Node* details, Label* writable, @@ -886,7 +905,7 @@ void AccessorAssembler::JumpIfDataProperty(Node* details, Label* writable, CSA_ASSERT(this, IsNotSetWord32(details, PropertyDetails::kAttributesReadOnlyMask)); } - Node* kind = DecodeWord32<PropertyDetails::KindField>(details); + TNode<Uint32T> kind = DecodeWord32<PropertyDetails::KindField>(details); GotoIf(Word32Equal(kind, Int32Constant(kData)), writable); // Fall through if it's an accessor property. } @@ -896,8 +915,8 @@ void AccessorAssembler::HandleStoreICNativeDataProperty( Comment("native_data_property_store"); TNode<IntPtrT> descriptor = Signed(DecodeWord<StoreHandler::DescriptorBits>(handler_word)); - Node* accessor_info = LoadDescriptorValue(LoadMap(holder), descriptor); - CSA_CHECK(this, IsAccessorInfo(accessor_info)); + TNode<AccessorInfo> accessor_info = + CAST(LoadDescriptorValue(LoadMap(holder), descriptor)); TailCallRuntime(Runtime::kStoreCallbackProperty, p->context(), p->receiver(), holder, accessor_info, p->name(), p->value()); @@ -917,7 +936,7 @@ void AccessorAssembler::HandleStoreICHandlerCase( BIND(&if_smi_handler); { Node* holder = p->receiver(); - Node* handler_word = SmiUntag(CAST(handler)); + TNode<IntPtrT> handler_word = SmiUntag(CAST(handler)); Label if_fast_smi(this), if_proxy(this); @@ -925,7 +944,8 @@ void AccessorAssembler::HandleStoreICHandlerCase( STATIC_ASSERT(StoreHandler::kNormal + 1 == StoreHandler::kProxy); STATIC_ASSERT(StoreHandler::kProxy + 1 == StoreHandler::kKindsNumber); - Node* handler_kind = DecodeWord<StoreHandler::KindBits>(handler_word); + TNode<UintPtrT> handler_kind = + DecodeWord<StoreHandler::KindBits>(handler_word); GotoIf(IntPtrLessThan(handler_kind, IntPtrConstant(StoreHandler::kGlobalProxy)), &if_fast_smi); @@ -941,7 +961,7 @@ void AccessorAssembler::HandleStoreICHandlerCase( properties, CAST(p->name()), &dictionary_found, &var_name_index, miss); BIND(&dictionary_found); { - Node* details = LoadDetailsByKeyIndex<NameDictionary>( + TNode<Uint32T> details = LoadDetailsByKeyIndex<NameDictionary>( properties, var_name_index.value()); // Check that the property is a writable data property (no accessor). const int kTypeAndReadOnlyMask = PropertyDetails::KindField::kMask | @@ -956,7 +976,8 @@ void AccessorAssembler::HandleStoreICHandlerCase( BIND(&if_fast_smi); { - Node* handler_kind = DecodeWord<StoreHandler::KindBits>(handler_word); + TNode<UintPtrT> handler_kind = + DecodeWord<StoreHandler::KindBits>(handler_word); Label data(this), accessor(this), native_data_property(this); GotoIf(WordEqual(handler_kind, IntPtrConstant(StoreHandler::kAccessor)), @@ -1034,7 +1055,7 @@ void AccessorAssembler::HandleStoreICTransitionMapHandlerCase( StoreTransitionMapFlags flags) { DCHECK_EQ(0, flags & ~kStoreTransitionMapFlagsMask); if (flags & kCheckPrototypeValidity) { - Node* maybe_validity_cell = + TNode<Object> maybe_validity_cell = LoadObjectField(transition_map, Map::kPrototypeValidityCellOffset); CheckPrototypeValidityCell(maybe_validity_cell, miss); } @@ -1044,21 +1065,22 @@ void AccessorAssembler::HandleStoreICTransitionMapHandlerCase( GotoIf(IsSetWord32<Map::IsDeprecatedBit>(bitfield3), miss); // Load last descriptor details. - Node* nof = DecodeWordFromWord32<Map::NumberOfOwnDescriptorsBits>(bitfield3); + TNode<UintPtrT> nof = + DecodeWordFromWord32<Map::NumberOfOwnDescriptorsBits>(bitfield3); CSA_ASSERT(this, WordNotEqual(nof, IntPtrConstant(0))); TNode<DescriptorArray> descriptors = LoadMapDescriptors(transition_map); - Node* factor = IntPtrConstant(DescriptorArray::kEntrySize); + TNode<IntPtrT> factor = IntPtrConstant(DescriptorArray::kEntrySize); TNode<IntPtrT> last_key_index = UncheckedCast<IntPtrT>(IntPtrAdd( IntPtrConstant(DescriptorArray::ToKeyIndex(-1)), IntPtrMul(nof, factor))); if (flags & kValidateTransitionHandler) { TNode<Name> key = LoadKeyByKeyIndex(descriptors, last_key_index); - GotoIf(WordNotEqual(key, p->name()), miss); + GotoIf(TaggedNotEqual(key, p->name()), miss); } else { - CSA_ASSERT(this, WordEqual(LoadKeyByKeyIndex(descriptors, last_key_index), - p->name())); + CSA_ASSERT(this, TaggedEqual(LoadKeyByKeyIndex(descriptors, last_key_index), + p->name())); } - Node* details = LoadDetailsByKeyIndex(descriptors, last_key_index); + TNode<Uint32T> details = LoadDetailsByKeyIndex(descriptors, last_key_index); if (flags & kValidateTransitionHandler) { // Follow transitions only in the following cases: // 1) name is a non-private symbol and attributes equal to NONE, @@ -1077,7 +1099,7 @@ void AccessorAssembler::HandleStoreICTransitionMapHandlerCase( // DontEnum attribute is allowed only for private symbols and vice versa. Branch(Word32Equal( IsSetWord32(details, PropertyDetails::kAttributesDontEnumMask), - IsPrivateSymbol(p->name())), + IsPrivateSymbol(CAST(p->name()))), &attributes_ok, miss); BIND(&attributes_ok); @@ -1089,7 +1111,8 @@ void AccessorAssembler::HandleStoreICTransitionMapHandlerCase( } void AccessorAssembler::CheckFieldType(TNode<DescriptorArray> descriptors, - Node* name_index, Node* representation, + Node* name_index, + TNode<Word32T> representation, Node* value, Label* bailout) { Label r_smi(this), r_double(this), r_heapobject(this), all_fine(this); // Ignore FLAG_track_fields etc. and always emit code for all checks, @@ -1114,12 +1137,7 @@ void AccessorAssembler::CheckFieldType(TNode<DescriptorArray> descriptors, BIND(&r_double); { GotoIf(TaggedIsSmi(value), &all_fine); - Node* value_map = LoadMap(value); - // While supporting mutable HeapNumbers would be straightforward, such - // objects should not end up here anyway. - CSA_ASSERT(this, WordNotEqual(value_map, - LoadRoot(RootIndex::kMutableHeapNumberMap))); - Branch(IsHeapNumberMap(value_map), &all_fine, bailout); + Branch(IsHeapNumber(value), &all_fine, bailout); } BIND(&r_heapobject); @@ -1144,7 +1162,7 @@ void AccessorAssembler::CheckFieldType(TNode<DescriptorArray> descriptors, TNode<Map> field_type_map = CAST(GetHeapObjectAssumeWeak(field_type, bailout)); // FieldType::Class(...) performs a map check. - Branch(WordEqual(LoadMap(value), field_type_map), &all_fine, bailout); + Branch(TaggedEqual(LoadMap(value), field_type_map), &all_fine, bailout); } BIND(&all_fine); @@ -1157,8 +1175,8 @@ TNode<BoolT> AccessorAssembler::IsPropertyDetailsConst(Node* details) { void AccessorAssembler::OverwriteExistingFastDataProperty( Node* object, Node* object_map, Node* descriptors, - Node* descriptor_name_index, Node* details, Node* value, Label* slow, - bool do_transitioning_store) { + Node* descriptor_name_index, Node* details, TNode<Object> value, + Label* slow, bool do_transitioning_store) { Label done(this), if_field(this), if_descriptor(this); CSA_ASSERT(this, @@ -1171,17 +1189,19 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( BIND(&if_field); { - Node* representation = + TNode<Uint32T> representation = DecodeWord32<PropertyDetails::RepresentationField>(details); CheckFieldType(CAST(descriptors), descriptor_name_index, representation, value, slow); - Node* field_index = + TNode<UintPtrT> field_index = DecodeWordFromWord32<PropertyDetails::FieldIndexField>(details); - field_index = IntPtrAdd(field_index, - LoadMapInobjectPropertiesStartInWords(object_map)); - Node* instance_size_in_words = LoadMapInstanceSizeInWords(object_map); + field_index = Unsigned( + IntPtrAdd(field_index, + Unsigned(LoadMapInobjectPropertiesStartInWords(object_map)))); + TNode<IntPtrT> instance_size_in_words = + LoadMapInstanceSizeInWords(object_map); Label inobject(this), backing_store(this); Branch(UintPtrLessThan(field_index, instance_size_in_words), &inobject, @@ -1212,19 +1232,19 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( MachineRepresentation::kFloat64); } else { if (do_transitioning_store) { - Node* mutable_heap_number = - AllocateMutableHeapNumberWithValue(double_value); + TNode<HeapNumber> heap_number = + AllocateHeapNumberWithValue(double_value); StoreMap(object, object_map); - StoreObjectField(object, field_offset, mutable_heap_number); + StoreObjectField(object, field_offset, heap_number); } else { - Node* mutable_heap_number = LoadObjectField(object, field_offset); + TNode<HeapNumber> heap_number = + CAST(LoadObjectField(object, field_offset)); Label if_mutable(this); GotoIfNot(IsPropertyDetailsConst(details), &if_mutable); - TNode<Float64T> current_value = - LoadHeapNumberValue(mutable_heap_number); + TNode<Float64T> current_value = LoadHeapNumberValue(heap_number); BranchIfSameNumberValue(current_value, double_value, &done, slow); BIND(&if_mutable); - StoreHeapNumberValue(mutable_heap_number, double_value); + StoreHeapNumberValue(heap_number, double_value); } } Goto(&done); @@ -1250,8 +1270,8 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( BIND(&backing_store); { - Node* backing_store_index = - IntPtrSub(field_index, instance_size_in_words); + TNode<IntPtrT> backing_store_index = + Signed(IntPtrSub(field_index, instance_size_in_words)); if (do_transitioning_store) { // Allocate mutable heap number before extending properties backing @@ -1264,10 +1284,10 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( Int32Constant(Representation::kDouble)), &cont); { - Node* double_value = ChangeNumberToFloat64(CAST(value)); - Node* mutable_heap_number = - AllocateMutableHeapNumberWithValue(double_value); - var_value.Bind(mutable_heap_number); + TNode<Float64T> double_value = ChangeNumberToFloat64(CAST(value)); + TNode<HeapNumber> heap_number = + AllocateHeapNumberWithValue(double_value); + var_value.Bind(heap_number); Goto(&cont); } BIND(&cont); @@ -1288,18 +1308,17 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( &double_rep, &tagged_rep); BIND(&double_rep); { - Node* mutable_heap_number = - LoadPropertyArrayElement(properties, backing_store_index); + TNode<HeapNumber> heap_number = + CAST(LoadPropertyArrayElement(properties, backing_store_index)); TNode<Float64T> double_value = ChangeNumberToFloat64(CAST(value)); Label if_mutable(this); GotoIfNot(IsPropertyDetailsConst(details), &if_mutable); - TNode<Float64T> current_value = - LoadHeapNumberValue(mutable_heap_number); + TNode<Float64T> current_value = LoadHeapNumberValue(heap_number); BranchIfSameNumberValue(current_value, double_value, &done, slow); BIND(&if_mutable); - StoreHeapNumberValue(mutable_heap_number, double_value); + StoreHeapNumberValue(heap_number, double_value); Goto(&done); } BIND(&tagged_rep); @@ -1322,9 +1341,9 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( BIND(&if_descriptor); { // Check that constant matches value. - Node* constant = LoadValueByKeyIndex( + TNode<Object> constant = LoadValueByKeyIndex( CAST(descriptors), UncheckedCast<IntPtrT>(descriptor_name_index)); - GotoIf(WordNotEqual(value, constant), slow); + GotoIf(TaggedNotEqual(value, constant), slow); if (do_transitioning_store) { StoreMap(object, object_map); @@ -1334,15 +1353,17 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( BIND(&done); } -void AccessorAssembler::CheckPrototypeValidityCell(Node* maybe_validity_cell, - Label* miss) { +void AccessorAssembler::CheckPrototypeValidityCell( + TNode<Object> maybe_validity_cell, Label* miss) { Label done(this); - GotoIf(WordEqual(maybe_validity_cell, SmiConstant(Map::kPrototypeChainValid)), - &done); + GotoIf( + TaggedEqual(maybe_validity_cell, SmiConstant(Map::kPrototypeChainValid)), + &done); CSA_ASSERT(this, TaggedIsNotSmi(maybe_validity_cell)); - Node* cell_value = LoadObjectField(maybe_validity_cell, Cell::kValueOffset); - Branch(WordEqual(cell_value, SmiConstant(Map::kPrototypeChainValid)), &done, + TNode<Object> cell_value = + LoadObjectField(CAST(maybe_validity_cell), Cell::kValueOffset); + Branch(TaggedEqual(cell_value, SmiConstant(Map::kPrototypeChainValid)), &done, miss); BIND(&done); @@ -1353,9 +1374,11 @@ void AccessorAssembler::HandleStoreAccessor(const StoreICParameters* p, Comment("accessor_store"); TNode<IntPtrT> descriptor = Signed(DecodeWord<StoreHandler::DescriptorBits>(handler_word)); - Node* accessor_pair = LoadDescriptorValue(LoadMap(holder), descriptor); + TNode<HeapObject> accessor_pair = + CAST(LoadDescriptorValue(LoadMap(holder), descriptor)); CSA_ASSERT(this, IsAccessorPair(accessor_pair)); - Node* setter = LoadObjectField(accessor_pair, AccessorPair::kSetterOffset); + TNode<Object> setter = + LoadObjectField(accessor_pair, AccessorPair::kSetterOffset); CSA_ASSERT(this, Word32BinaryNot(IsTheHole(setter))); Callable callable = CodeFactory::Call(isolate()); @@ -1402,7 +1425,7 @@ void AccessorAssembler::HandleStoreICProtoHandler( p, handler, on_code_handler, // on_found_on_receiver [=](Node* properties, Node* name_index) { - Node* details = + TNode<Uint32T> details = LoadDetailsByKeyIndex<NameDictionary>(properties, name_index); // Check that the property is a writable data property (no accessor). const int kTypeAndReadOnlyMask = @@ -1422,15 +1445,16 @@ void AccessorAssembler::HandleStoreICProtoHandler( if_accessor(this), if_native_data_property(this); CSA_ASSERT(this, TaggedIsSmi(smi_handler)); - Node* handler_word = SmiUntag(smi_handler); + TNode<IntPtrT> handler_word = SmiUntag(smi_handler); - Node* handler_kind = DecodeWord<StoreHandler::KindBits>(handler_word); + TNode<UintPtrT> handler_kind = + DecodeWord<StoreHandler::KindBits>(handler_word); GotoIf(WordEqual(handler_kind, IntPtrConstant(StoreHandler::kNormal)), &if_add_normal); TNode<MaybeObject> maybe_holder = LoadHandlerDataField(handler, 1); CSA_ASSERT(this, IsWeakOrCleared(maybe_holder)); - TNode<Object> holder = GetHeapObjectAssumeWeak(maybe_holder, miss); + TNode<HeapObject> holder = GetHeapObjectAssumeWeak(maybe_holder, miss); GotoIf(WordEqual(handler_kind, IntPtrConstant(StoreHandler::kGlobalProxy)), &if_store_global_proxy); @@ -1497,11 +1521,11 @@ void AccessorAssembler::HandleStoreICProtoHandler( IsCleared(maybe_context), [=] { return SmiConstant(0); }, [=] { return GetHeapObjectAssumeWeak(maybe_context); }); - Node* foreign = LoadObjectField(call_handler_info, - CallHandlerInfo::kJsCallbackOffset); + TNode<Foreign> foreign = CAST(LoadObjectField( + call_handler_info, CallHandlerInfo::kJsCallbackOffset)); Node* callback = LoadObjectField(foreign, Foreign::kForeignAddressOffset, MachineType::Pointer()); - Node* data = + TNode<Object> data = LoadObjectField(call_handler_info, CallHandlerInfo::kDataOffset); VARIABLE(api_holder, MachineRepresentation::kTagged, p->receiver()); @@ -1560,7 +1584,8 @@ void AccessorAssembler::HandleStoreToProxy(const StoreICParameters* p, TailCallRuntime(Runtime::kSetPropertyWithReceiver, p->context(), proxy, p->name(), p->value(), p->receiver()); } else { - Node* name = CallBuiltin(Builtins::kToName, p->context(), p->name()); + TNode<Object> name = + CallBuiltin(Builtins::kToName, p->context(), p->name()); TailCallBuiltin(Builtins::kProxySetProperty, p->context(), proxy, name, p->value(), p->receiver()); } @@ -1571,7 +1596,8 @@ void AccessorAssembler::HandleStoreICSmiHandlerCase(Node* handler_word, Label* miss) { Comment("field store"); #ifdef DEBUG - Node* handler_kind = DecodeWord<StoreHandler::KindBits>(handler_word); + TNode<UintPtrT> handler_kind = + DecodeWord<StoreHandler::KindBits>(handler_word); CSA_ASSERT( this, Word32Or( @@ -1579,7 +1605,7 @@ void AccessorAssembler::HandleStoreICSmiHandlerCase(Node* handler_word, WordEqual(handler_kind, IntPtrConstant(StoreHandler::kConstField)))); #endif - Node* field_representation = + TNode<UintPtrT> field_representation = DecodeWord<StoreHandler::FieldRepresentationBits>(handler_word); Label if_smi_field(this), if_double_field(this), if_heap_object_field(this), @@ -1674,8 +1700,9 @@ Node* AccessorAssembler::PrepareValueForStore(Node* handler_word, Node* holder, GotoIf(TaggedIsSmi(maybe_field_type), &done); // Check that value type matches the field type. { - Node* field_type = GetHeapObjectAssumeWeak(maybe_field_type, bailout); - Branch(WordEqual(LoadMap(value), field_type), &done, bailout); + TNode<HeapObject> field_type = + GetHeapObjectAssumeWeak(maybe_field_type, bailout); + Branch(TaggedEqual(LoadMap(CAST(value)), field_type), &done, bailout); } BIND(&done); @@ -1700,7 +1727,8 @@ Node* AccessorAssembler::ExtendPropertiesBackingStore(Node* object, VARIABLE(var_encoded_hash, MachineRepresentation::kWord32); VARIABLE(var_length, ParameterRepresentation(mode)); - Node* properties = LoadObjectField(object, JSObject::kPropertiesOrHashOffset); + TNode<Object> properties = + LoadObjectField(object, JSObject::kPropertiesOrHashOffset); var_properties.Bind(properties); Label if_smi_hash(this), if_property_array(this), extend_store(this); @@ -1708,8 +1736,8 @@ Node* AccessorAssembler::ExtendPropertiesBackingStore(Node* object, BIND(&if_smi_hash); { - Node* hash = SmiToInt32(properties); - Node* encoded_hash = + TNode<Int32T> hash = SmiToInt32(CAST(properties)); + TNode<Word32T> encoded_hash = Word32Shl(hash, Int32Constant(PropertyArray::HashField::kShift)); var_encoded_hash.Bind(encoded_hash); var_length.Bind(IntPtrOrSmiConstant(0, mode)); @@ -1719,11 +1747,11 @@ Node* AccessorAssembler::ExtendPropertiesBackingStore(Node* object, BIND(&if_property_array); { - Node* length_and_hash_int32 = LoadAndUntagToWord32ObjectField( + TNode<Int32T> length_and_hash_int32 = LoadAndUntagToWord32ObjectField( var_properties.value(), PropertyArray::kLengthAndHashOffset); var_encoded_hash.Bind(Word32And( length_and_hash_int32, Int32Constant(PropertyArray::HashField::kMask))); - Node* length_intptr = ChangeInt32ToIntPtr( + TNode<IntPtrT> length_intptr = ChangeInt32ToIntPtr( Word32And(length_and_hash_int32, Int32Constant(PropertyArray::LengthField::kMask))); Node* length = IntPtrToParameter(length_intptr, mode); @@ -1771,10 +1799,10 @@ Node* AccessorAssembler::ExtendPropertiesBackingStore(Node* object, // TODO(gsathya): Clean up the type conversions by creating smarter // helpers that do the correct op based on the mode. - Node* new_capacity_int32 = + TNode<Int32T> new_capacity_int32 = TruncateIntPtrToInt32(ParameterToIntPtr(new_capacity, mode)); - Node* new_length_and_hash_int32 = - Word32Or(var_encoded_hash.value(), new_capacity_int32); + TNode<Int32T> new_length_and_hash_int32 = + Signed(Word32Or(var_encoded_hash.value(), new_capacity_int32)); StoreObjectField(new_properties, PropertyArray::kLengthAndHashOffset, SmiFromInt32(new_length_and_hash_int32)); StoreObjectField(object, JSObject::kPropertiesOrHashOffset, new_properties); @@ -1795,7 +1823,8 @@ void AccessorAssembler::StoreNamedField(Node* handler_word, Node* object, property_storage = LoadFastProperties(object); } - Node* index = DecodeWord<StoreHandler::FieldIndexBits>(handler_word); + TNode<UintPtrT> index = + DecodeWord<StoreHandler::FieldIndexBits>(handler_word); TNode<IntPtrT> offset = Signed(TimesTaggedSize(index)); if (representation.IsDouble()) { if (!FLAG_unbox_double_fields || !is_inobject) { @@ -1818,8 +1847,9 @@ void AccessorAssembler::StoreNamedField(Node* handler_word, Node* object, BranchIfSameNumberValue(current_value, UncheckedCast<Float64T>(value), &const_checked, bailout); } else { - Node* current_value = LoadObjectField(property_storage, offset); - Branch(WordEqual(current_value, value), &const_checked, bailout); + TNode<Object> current_value = LoadObjectField(property_storage, offset); + Branch(TaggedEqual(current_value, UncheckedCast<Object>(value)), + &const_checked, bailout); } } @@ -1859,42 +1889,44 @@ void AccessorAssembler::EmitFastElementsBoundsCheck(Node* object, } void AccessorAssembler::EmitElementLoad( - Node* object, Node* elements_kind, SloppyTNode<IntPtrT> intptr_index, - Node* is_jsarray_condition, Label* if_hole, Label* rebox_double, - Variable* var_double_value, Label* unimplemented_elements_kind, - Label* out_of_bounds, Label* miss, ExitPoint* exit_point, - LoadAccessMode access_mode) { + Node* object, TNode<Word32T> elements_kind, + SloppyTNode<IntPtrT> intptr_index, Node* is_jsarray_condition, + Label* if_hole, Label* rebox_double, Variable* var_double_value, + Label* unimplemented_elements_kind, Label* out_of_bounds, Label* miss, + ExitPoint* exit_point, LoadAccessMode access_mode) { Label if_typed_array(this), if_fast(this), if_fast_packed(this), if_fast_holey(this), if_fast_double(this), if_fast_holey_double(this), if_nonfast(this), if_dictionary(this); - Branch( - Int32GreaterThan(elements_kind, Int32Constant(LAST_FROZEN_ELEMENTS_KIND)), - &if_nonfast, &if_fast); + Branch(Int32GreaterThan(elements_kind, + Int32Constant(LAST_ANY_NONEXTENSIBLE_ELEMENTS_KIND)), + &if_nonfast, &if_fast); BIND(&if_fast); { TNode<FixedArrayBase> elements = LoadJSObjectElements(CAST(object)); EmitFastElementsBoundsCheck(object, elements, intptr_index, is_jsarray_condition, out_of_bounds); - int32_t kinds[] = {// Handled by if_fast_packed. - PACKED_SMI_ELEMENTS, PACKED_ELEMENTS, - PACKED_SEALED_ELEMENTS, PACKED_FROZEN_ELEMENTS, - // Handled by if_fast_holey. - HOLEY_SMI_ELEMENTS, HOLEY_ELEMENTS, - HOLEY_FROZEN_ELEMENTS, HOLEY_SEALED_ELEMENTS, - // Handled by if_fast_double. - PACKED_DOUBLE_ELEMENTS, - // Handled by if_fast_holey_double. - HOLEY_DOUBLE_ELEMENTS}; - Label* labels[] = { - // FAST_{SMI,}_ELEMENTS - &if_fast_packed, &if_fast_packed, &if_fast_packed, &if_fast_packed, - // FAST_HOLEY_{SMI,}_ELEMENTS - &if_fast_holey, &if_fast_holey, &if_fast_holey, &if_fast_holey, - // PACKED_DOUBLE_ELEMENTS - &if_fast_double, - // HOLEY_DOUBLE_ELEMENTS - &if_fast_holey_double}; + int32_t kinds[] = { + // Handled by if_fast_packed. + PACKED_SMI_ELEMENTS, PACKED_ELEMENTS, PACKED_NONEXTENSIBLE_ELEMENTS, + PACKED_SEALED_ELEMENTS, PACKED_FROZEN_ELEMENTS, + // Handled by if_fast_holey. + HOLEY_SMI_ELEMENTS, HOLEY_ELEMENTS, HOLEY_NONEXTENSIBLE_ELEMENTS, + HOLEY_FROZEN_ELEMENTS, HOLEY_SEALED_ELEMENTS, + // Handled by if_fast_double. + PACKED_DOUBLE_ELEMENTS, + // Handled by if_fast_holey_double. + HOLEY_DOUBLE_ELEMENTS}; + Label* labels[] = {// FAST_{SMI,}_ELEMENTS + &if_fast_packed, &if_fast_packed, &if_fast_packed, + &if_fast_packed, &if_fast_packed, + // FAST_HOLEY_{SMI,}_ELEMENTS + &if_fast_holey, &if_fast_holey, &if_fast_holey, + &if_fast_holey, &if_fast_holey, + // PACKED_DOUBLE_ELEMENTS + &if_fast_double, + // HOLEY_DOUBLE_ELEMENTS + &if_fast_holey_double}; Switch(elements_kind, unimplemented_elements_kind, kinds, labels, arraysize(kinds)); @@ -1910,8 +1942,9 @@ void AccessorAssembler::EmitElementLoad( BIND(&if_fast_holey); { Comment("fast holey elements"); - Node* element = UnsafeLoadFixedArrayElement(CAST(elements), intptr_index); - GotoIf(WordEqual(element, TheHoleConstant()), if_hole); + TNode<Object> element = + UnsafeLoadFixedArrayElement(CAST(elements), intptr_index); + GotoIf(TaggedEqual(element, TheHoleConstant()), if_hole); exit_point->Return(access_mode == LoadAccessMode::kHas ? TrueConstant() : element); } @@ -1931,9 +1964,9 @@ void AccessorAssembler::EmitElementLoad( BIND(&if_fast_holey_double); { Comment("holey double elements"); - Node* value = LoadFixedDoubleArrayElement(CAST(elements), intptr_index, - MachineType::Float64(), 0, - INTPTR_PARAMETERS, if_hole); + TNode<Float64T> value = LoadFixedDoubleArrayElement( + CAST(elements), intptr_index, MachineType::Float64(), 0, + INTPTR_PARAMETERS, if_hole); if (access_mode == LoadAccessMode::kHas) { exit_point->Return(TrueConstant()); } else { @@ -2020,35 +2053,35 @@ void AccessorAssembler::EmitElementLoad( BIND(&uint16_elements); { Comment("UINT16_ELEMENTS"); - Node* index = WordShl(intptr_index, IntPtrConstant(1)); + TNode<IntPtrT> index = WordShl(intptr_index, IntPtrConstant(1)); Node* element = Load(MachineType::Uint16(), backing_store, index); exit_point->Return(SmiFromInt32(element)); } BIND(&int16_elements); { Comment("INT16_ELEMENTS"); - Node* index = WordShl(intptr_index, IntPtrConstant(1)); + TNode<IntPtrT> index = WordShl(intptr_index, IntPtrConstant(1)); Node* element = Load(MachineType::Int16(), backing_store, index); exit_point->Return(SmiFromInt32(element)); } BIND(&uint32_elements); { Comment("UINT32_ELEMENTS"); - Node* index = WordShl(intptr_index, IntPtrConstant(2)); + TNode<IntPtrT> index = WordShl(intptr_index, IntPtrConstant(2)); Node* element = Load(MachineType::Uint32(), backing_store, index); exit_point->Return(ChangeUint32ToTagged(element)); } BIND(&int32_elements); { Comment("INT32_ELEMENTS"); - Node* index = WordShl(intptr_index, IntPtrConstant(2)); + TNode<IntPtrT> index = WordShl(intptr_index, IntPtrConstant(2)); Node* element = Load(MachineType::Int32(), backing_store, index); exit_point->Return(ChangeInt32ToTagged(element)); } BIND(&float32_elements); { Comment("FLOAT32_ELEMENTS"); - Node* index = WordShl(intptr_index, IntPtrConstant(2)); + TNode<IntPtrT> index = WordShl(intptr_index, IntPtrConstant(2)); Node* element = Load(MachineType::Float32(), backing_store, index); var_double_value->Bind(ChangeFloat32ToFloat64(element)); Goto(rebox_double); @@ -2056,7 +2089,7 @@ void AccessorAssembler::EmitElementLoad( BIND(&float64_elements); { Comment("FLOAT64_ELEMENTS"); - Node* index = WordShl(intptr_index, IntPtrConstant(3)); + TNode<IntPtrT> index = WordShl(intptr_index, IntPtrConstant(3)); Node* element = Load(MachineType::Float64(), backing_store, index); var_double_value->Bind(element); Goto(rebox_double); @@ -2105,12 +2138,12 @@ void AccessorAssembler::InvalidateValidityCellIfPrototype(Node* map, BIND(&is_prototype); { - Node* maybe_prototype_info = + TNode<Object> maybe_prototype_info = LoadObjectField(map, Map::kTransitionsOrPrototypeInfoOffset); // If there's no prototype info then there's nothing to invalidate. GotoIf(TaggedIsSmi(maybe_prototype_info), &cont); - Node* function = ExternalConstant( + TNode<ExternalReference> function = ExternalConstant( ExternalReference::invalidate_prototype_chains_function()); CallCFunction(function, MachineType::AnyTagged(), std::make_pair(MachineType::AnyTagged(), map)); @@ -2130,8 +2163,9 @@ void AccessorAssembler::GenericElementLoad(Node* receiver, Node* receiver_map, // Receivers requiring non-standard element accesses (interceptors, access // checks, strings and string wrappers, proxies) are handled in the runtime. GotoIf(IsCustomElementsReceiverInstanceType(instance_type), &if_custom); - Node* elements_kind = LoadMapElementsKind(receiver_map); - Node* is_jsarray_condition = InstanceTypeEqual(instance_type, JS_ARRAY_TYPE); + TNode<Int32T> elements_kind = LoadMapElementsKind(receiver_map); + TNode<BoolT> is_jsarray_condition = + InstanceTypeEqual(instance_type, JS_ARRAY_TYPE); VARIABLE(var_double_value, MachineRepresentation::kFloat64); Label rebox_double(this, &var_double_value); @@ -2192,12 +2226,14 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, VARIABLE(var_details, MachineRepresentation::kWord32); VARIABLE(var_value, MachineRepresentation::kTagged); + TNode<Name> name = CAST(p->name()); + // Receivers requiring non-standard accesses (interceptors, access // checks, strings and string wrappers) are handled in the runtime. GotoIf(IsSpecialReceiverInstanceType(instance_type), &special_receiver); // Check if the receiver has fast or slow properties. - Node* bitfield3 = LoadMapBitField3(receiver_map); + TNode<Uint32T> bitfield3 = LoadMapBitField3(receiver_map); GotoIf(IsSetWord32<Map::IsDictionaryMapBit>(bitfield3), &if_property_dictionary); @@ -2209,7 +2245,7 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, TVARIABLE(IntPtrT, var_name_index); Label* notfound = use_stub_cache == kUseStubCache ? &try_stub_cache : &lookup_prototype_chain; - DescriptorLookup(p->name(), descriptors, bitfield3, &if_descriptor_found, + DescriptorLookup(name, descriptors, bitfield3, &if_descriptor_found, &var_name_index, notfound); BIND(&if_descriptor_found); @@ -2226,13 +2262,13 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, // When there is no feedback vector don't use stub cache. GotoIfNot(IsUndefined(p->vector()), &stub_cache); // Fall back to the slow path for private symbols. - Branch(IsPrivateSymbol(p->name()), slow, &lookup_prototype_chain); + Branch(IsPrivateSymbol(name), slow, &lookup_prototype_chain); BIND(&stub_cache); Comment("stub cache probe for fast property load"); TVARIABLE(MaybeObject, var_handler); Label found_handler(this, &var_handler), stub_cache_miss(this); - TryProbeStubCache(isolate()->load_stub_cache(), receiver, p->name(), + TryProbeStubCache(isolate()->load_stub_cache(), receiver, name, &found_handler, &var_handler, &stub_cache_miss); BIND(&found_handler); { @@ -2247,7 +2283,7 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, // chain. If it doesn't, then there's no point in missing. Comment("KeyedLoadGeneric_miss"); TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context(), p->receiver(), - p->name(), p->slot(), p->vector()); + name, p->slot(), p->vector()); } } @@ -2260,8 +2296,8 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, TVARIABLE(IntPtrT, var_name_index); Label dictionary_found(this, &var_name_index); TNode<NameDictionary> properties = CAST(LoadSlowProperties(receiver)); - NameDictionaryLookup<NameDictionary>(properties, CAST(p->name()), - &dictionary_found, &var_name_index, + NameDictionaryLookup<NameDictionary>(properties, name, &dictionary_found, + &var_name_index, &lookup_prototype_chain); BIND(&dictionary_found); { @@ -2273,8 +2309,8 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, BIND(&if_found_on_receiver); { - Node* value = CallGetterIfAccessor(var_value.value(), var_details.value(), - p->context(), receiver, slow); + TNode<Object> value = CallGetterIfAccessor( + var_value.value(), var_details.value(), p->context(), receiver, slow); IncrementCounter(isolate()->counters()->ic_keyed_load_generic_symbol(), 1); Return(value); } @@ -2289,7 +2325,7 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, var_holder_map.Bind(receiver_map); var_holder_instance_type.Bind(instance_type); - GotoIf(IsPrivateSymbol(p->name()), &is_private_symbol); + GotoIf(IsPrivateSymbol(name), &is_private_symbol); Goto(&loop); BIND(&loop); @@ -2298,16 +2334,16 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, GotoIf(InstanceTypeEqual(var_holder_instance_type.value(), JS_TYPED_ARRAY_TYPE), slow); - Node* proto = LoadMapPrototype(var_holder_map.value()); - GotoIf(WordEqual(proto, NullConstant()), &return_undefined); - Node* proto_map = LoadMap(proto); - Node* proto_instance_type = LoadMapInstanceType(proto_map); + TNode<HeapObject> proto = LoadMapPrototype(var_holder_map.value()); + GotoIf(TaggedEqual(proto, NullConstant()), &return_undefined); + TNode<Map> proto_map = LoadMap(proto); + TNode<Uint16T> proto_instance_type = LoadMapInstanceType(proto_map); var_holder_map.Bind(proto_map); var_holder_instance_type.Bind(proto_instance_type); Label next_proto(this), return_value(this, &var_value), goto_slow(this); TryGetOwnProperty(p->context(), receiver, proto, proto_map, - proto_instance_type, p->name(), &return_value, - &var_value, &next_proto, &goto_slow); + proto_instance_type, name, &return_value, &var_value, + &next_proto, &goto_slow); // This trampoline and the next are required to appease Turbofan's // variable merging. @@ -2323,12 +2359,12 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, BIND(&is_private_symbol); { - CSA_ASSERT(this, IsPrivateSymbol(p->name())); + CSA_ASSERT(this, IsPrivateSymbol(name)); // For private names that don't exist on the receiver, we bail // to the runtime to throw. For private symbols, we just return // undefined. - Branch(IsPrivateName(p->name()), slow, &return_undefined); + Branch(IsPrivateName(CAST(name)), slow, &return_undefined); } BIND(&return_undefined); @@ -2341,11 +2377,11 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, GotoIfNot(InstanceTypeEqual(instance_type, JS_PROXY_TYPE), slow); // Private field/symbol lookup is not supported. - GotoIf(IsPrivateSymbol(p->name()), slow); + GotoIf(IsPrivateSymbol(name), slow); direct_exit.ReturnCallStub( Builtins::CallableFor(isolate(), Builtins::kProxyGetProperty), - p->context(), receiver /*holder is the same as receiver*/, p->name(), + p->context(), receiver /*holder is the same as receiver*/, name, receiver, SmiConstant(OnNonExistent::kReturnUndefined)); } } @@ -2361,7 +2397,7 @@ Node* AccessorAssembler::StubCachePrimaryOffset(Node* name, Node* map) { // See v8::internal::StubCache::PrimaryOffset(). STATIC_ASSERT(StubCache::kCacheIndexShift == Name::kHashShift); // Compute the hash of the name (use entire hash field). - Node* hash_field = LoadNameHashField(name); + TNode<Uint32T> hash_field = LoadNameHashField(name); CSA_ASSERT(this, Word32Equal(Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), @@ -2370,12 +2406,12 @@ Node* AccessorAssembler::StubCachePrimaryOffset(Node* name, Node* map) { // Using only the low bits in 64-bit mode is unlikely to increase the // risk of collision even if the heap is spread over an area larger than // 4Gb (and not at all if it isn't). - Node* map_word = BitcastTaggedToWord(map); + TNode<IntPtrT> map_word = BitcastTaggedToWord(map); - Node* map32 = TruncateIntPtrToInt32(UncheckedCast<IntPtrT>( + TNode<Int32T> map32 = TruncateIntPtrToInt32(UncheckedCast<IntPtrT>( WordXor(map_word, WordShr(map_word, StubCache::kMapKeyShift)))); // Base the offset on a simple combination of name and map. - Node* hash = Int32Add(hash_field, map32); + TNode<Word32T> hash = Int32Add(hash_field, map32); uint32_t mask = (StubCache::kPrimaryTableSize - 1) << StubCache::kCacheIndexShift; return ChangeUint32ToWord(Word32And(hash, Int32Constant(mask))); @@ -2385,8 +2421,8 @@ Node* AccessorAssembler::StubCacheSecondaryOffset(Node* name, Node* seed) { // See v8::internal::StubCache::SecondaryOffset(). // Use the seed from the primary cache in the secondary cache. - Node* name32 = TruncateIntPtrToInt32(BitcastTaggedToWord(name)); - Node* hash = Int32Sub(TruncateIntPtrToInt32(seed), name32); + TNode<Int32T> name32 = TruncateIntPtrToInt32(BitcastTaggedToWord(name)); + TNode<Word32T> hash = Int32Sub(TruncateIntPtrToInt32(seed), name32); hash = Int32Add(hash, Int32Constant(StubCache::kSecondaryMagic)); int32_t mask = (StubCache::kSecondaryTableSize - 1) << StubCache::kCacheIndexShift; @@ -2395,7 +2431,7 @@ Node* AccessorAssembler::StubCacheSecondaryOffset(Node* name, Node* seed) { void AccessorAssembler::TryProbeStubCacheTable( StubCache* stub_cache, StubCacheTable table_id, Node* entry_offset, - Node* name, Node* map, Label* if_handler, + TNode<Object> name, TNode<Map> map, Label* if_handler, TVariable<MaybeObject>* var_handler, Label* if_miss) { StubCache::Table table = static_cast<StubCache::Table>(table_id); // The {table_offset} holds the entry offset times four (due to masking @@ -2403,19 +2439,20 @@ void AccessorAssembler::TryProbeStubCacheTable( const int kMultiplier = sizeof(StubCache::Entry) >> Name::kHashShift; entry_offset = IntPtrMul(entry_offset, IntPtrConstant(kMultiplier)); - Node* key_base = ExternalConstant( + TNode<ExternalReference> key_base = ExternalConstant( ExternalReference::Create(stub_cache->key_reference(table))); // Check that the key in the entry matches the name. DCHECK_EQ(0, offsetof(StubCache::Entry, key)); - Node* cached_key = Load(MachineType::TaggedPointer(), key_base, entry_offset); - GotoIf(WordNotEqual(name, cached_key), if_miss); + TNode<HeapObject> cached_key = + CAST(Load(MachineType::TaggedPointer(), key_base, entry_offset)); + GotoIf(TaggedNotEqual(name, cached_key), if_miss); // Check that the map in the entry matches. - Node* cached_map = Load( - MachineType::TaggedPointer(), key_base, + TNode<Object> cached_map = Load<Object>( + key_base, IntPtrAdd(entry_offset, IntPtrConstant(offsetof(StubCache::Entry, map)))); - GotoIf(WordNotEqual(map, cached_map), if_miss); + GotoIf(TaggedNotEqual(map, cached_map), if_miss); TNode<MaybeObject> handler = ReinterpretCast<MaybeObject>( Load(MachineType::AnyTagged(), key_base, @@ -2428,7 +2465,7 @@ void AccessorAssembler::TryProbeStubCacheTable( } void AccessorAssembler::TryProbeStubCache(StubCache* stub_cache, Node* receiver, - Node* name, Label* if_handler, + TNode<Object> name, Label* if_handler, TVariable<MaybeObject>* var_handler, Label* if_miss) { Label try_secondary(this), miss(this); @@ -2439,7 +2476,7 @@ void AccessorAssembler::TryProbeStubCache(StubCache* stub_cache, Node* receiver, // Check that the {receiver} isn't a smi. GotoIf(TaggedIsSmi(receiver), &miss); - Node* receiver_map = LoadMap(receiver); + TNode<Map> receiver_map = LoadMap(receiver); // Probe the primary table. Node* primary_offset = StubCachePrimaryOffset(name, receiver_map); @@ -2477,7 +2514,7 @@ void AccessorAssembler::LoadIC_BytecodeHandler(const LazyLoadICParameters* p, Label stub_call(this, Label::kDeferred), miss(this, Label::kDeferred), no_feedback(this, Label::kDeferred); - Node* recv_map = LoadReceiverMap(p->receiver()); + TNode<Map> recv_map = LoadReceiverMap(p->receiver()); GotoIf(IsDeprecatedMap(recv_map), &miss); GotoIf(IsUndefined(p->vector()), &no_feedback); @@ -2513,7 +2550,7 @@ void AccessorAssembler::LoadIC_BytecodeHandler(const LazyLoadICParameters* p, // Call into the stub that implements the non-inlined parts of LoadIC. Callable ic = Builtins::CallableFor(isolate(), Builtins::kLoadIC_Noninlined); - Node* code_target = HeapConstant(ic.code()); + TNode<Code> code_target = HeapConstant(ic.code()); exit_point->ReturnCallStub(ic.descriptor(), code_target, p->context(), p->receiver(), p->name(), p->slot(), p->vector()); @@ -2524,8 +2561,8 @@ void AccessorAssembler::LoadIC_BytecodeHandler(const LazyLoadICParameters* p, Comment("LoadIC_BytecodeHandler_nofeedback"); // Call into the stub that implements the non-inlined parts of LoadIC. exit_point->ReturnCallStub( - Builtins::CallableFor(isolate(), Builtins::kLoadIC_Uninitialized), - p->context(), p->receiver(), p->name(), p->slot(), p->vector()); + Builtins::CallableFor(isolate(), Builtins::kLoadIC_NoFeedback), + p->context(), p->receiver(), p->name(), p->slot()); } BIND(&miss); @@ -2547,7 +2584,7 @@ void AccessorAssembler::LoadIC(const LoadICParameters* p) { Label if_handler(this, &var_handler), non_inlined(this, Label::kDeferred), try_polymorphic(this), miss(this, Label::kDeferred); - Node* receiver_map = LoadReceiverMap(p->receiver()); + TNode<Map> receiver_map = LoadReceiverMap(p->receiver()); GotoIf(IsDeprecatedMap(receiver_map), &miss); // Check monomorphic case. @@ -2584,58 +2621,34 @@ void AccessorAssembler::LoadIC(const LoadICParameters* p) { } void AccessorAssembler::LoadIC_Noninlined(const LoadICParameters* p, - Node* receiver_map, + TNode<Map> receiver_map, TNode<HeapObject> feedback, TVariable<MaybeObject>* var_handler, Label* if_handler, Label* miss, ExitPoint* exit_point) { - Label try_uninitialized(this, Label::kDeferred); - // Neither deprecated map nor monomorphic. These cases are handled in the // bytecode handler. CSA_ASSERT(this, Word32BinaryNot(IsDeprecatedMap(receiver_map))); - CSA_ASSERT(this, WordNotEqual(receiver_map, feedback)); + CSA_ASSERT(this, TaggedNotEqual(receiver_map, feedback)); CSA_ASSERT(this, Word32BinaryNot(IsWeakFixedArrayMap(LoadMap(feedback)))); DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); { // Check megamorphic case. - GotoIfNot(WordEqual(feedback, LoadRoot(RootIndex::kmegamorphic_symbol)), - &try_uninitialized); + GotoIfNot(TaggedEqual(feedback, MegamorphicSymbolConstant()), miss); TryProbeStubCache(isolate()->load_stub_cache(), p->receiver(), p->name(), if_handler, var_handler, miss); } - - BIND(&try_uninitialized); - { - // Check uninitialized case. - GotoIfNot(WordEqual(feedback, LoadRoot(RootIndex::kuninitialized_symbol)), - miss); - exit_point->ReturnCallStub( - Builtins::CallableFor(isolate(), Builtins::kLoadIC_Uninitialized), - p->context(), p->receiver(), p->name(), p->slot(), p->vector()); - } } -void AccessorAssembler::LoadIC_Uninitialized(const LoadICParameters* p) { - Label miss(this, Label::kDeferred), - check_function_prototype(this); +void AccessorAssembler::LoadIC_NoFeedback(const LoadICParameters* p) { + Label miss(this, Label::kDeferred); Node* receiver = p->receiver(); GotoIf(TaggedIsSmi(receiver), &miss); - Node* receiver_map = LoadMap(receiver); - Node* instance_type = LoadMapInstanceType(receiver_map); - - GotoIf(IsUndefined(p->vector()), &check_function_prototype); - // Optimistically write the state transition to the vector. - StoreFeedbackVectorSlot(p->vector(), p->slot(), - LoadRoot(RootIndex::kpremonomorphic_symbol), - SKIP_WRITE_BARRIER, 0, SMI_PARAMETERS); - StoreWeakReferenceInFeedbackVector(p->vector(), p->slot(), receiver_map, - kTaggedSize, SMI_PARAMETERS); - Goto(&check_function_prototype); + TNode<Map> receiver_map = LoadMap(receiver); + TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map); - BIND(&check_function_prototype); { // Special case for Function.prototype load, because it's very common // for ICs that are only executed once (MyFunc.prototype.foo = ...). @@ -2644,9 +2657,9 @@ void AccessorAssembler::LoadIC_Uninitialized(const LoadICParameters* p) { ¬_function_prototype); GotoIfNot(IsPrototypeString(p->name()), ¬_function_prototype); - GotoIfPrototypeRequiresRuntimeLookup(CAST(receiver), CAST(receiver_map), + GotoIfPrototypeRequiresRuntimeLookup(CAST(receiver), receiver_map, ¬_function_prototype); - Return(LoadJSFunctionPrototype(receiver, &miss)); + Return(LoadJSFunctionPrototype(CAST(receiver), &miss)); BIND(¬_function_prototype); } @@ -2655,15 +2668,6 @@ void AccessorAssembler::LoadIC_Uninitialized(const LoadICParameters* p) { BIND(&miss); { - Label call_runtime(this, Label::kDeferred); - GotoIf(IsUndefined(p->vector()), &call_runtime); - // Undo the optimistic state transition. - StoreFeedbackVectorSlot(p->vector(), p->slot(), - LoadRoot(RootIndex::kuninitialized_symbol), - SKIP_WRITE_BARRIER, 0, SMI_PARAMETERS); - Goto(&call_runtime); - - BIND(&call_runtime); TailCallRuntime(Runtime::kLoadIC_Miss, p->context(), p->receiver(), p->name(), p->slot(), p->vector()); } @@ -2715,7 +2719,7 @@ void AccessorAssembler::LoadGlobalIC_TryPropertyCellCase( CAST(GetHeapObjectAssumeWeak(maybe_weak_ref, try_handler)); TNode<Object> value = LoadObjectField(property_cell, PropertyCell::kValueOffset); - GotoIf(WordEqual(value, TheHoleConstant()), miss); + GotoIf(TaggedEqual(value, TheHoleConstant()), miss); exit_point->Return(value); } @@ -2746,7 +2750,7 @@ void AccessorAssembler::LoadGlobalIC_TryHandlerCase( TNode<MaybeObject> feedback_element = LoadFeedbackVectorSlot(vector, slot, kTaggedSize, slot_mode); TNode<Object> handler = CAST(feedback_element); - GotoIf(WordEqual(handler, LoadRoot(RootIndex::kuninitialized_symbol)), miss); + GotoIf(TaggedEqual(handler, UninitializedSymbolConstant()), miss); OnNonExistent on_nonexistent = typeof_mode == NOT_INSIDE_TYPEOF ? OnNonExistent::kThrowReferenceError @@ -2756,7 +2760,8 @@ void AccessorAssembler::LoadGlobalIC_TryHandlerCase( TNode<Context> native_context = LoadNativeContext(context); TNode<JSGlobalProxy> receiver = CAST(LoadContextElement(native_context, Context::GLOBAL_PROXY_INDEX)); - Node* holder = LoadContextElement(native_context, Context::EXTENSION_INDEX); + TNode<Object> holder = + LoadContextElement(native_context, Context::EXTENSION_INDEX); LazyLoadICParameters p([=] { return context; }, receiver, lazy_name, ParameterToTagged(slot, slot_mode), vector, holder); @@ -2772,10 +2777,11 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p, TVARIABLE(MaybeObject, var_handler); Label if_handler(this, &var_handler), try_polymorphic(this, Label::kDeferred), try_megamorphic(this, Label::kDeferred), + try_uninitialized(this, Label::kDeferred), try_polymorphic_name(this, Label::kDeferred), miss(this, Label::kDeferred), generic(this, Label::kDeferred); - Node* receiver_map = LoadReceiverMap(p->receiver()); + TNode<Map> receiver_map = LoadReceiverMap(p->receiver()); GotoIf(IsDeprecatedMap(receiver_map), &miss); GotoIf(IsUndefined(p->vector()), &generic); @@ -2807,8 +2813,8 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p, { // Check megamorphic case. Comment("KeyedLoadIC_try_megamorphic"); - Branch(WordEqual(strong_feedback, LoadRoot(RootIndex::kmegamorphic_symbol)), - &generic, &try_polymorphic_name); + Branch(TaggedEqual(strong_feedback, MegamorphicSymbolConstant()), &generic, + &try_uninitialized); } BIND(&generic); @@ -2821,42 +2827,49 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p, p->vector()); } + BIND(&try_uninitialized); + { + // Check uninitialized case. + Comment("KeyedLoadIC_try_uninitialized"); + Branch(TaggedEqual(strong_feedback, UninitializedSymbolConstant()), &miss, + &try_polymorphic_name); + } + BIND(&try_polymorphic_name); { // We might have a name in feedback, and a weak fixed array in the next // slot. - Node* name = p->name(); Comment("KeyedLoadIC_try_polymorphic_name"); - VARIABLE(var_name, MachineRepresentation::kTagged, name); - VARIABLE(var_index, MachineType::PointerRepresentation()); + TVARIABLE(Object, var_name, p->name()); + TVARIABLE(IntPtrT, var_index); Label if_polymorphic_name(this, &var_name), if_internalized(this), if_notinternalized(this, Label::kDeferred); // Fast-case: The recorded {feedback} matches the {name}. - GotoIf(WordEqual(strong_feedback, name), &if_polymorphic_name); + GotoIf(TaggedEqual(strong_feedback, p->name()), &if_polymorphic_name); // Try to internalize the {name} if it isn't already. - TryToName(name, &miss, &var_index, &if_internalized, &var_name, &miss, + TryToName(p->name(), &miss, &var_index, &if_internalized, &var_name, &miss, &if_notinternalized); BIND(&if_internalized); { // The {var_name} now contains a unique name. - Branch(WordEqual(strong_feedback, var_name.value()), &if_polymorphic_name, - &miss); + Branch(TaggedEqual(strong_feedback, var_name.value()), + &if_polymorphic_name, &miss); } BIND(&if_notinternalized); { // Try to internalize the {name}. - Node* function = ExternalConstant( + TNode<ExternalReference> function = ExternalConstant( ExternalReference::try_internalize_string_function()); - Node* const isolate_ptr = + TNode<ExternalReference> const isolate_ptr = ExternalConstant(ExternalReference::isolate_address(isolate())); - var_name.Bind( + var_name = CAST( CallCFunction(function, MachineType::AnyTagged(), std::make_pair(MachineType::Pointer(), isolate_ptr), - std::make_pair(MachineType::AnyTagged(), name))); + std::make_pair(MachineType::AnyTagged(), p->name()))); Goto(&if_internalized); } @@ -2864,11 +2877,10 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p, { // If the name comparison succeeded, we know we have a weak fixed array // with at least one map/handler pair. - Node* name = var_name.value(); TailCallBuiltin(access_mode == LoadAccessMode::kLoad ? Builtins::kKeyedLoadIC_PolymorphicName : Builtins::kKeyedHasIC_PolymorphicName, - p->context(), p->receiver(), name, p->slot(), + p->context(), p->receiver(), var_name.value(), p->slot(), p->vector()); } } @@ -2884,8 +2896,8 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p, } void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { - VARIABLE(var_index, MachineType::PointerRepresentation()); - VARIABLE(var_unique, MachineRepresentation::kTagged, p->name()); + TVARIABLE(IntPtrT, var_index); + TVARIABLE(Object, var_unique, p->name()); Label if_index(this), if_unique_name(this), if_notunique(this), if_other(this, Label::kDeferred), if_runtime(this, Label::kDeferred); @@ -2898,16 +2910,17 @@ void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { BIND(&if_other); { - Node* name = CallBuiltin(Builtins::kToName, p->context(), p->name()); - var_unique.Bind(name); + TNode<Name> name = + CAST(CallBuiltin(Builtins::kToName, p->context(), p->name())); + var_unique = name; TryToName(name, &if_index, &var_index, &if_unique_name, &var_unique, &if_runtime, &if_notunique); } BIND(&if_index); { - Node* receiver_map = LoadMap(receiver); - Node* instance_type = LoadMapInstanceType(receiver_map); + TNode<Map> receiver_map = LoadMap(receiver); + TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map); GenericElementLoad(receiver, receiver_map, instance_type, var_index.value(), &if_runtime); } @@ -2915,8 +2928,8 @@ void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { BIND(&if_unique_name); { LoadICParameters pp(p, var_unique.value()); - Node* receiver_map = LoadMap(receiver); - Node* instance_type = LoadMapInstanceType(receiver_map); + TNode<Map> receiver_map = LoadMap(receiver); + TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map); GenericPropertyLoad(receiver, receiver_map, instance_type, &pp, &if_runtime); } @@ -2941,8 +2954,8 @@ void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { // with this have shown that it causes too much traffic on the stub // cache. We may want to re-evaluate that in the future. LoadICParameters pp(p, var_unique.value()); - Node* receiver_map = LoadMap(receiver); - Node* instance_type = LoadMapInstanceType(receiver_map); + TNode<Map> receiver_map = LoadMap(receiver); + TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map); GenericPropertyLoad(receiver, receiver_map, instance_type, &pp, &if_runtime, kDontUseStubCache); } @@ -2967,8 +2980,8 @@ void AccessorAssembler::KeyedLoadICPolymorphicName(const LoadICParameters* p, Label if_handler(this, &var_handler), miss(this, Label::kDeferred); Node* receiver = p->receiver(); - Node* receiver_map = LoadReceiverMap(receiver); - Node* name = p->name(); + TNode<Map> receiver_map = LoadReceiverMap(receiver); + TNode<Name> name = CAST(p->name()); Node* vector = p->vector(); Node* slot = p->slot(); TNode<Context> context = p->context(); @@ -2976,10 +2989,11 @@ void AccessorAssembler::KeyedLoadICPolymorphicName(const LoadICParameters* p, // When we get here, we know that the {name} matches the recorded // feedback name in the {vector} and can safely be used for the // LoadIC handler logic below. - CSA_ASSERT(this, IsName(name)); CSA_ASSERT(this, Word32BinaryNot(IsDeprecatedMap(receiver_map))); - CSA_ASSERT(this, WordEqual(name, CAST(LoadFeedbackVectorSlot( - vector, slot, 0, SMI_PARAMETERS)))); + CSA_ASSERT(this, + TaggedEqual( + name, LoadFeedbackVectorSlot(vector, slot, 0, SMI_PARAMETERS)), + name, vector); // Check if we have a matching handler for the {receiver_map}. TNode<MaybeObject> feedback_element = @@ -3014,11 +3028,10 @@ void AccessorAssembler::StoreIC(const StoreICParameters* p) { Label if_handler(this, &var_handler), if_handler_from_stub_cache(this, &var_handler, Label::kDeferred), try_polymorphic(this, Label::kDeferred), - try_megamorphic(this, Label::kDeferred), - try_uninitialized(this, Label::kDeferred), miss(this, Label::kDeferred), + try_megamorphic(this, Label::kDeferred), miss(this, Label::kDeferred), no_feedback(this, Label::kDeferred); - Node* receiver_map = LoadReceiverMap(p->receiver()); + TNode<Map> receiver_map = LoadReceiverMap(p->receiver()); GotoIf(IsDeprecatedMap(receiver_map), &miss); GotoIf(IsUndefined(p->vector()), &no_feedback); @@ -3047,26 +3060,16 @@ void AccessorAssembler::StoreIC(const StoreICParameters* p) { BIND(&try_megamorphic); { // Check megamorphic case. - GotoIfNot( - WordEqual(strong_feedback, LoadRoot(RootIndex::kmegamorphic_symbol)), - &try_uninitialized); + GotoIfNot(TaggedEqual(strong_feedback, MegamorphicSymbolConstant()), &miss); TryProbeStubCache(isolate()->store_stub_cache(), p->receiver(), p->name(), &if_handler, &var_handler, &miss); } - BIND(&try_uninitialized); - { - // Check uninitialized case. - Branch( - WordEqual(strong_feedback, LoadRoot(RootIndex::kuninitialized_symbol)), - &no_feedback, &miss); - } BIND(&no_feedback); { - TailCallBuiltin(Builtins::kStoreIC_Uninitialized, p->context(), - p->receiver(), p->name(), p->value(), p->slot(), - p->vector()); + TailCallBuiltin(Builtins::kStoreIC_NoFeedback, p->context(), p->receiver(), + p->name(), p->value(), p->slot()); } BIND(&miss); @@ -3085,9 +3088,11 @@ void AccessorAssembler::StoreGlobalIC(const StoreICParameters* pp) { BIND(&if_heapobject); { Label try_handler(this), miss(this, Label::kDeferred); - GotoIf( - WordEqual(maybe_weak_ref, LoadRoot(RootIndex::kpremonomorphic_symbol)), - &miss); + // We use pre-monomorphic state for global stores that run into + // interceptors because the property doesn't exist yet. Using + // pre-monomorphic state gives it a chance to find more information the + // second time. + GotoIf(TaggedEqual(maybe_weak_ref, PremonomorphicSymbolConstant()), &miss); CSA_ASSERT(this, IsWeakOrCleared(maybe_weak_ref)); TNode<PropertyCell> property_cell = @@ -3103,11 +3108,10 @@ void AccessorAssembler::StoreGlobalIC(const StoreICParameters* pp) { TNode<MaybeObject> handler = LoadFeedbackVectorSlot( pp->vector(), pp->slot(), kTaggedSize, SMI_PARAMETERS); - GotoIf(WordEqual(handler, LoadRoot(RootIndex::kuninitialized_symbol)), - &miss); + GotoIf(TaggedEqual(handler, UninitializedSymbolConstant()), &miss); DCHECK_NULL(pp->receiver()); - Node* native_context = LoadNativeContext(pp->context()); + TNode<Context> native_context = LoadNativeContext(pp->context()); StoreICParameters p( pp->context(), LoadContextElement(native_context, Context::GLOBAL_PROXY_INDEX), @@ -3139,7 +3143,7 @@ void AccessorAssembler::StoreGlobalIC(const StoreICParameters* pp) { } void AccessorAssembler::StoreGlobalIC_PropertyCellCase(Node* property_cell, - Node* value, + TNode<Object> value, ExitPoint* exit_point, Label* miss) { Comment("StoreGlobalIC_TryPropertyCellCase"); @@ -3148,16 +3152,17 @@ void AccessorAssembler::StoreGlobalIC_PropertyCellCase(Node* property_cell, // Load the payload of the global parameter cell. A hole indicates that // the cell has been invalidated and that the store must be handled by the // runtime. - Node* cell_contents = + TNode<Object> cell_contents = LoadObjectField(property_cell, PropertyCell::kValueOffset); - Node* details = LoadAndUntagToWord32ObjectField( + TNode<Int32T> details = LoadAndUntagToWord32ObjectField( property_cell, PropertyCell::kPropertyDetailsRawOffset); GotoIf(IsSetWord32(details, PropertyDetails::kAttributesReadOnlyMask), miss); CSA_ASSERT(this, Word32Equal(DecodeWord32<PropertyDetails::KindField>(details), Int32Constant(kData))); - Node* type = DecodeWord32<PropertyDetails::PropertyCellTypeField>(details); + TNode<Uint32T> type = + DecodeWord32<PropertyDetails::PropertyCellTypeField>(details); Label constant(this), store(this), not_smi(this); @@ -3183,9 +3188,9 @@ void AccessorAssembler::StoreGlobalIC_PropertyCellCase(Node* property_cell, BIND(¬_smi); { GotoIf(TaggedIsSmi(value), miss); - Node* expected_map = LoadMap(cell_contents); - Node* map = LoadMap(value); - GotoIfNot(WordEqual(expected_map, map), miss); + TNode<Map> expected_map = LoadMap(CAST(cell_contents)); + TNode<Map> map = LoadMap(CAST(value)); + GotoIfNot(TaggedEqual(expected_map, map), miss); Goto(&store); } @@ -3197,7 +3202,7 @@ void AccessorAssembler::StoreGlobalIC_PropertyCellCase(Node* property_cell, BIND(&constant); { - GotoIfNot(WordEqual(cell_contents, value), miss); + GotoIfNot(TaggedEqual(cell_contents, value), miss); exit_point->Return(value); } } @@ -3213,7 +3218,7 @@ void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p) { no_feedback(this, Label::kDeferred), try_polymorphic_name(this, Label::kDeferred); - Node* receiver_map = LoadReceiverMap(p->receiver()); + TNode<Map> receiver_map = LoadReceiverMap(p->receiver()); GotoIf(IsDeprecatedMap(receiver_map), &miss); GotoIf(IsUndefined(p->vector()), &no_feedback); @@ -3244,9 +3249,8 @@ void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p) { { // Check megamorphic case. Comment("KeyedStoreIC_try_megamorphic"); - Branch( - WordEqual(strong_feedback, LoadRoot(RootIndex::kmegamorphic_symbol)), - &no_feedback, &try_polymorphic_name); + Branch(TaggedEqual(strong_feedback, MegamorphicSymbolConstant()), + &no_feedback, &try_polymorphic_name); } BIND(&no_feedback); @@ -3259,7 +3263,7 @@ void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p) { { // We might have a name in feedback, and a fixed array in the next slot. Comment("KeyedStoreIC_try_polymorphic_name"); - GotoIfNot(WordEqual(strong_feedback, p->name()), &miss); + GotoIfNot(TaggedEqual(strong_feedback, p->name()), &miss); // If the name comparison succeeded, we know we have a feedback vector // with at least one map/handler pair. TNode<MaybeObject> feedback_element = LoadFeedbackVectorSlot( @@ -3286,7 +3290,7 @@ void AccessorAssembler::StoreInArrayLiteralIC(const StoreICParameters* p) { try_polymorphic(this, Label::kDeferred), try_megamorphic(this, Label::kDeferred); - Node* array_map = LoadReceiverMap(p->receiver()); + TNode<Map> array_map = LoadReceiverMap(p->receiver()); GotoIf(IsDeprecatedMap(array_map), &miss); GotoIf(IsUndefined(p->vector()), &miss); @@ -3314,8 +3318,8 @@ void AccessorAssembler::StoreInArrayLiteralIC(const StoreICParameters* p) { TNode<Map> transition_map = CAST(GetHeapObjectAssumeWeak(maybe_transition_map, &miss)); GotoIf(IsDeprecatedMap(transition_map), &miss); - Node* code = LoadObjectField(handler, StoreHandler::kSmiHandlerOffset); - CSA_ASSERT(this, IsCode(code)); + TNode<Code> code = + CAST(LoadObjectField(handler, StoreHandler::kSmiHandlerOffset)); TailCallStub(StoreTransitionDescriptor{}, code, p->context(), p->receiver(), p->name(), transition_map, p->value(), p->slot(), p->vector()); @@ -3335,14 +3339,12 @@ void AccessorAssembler::StoreInArrayLiteralIC(const StoreICParameters* p) { BIND(&try_megamorphic); { Comment("StoreInArrayLiteralIC_try_megamorphic"); - CSA_ASSERT(this, - Word32Or(WordEqual(strong_feedback, - LoadRoot(RootIndex::kuninitialized_symbol)), - WordEqual(strong_feedback, - LoadRoot(RootIndex::kmegamorphic_symbol)))); - GotoIfNot( - WordEqual(strong_feedback, LoadRoot(RootIndex::kmegamorphic_symbol)), - &miss); + CSA_ASSERT( + this, + Word32Or(TaggedEqual(strong_feedback, UninitializedSymbolConstant()), + TaggedEqual(strong_feedback, MegamorphicSymbolConstant()))); + GotoIfNot(TaggedEqual(strong_feedback, MegamorphicSymbolConstant()), + &miss); TailCallRuntime(Runtime::kStoreInArrayLiteralIC_Slow, p->context(), p->value(), p->receiver(), p->name()); } @@ -3363,7 +3365,7 @@ void AccessorAssembler::GenerateLoadIC() { using Descriptor = LoadWithVectorDescriptor; Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -3376,7 +3378,7 @@ void AccessorAssembler::GenerateLoadIC_Megamorphic() { using Descriptor = LoadWithVectorDescriptor; Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -3390,7 +3392,7 @@ void AccessorAssembler::GenerateLoadIC_Megamorphic() { BIND(&if_handler); LazyLoadICParameters p([=] { return context; }, receiver, - [=] { return CAST(name); }, slot, vector); + [=] { return name; }, slot, vector); HandleLoadICHandlerCase(&p, CAST(var_handler.value()), &miss, &direct_exit); BIND(&miss); @@ -3402,7 +3404,7 @@ void AccessorAssembler::GenerateLoadIC_Noninlined() { using Descriptor = LoadWithVectorDescriptor; Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -3411,7 +3413,7 @@ void AccessorAssembler::GenerateLoadIC_Noninlined() { TVARIABLE(MaybeObject, var_handler); Label if_handler(this, &var_handler), miss(this, Label::kDeferred); - Node* receiver_map = LoadReceiverMap(receiver); + TNode<Map> receiver_map = LoadReceiverMap(receiver); TNode<MaybeObject> feedback_element = LoadFeedbackVectorSlot(vector, slot, 0, SMI_PARAMETERS); TNode<HeapObject> feedback = CAST(feedback_element); @@ -3432,27 +3434,26 @@ void AccessorAssembler::GenerateLoadIC_Noninlined() { slot, vector); } -void AccessorAssembler::GenerateLoadIC_Uninitialized() { - using Descriptor = LoadWithVectorDescriptor; +void AccessorAssembler::GenerateLoadIC_NoFeedback() { + using Descriptor = LoadDescriptor; Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* slot = Parameter(Descriptor::kSlot); - Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - LoadICParameters p(context, receiver, name, slot, vector); - LoadIC_Uninitialized(&p); + LoadICParameters p(context, receiver, name, slot, UndefinedConstant()); + LoadIC_NoFeedback(&p); } void AccessorAssembler::GenerateLoadICTrampoline() { using Descriptor = LoadDescriptor; Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* slot = Parameter(Descriptor::kSlot); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - Node* vector = LoadFeedbackVectorForStub(); + TNode<FeedbackVector> vector = LoadFeedbackVectorForStub(); TailCallBuiltin(Builtins::kLoadIC, context, receiver, name, slot, vector); } @@ -3461,10 +3462,10 @@ void AccessorAssembler::GenerateLoadICTrampoline_Megamorphic() { using Descriptor = LoadDescriptor; Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* slot = Parameter(Descriptor::kSlot); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - Node* vector = LoadFeedbackVectorForStub(); + TNode<FeedbackVector> vector = LoadFeedbackVectorForStub(); TailCallBuiltin(Builtins::kLoadIC_Megamorphic, context, receiver, name, slot, vector); @@ -3473,7 +3474,7 @@ void AccessorAssembler::GenerateLoadICTrampoline_Megamorphic() { void AccessorAssembler::GenerateLoadGlobalIC(TypeofMode typeof_mode) { using Descriptor = LoadGlobalWithVectorDescriptor; - Node* name = Parameter(Descriptor::kName); + TNode<Name> name = CAST(Parameter(Descriptor::kName)); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -3484,16 +3485,16 @@ void AccessorAssembler::GenerateLoadGlobalIC(TypeofMode typeof_mode) { // lazy_context [=] { return context; }, // lazy_name - [=] { return CAST(name); }, typeof_mode, &direct_exit); + [=] { return name; }, typeof_mode, &direct_exit); } void AccessorAssembler::GenerateLoadGlobalICTrampoline(TypeofMode typeof_mode) { using Descriptor = LoadGlobalDescriptor; - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* slot = Parameter(Descriptor::kSlot); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - Node* vector = LoadFeedbackVectorForStub(); + TNode<FeedbackVector> vector = LoadFeedbackVectorForStub(); Callable callable = CodeFactory::LoadGlobalICInOptimizedCode(isolate(), typeof_mode); @@ -3504,7 +3505,7 @@ void AccessorAssembler::GenerateKeyedLoadIC() { using Descriptor = LoadWithVectorDescriptor; Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -3517,7 +3518,7 @@ void AccessorAssembler::GenerateKeyedLoadIC_Megamorphic() { using Descriptor = LoadWithVectorDescriptor; Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -3530,10 +3531,10 @@ void AccessorAssembler::GenerateKeyedLoadICTrampoline() { using Descriptor = LoadDescriptor; Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* slot = Parameter(Descriptor::kSlot); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - Node* vector = LoadFeedbackVectorForStub(); + TNode<FeedbackVector> vector = LoadFeedbackVectorForStub(); TailCallBuiltin(Builtins::kKeyedLoadIC, context, receiver, name, slot, vector); @@ -3543,10 +3544,10 @@ void AccessorAssembler::GenerateKeyedLoadICTrampoline_Megamorphic() { using Descriptor = LoadDescriptor; Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* slot = Parameter(Descriptor::kSlot); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - Node* vector = LoadFeedbackVectorForStub(); + TNode<FeedbackVector> vector = LoadFeedbackVectorForStub(); TailCallBuiltin(Builtins::kKeyedLoadIC_Megamorphic, context, receiver, name, slot, vector); @@ -3556,7 +3557,7 @@ void AccessorAssembler::GenerateKeyedLoadIC_PolymorphicName() { using Descriptor = LoadWithVectorDescriptor; Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -3568,7 +3569,7 @@ void AccessorAssembler::GenerateKeyedLoadIC_PolymorphicName() { void AccessorAssembler::GenerateStoreGlobalIC() { using Descriptor = StoreGlobalWithVectorDescriptor; - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* value = Parameter(Descriptor::kValue); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); @@ -3581,11 +3582,11 @@ void AccessorAssembler::GenerateStoreGlobalIC() { void AccessorAssembler::GenerateStoreGlobalICTrampoline() { using Descriptor = StoreGlobalDescriptor; - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* value = Parameter(Descriptor::kValue); Node* slot = Parameter(Descriptor::kSlot); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - Node* vector = LoadFeedbackVectorForStub(); + TNode<FeedbackVector> vector = LoadFeedbackVectorForStub(); TailCallBuiltin(Builtins::kStoreGlobalIC, context, name, value, slot, vector); } @@ -3594,7 +3595,7 @@ void AccessorAssembler::GenerateStoreIC() { using Descriptor = StoreWithVectorDescriptor; Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* value = Parameter(Descriptor::kValue); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); @@ -3608,11 +3609,11 @@ void AccessorAssembler::GenerateStoreICTrampoline() { using Descriptor = StoreDescriptor; Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* value = Parameter(Descriptor::kValue); Node* slot = Parameter(Descriptor::kSlot); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - Node* vector = LoadFeedbackVectorForStub(); + TNode<FeedbackVector> vector = LoadFeedbackVectorForStub(); TailCallBuiltin(Builtins::kStoreIC, context, receiver, name, value, slot, vector); @@ -3622,7 +3623,7 @@ void AccessorAssembler::GenerateKeyedStoreIC() { using Descriptor = StoreWithVectorDescriptor; Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* value = Parameter(Descriptor::kValue); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); @@ -3636,11 +3637,11 @@ void AccessorAssembler::GenerateKeyedStoreICTrampoline() { using Descriptor = StoreDescriptor; Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* value = Parameter(Descriptor::kValue); Node* slot = Parameter(Descriptor::kSlot); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - Node* vector = LoadFeedbackVectorForStub(); + TNode<FeedbackVector> vector = LoadFeedbackVectorForStub(); TailCallBuiltin(Builtins::kKeyedStoreIC, context, receiver, name, value, slot, vector); @@ -3650,7 +3651,7 @@ void AccessorAssembler::GenerateStoreInArrayLiteralIC() { using Descriptor = StoreWithVectorDescriptor; Node* array = Parameter(Descriptor::kReceiver); - Node* index = Parameter(Descriptor::kName); + TNode<Object> index = CAST(Parameter(Descriptor::kName)); Node* value = Parameter(Descriptor::kValue); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); @@ -3798,8 +3799,8 @@ void AccessorAssembler::GenerateCloneObjectIC() { TNode<IntPtrT> field_offset_difference = TimesTaggedSize(IntPtrSub(result_start, source_start)); - // Just copy the fields as raw data (pretending that there are no - // MutableHeapNumbers). This doesn't need write barriers. + // Just copy the fields as raw data (pretending that there are no mutable + // HeapNumbers). This doesn't need write barriers. BuildFastLoop( source_start, source_size, [=](Node* field_index) { @@ -3813,7 +3814,7 @@ void AccessorAssembler::GenerateCloneObjectIC() { }, 1, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); - // If MutableHeapNumbers can occur, we need to go through the {object} + // If mutable HeapNumbers can occur, we need to go through the {object} // again here and properly clone them. We use a second loop here to // ensure that the GC (and heap verifier) always sees properly initialized // objects, i.e. never hits undefined values in double fields. @@ -3827,11 +3828,10 @@ void AccessorAssembler::GenerateCloneObjectIC() { TNode<Object> field = LoadObjectField(object, result_offset); Label if_done(this), if_mutableheapnumber(this, Label::kDeferred); GotoIf(TaggedIsSmi(field), &if_done); - Branch(IsMutableHeapNumber(CAST(field)), &if_mutableheapnumber, - &if_done); + Branch(IsHeapNumber(CAST(field)), &if_mutableheapnumber, &if_done); BIND(&if_mutableheapnumber); { - TNode<Object> value = AllocateMutableHeapNumberWithValue( + TNode<HeapNumber> value = AllocateHeapNumberWithValue( LoadHeapNumberValue(UncheckedCast<HeapNumber>(field))); StoreObjectField(object, result_offset, value); Goto(&if_done); @@ -3856,14 +3856,11 @@ void AccessorAssembler::GenerateCloneObjectIC() { BIND(&try_megamorphic); { Comment("CloneObjectIC_try_megamorphic"); - CSA_ASSERT(this, - Word32Or(WordEqual(strong_feedback, - LoadRoot(RootIndex::kuninitialized_symbol)), - WordEqual(strong_feedback, - LoadRoot(RootIndex::kmegamorphic_symbol)))); - GotoIfNot( - WordEqual(strong_feedback, LoadRoot(RootIndex::kmegamorphic_symbol)), - &miss); + CSA_ASSERT( + this, + Word32Or(TaggedEqual(strong_feedback, UninitializedSymbolConstant()), + TaggedEqual(strong_feedback, MegamorphicSymbolConstant()))); + GotoIfNot(TaggedEqual(strong_feedback, MegamorphicSymbolConstant()), &miss); Goto(&slow); } @@ -3876,8 +3873,8 @@ void AccessorAssembler::GenerateCloneObjectIC() { BIND(&miss); { Comment("CloneObjectIC_miss"); - Node* map_or_result = CallRuntime(Runtime::kCloneObjectIC_Miss, context, - source, flags, slot, vector); + TNode<HeapObject> map_or_result = CAST(CallRuntime( + Runtime::kCloneObjectIC_Miss, context, source, flags, slot, vector)); var_handler = UncheckedCast<MaybeObject>(map_or_result); GotoIf(IsMap(map_or_result), &if_handler); CSA_ASSERT(this, IsJSObject(map_or_result)); @@ -3889,7 +3886,7 @@ void AccessorAssembler::GenerateKeyedHasIC() { using Descriptor = LoadWithVectorDescriptor; Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -3902,7 +3899,7 @@ void AccessorAssembler::GenerateKeyedHasIC_Megamorphic() { using Descriptor = LoadWithVectorDescriptor; Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); // TODO(magardn): implement HasProperty handling in KeyedLoadICGeneric Return(HasProperty(context, receiver, name, @@ -3913,7 +3910,7 @@ void AccessorAssembler::GenerateKeyedHasIC_PolymorphicName() { using Descriptor = LoadWithVectorDescriptor; Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); diff --git a/deps/v8/src/ic/accessor-assembler.h b/deps/v8/src/ic/accessor-assembler.h index 6127b244e3..0de2292fd6 100644 --- a/deps/v8/src/ic/accessor-assembler.h +++ b/deps/v8/src/ic/accessor-assembler.h @@ -30,7 +30,7 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { void GenerateLoadIC(); void GenerateLoadIC_Megamorphic(); void GenerateLoadIC_Noninlined(); - void GenerateLoadIC_Uninitialized(); + void GenerateLoadIC_NoFeedback(); void GenerateLoadICTrampoline(); void GenerateLoadICTrampoline_Megamorphic(); void GenerateKeyedLoadIC(); @@ -56,9 +56,9 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { void GenerateStoreInArrayLiteralIC(); - void TryProbeStubCache(StubCache* stub_cache, Node* receiver, Node* name, - Label* if_handler, TVariable<MaybeObject>* var_handler, - Label* if_miss); + void TryProbeStubCache(StubCache* stub_cache, Node* receiver, + TNode<Object> name, Label* if_handler, + TVariable<MaybeObject>* var_handler, Label* if_miss); Node* StubCachePrimaryOffsetForTesting(Node* name, Node* map) { return StubCachePrimaryOffset(name, map); @@ -68,7 +68,7 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { } struct LoadICParameters { - LoadICParameters(TNode<Context> context, Node* receiver, Node* name, + LoadICParameters(TNode<Context> context, Node* receiver, TNode<Object> name, Node* slot, Node* vector, Node* holder = nullptr) : context_(context), receiver_(receiver), @@ -77,7 +77,7 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { vector_(vector), holder_(holder ? holder : receiver) {} - LoadICParameters(const LoadICParameters* p, Node* unique_name) + LoadICParameters(const LoadICParameters* p, TNode<Object> unique_name) : context_(p->context_), receiver_(p->receiver_), name_(unique_name), @@ -87,7 +87,7 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { TNode<Context> context() const { return context_; } Node* receiver() const { return receiver_; } - Node* name() const { return name_; } + TNode<Object> name() const { return name_; } Node* slot() const { return slot_; } Node* vector() const { return vector_; } Node* holder() const { return holder_; } @@ -95,7 +95,7 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { private: TNode<Context> context_; Node* receiver_; - Node* name_; + TNode<Object> name_; Node* slot_; Node* vector_; Node* holder_; @@ -119,13 +119,13 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { holder_(p->holder()) { TNode<Context> p_context = p->context(); context_ = [=] { return p_context; }; - TNode<Object> p_name = TNode<Object>::UncheckedCast(p->name()); + TNode<Object> p_name = p->name(); name_ = [=] { return p_name; }; } TNode<Context> context() const { return context_(); } Node* receiver() const { return receiver_; } - Node* name() const { return name_(); } + TNode<Object> name() const { return name_(); } Node* slot() const { return slot_; } Node* vector() const { return vector_; } Node* holder() const { return holder_; } @@ -156,8 +156,9 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { protected: struct StoreICParameters : public LoadICParameters { - StoreICParameters(TNode<Context> context, Node* receiver, Node* name, - SloppyTNode<Object> value, Node* slot, Node* vector) + StoreICParameters(TNode<Context> context, Node* receiver, + TNode<Object> name, SloppyTNode<Object> value, Node* slot, + Node* vector) : LoadICParameters(context, receiver, name, slot, vector), value_(value) {} @@ -191,12 +192,13 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { void OverwriteExistingFastDataProperty(Node* object, Node* object_map, Node* descriptors, Node* descriptor_name_index, - Node* details, Node* value, + Node* details, TNode<Object> value, Label* slow, bool do_transitioning_store); void CheckFieldType(TNode<DescriptorArray> descriptors, Node* name_index, - Node* representation, Node* value, Label* bailout); + TNode<Word32T> representation, Node* value, + Label* bailout); private: // Stub generation entry points. @@ -204,7 +206,7 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { // LoadIC contains the full LoadIC logic, while LoadIC_Noninlined contains // logic not inlined into Ignition bytecode handlers. void LoadIC(const LoadICParameters* p); - void LoadIC_Noninlined(const LoadICParameters* p, Node* receiver_map, + void LoadIC_Noninlined(const LoadICParameters* p, TNode<Map> receiver_map, TNode<HeapObject> feedback, TVariable<MaybeObject>* var_handler, Label* if_handler, Label* miss, ExitPoint* exit_point); @@ -214,7 +216,7 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { TNode<MaybeObject> LoadDescriptorValueOrFieldType( TNode<Map> map, TNode<IntPtrT> descriptor_entry); - void LoadIC_Uninitialized(const LoadICParameters* p); + void LoadIC_NoFeedback(const LoadICParameters* p); void KeyedLoadIC(const LoadICParameters* p, LoadAccessMode access_mode); void KeyedLoadICGeneric(const LoadICParameters* p); @@ -222,7 +224,7 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { LoadAccessMode access_mode); void StoreIC(const StoreICParameters* p); void StoreGlobalIC(const StoreICParameters* p); - void StoreGlobalIC_PropertyCellCase(Node* property_cell, Node* value, + void StoreGlobalIC_PropertyCellCase(Node* property_cell, TNode<Object> value, ExitPoint* exit_point, Label* miss); void KeyedStoreIC(const StoreICParameters* p); void StoreInArrayLiteralIC(const StoreICParameters* p); @@ -275,8 +277,9 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { Variable* var_double_value, Label* rebox_double, ExitPoint* exit_point); - void EmitAccessCheck(Node* expected_native_context, Node* context, - Node* receiver, Label* can_access, Label* miss); + void EmitAccessCheck(TNode<Context> expected_native_context, + TNode<Context> context, Node* receiver, + Label* can_access, Label* miss); void HandleLoadICSmiHandlerLoadNamedCase( const LazyLoadICParameters* p, Node* holder, TNode<IntPtrT> handler_kind, @@ -317,7 +320,8 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { Representation representation, Node* value, Label* miss); - void CheckPrototypeValidityCell(Node* maybe_validity_cell, Label* miss); + void CheckPrototypeValidityCell(TNode<Object> maybe_validity_cell, + Label* miss); void HandleStoreICNativeDataProperty(const StoreICParameters* p, Node* holder, Node* handler_word); @@ -366,7 +370,7 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { void EmitFastElementsBoundsCheck(Node* object, Node* elements, Node* intptr_index, Node* is_jsarray_condition, Label* miss); - void EmitElementLoad(Node* object, Node* elements_kind, + void EmitElementLoad(Node* object, TNode<Word32T> elements_kind, SloppyTNode<IntPtrT> key, Node* is_jsarray_condition, Label* if_hole, Label* rebox_double, Variable* var_double_value, @@ -387,8 +391,8 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { Node* StubCacheSecondaryOffset(Node* name, Node* seed); void TryProbeStubCacheTable(StubCache* stub_cache, StubCacheTable table_id, - Node* entry_offset, Node* name, Node* map, - Label* if_handler, + Node* entry_offset, TNode<Object> name, + TNode<Map> map, Label* if_handler, TVariable<MaybeObject>* var_handler, Label* if_miss); }; diff --git a/deps/v8/src/ic/binary-op-assembler.cc b/deps/v8/src/ic/binary-op-assembler.cc index 50b7cd1ebb..f6bec6eab9 100644 --- a/deps/v8/src/ic/binary-op-assembler.cc +++ b/deps/v8/src/ic/binary-op-assembler.cc @@ -114,8 +114,9 @@ Node* BinaryOpAssembler::Generate_AddWithFeedback(Node* context, Node* lhs, BIND(&do_fadd); { var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kNumber)); - Node* value = Float64Add(var_fadd_lhs.value(), var_fadd_rhs.value()); - Node* result = AllocateHeapNumberWithValue(value); + TNode<Float64T> value = + Float64Add(var_fadd_lhs.value(), var_fadd_rhs.value()); + TNode<HeapNumber> result = AllocateHeapNumberWithValue(value); var_result.Bind(result); Goto(&end); } @@ -124,8 +125,9 @@ Node* BinaryOpAssembler::Generate_AddWithFeedback(Node* context, Node* lhs, { // No checks on rhs are done yet. We just know lhs is not a number or Smi. Label if_lhsisoddball(this), if_lhsisnotoddball(this); - Node* lhs_instance_type = LoadInstanceType(lhs); - Node* lhs_is_oddball = InstanceTypeEqual(lhs_instance_type, ODDBALL_TYPE); + TNode<Uint16T> lhs_instance_type = LoadInstanceType(lhs); + TNode<BoolT> lhs_is_oddball = + InstanceTypeEqual(lhs_instance_type, ODDBALL_TYPE); Branch(lhs_is_oddball, &if_lhsisoddball, &if_lhsisnotoddball); BIND(&if_lhsisoddball); @@ -154,7 +156,7 @@ Node* BinaryOpAssembler::Generate_AddWithFeedback(Node* context, Node* lhs, // Check if the {rhs} is a smi, and exit the string check early if it is. GotoIf(TaggedIsSmi(rhs), &call_with_any_feedback); - Node* rhs_instance_type = LoadInstanceType(rhs); + TNode<Uint16T> rhs_instance_type = LoadInstanceType(rhs); // Exit unless {rhs} is a string. Since {lhs} is a string we no longer // need an Oddball check. @@ -173,8 +175,9 @@ Node* BinaryOpAssembler::Generate_AddWithFeedback(Node* context, Node* lhs, { // Check if rhs is an oddball. At this point we know lhs is either a // Smi or number or oddball and rhs is not a number or Smi. - Node* rhs_instance_type = LoadInstanceType(rhs); - Node* rhs_is_oddball = InstanceTypeEqual(rhs_instance_type, ODDBALL_TYPE); + TNode<Uint16T> rhs_instance_type = LoadInstanceType(rhs); + TNode<BoolT> rhs_is_oddball = + InstanceTypeEqual(rhs_instance_type, ODDBALL_TYPE); GotoIf(rhs_is_oddball, &call_with_oddball_feedback); Goto(&call_with_any_feedback); } @@ -322,9 +325,10 @@ Node* BinaryOpAssembler::Generate_BinaryOperationWithFeedback( { // No checks on rhs are done yet. We just know lhs is not a number or Smi. Label if_left_bigint(this), if_left_oddball(this); - Node* lhs_instance_type = LoadInstanceType(lhs); + TNode<Uint16T> lhs_instance_type = LoadInstanceType(lhs); GotoIf(IsBigIntInstanceType(lhs_instance_type), &if_left_bigint); - Node* lhs_is_oddball = InstanceTypeEqual(lhs_instance_type, ODDBALL_TYPE); + TNode<BoolT> lhs_is_oddball = + InstanceTypeEqual(lhs_instance_type, ODDBALL_TYPE); Branch(lhs_is_oddball, &if_left_oddball, &call_with_any_feedback); BIND(&if_left_oddball); @@ -361,9 +365,10 @@ Node* BinaryOpAssembler::Generate_BinaryOperationWithFeedback( { // Check if rhs is an oddball. At this point we know lhs is either a // Smi or number or oddball and rhs is not a number or Smi. - Node* rhs_instance_type = LoadInstanceType(rhs); + TNode<Uint16T> rhs_instance_type = LoadInstanceType(rhs); GotoIf(IsBigIntInstanceType(rhs_instance_type), &if_bigint); - Node* rhs_is_oddball = InstanceTypeEqual(rhs_instance_type, ODDBALL_TYPE); + TNode<BoolT> rhs_is_oddball = + InstanceTypeEqual(rhs_instance_type, ODDBALL_TYPE); GotoIfNot(rhs_is_oddball, &call_with_any_feedback); var_type_feedback.Bind( @@ -437,7 +442,7 @@ Node* BinaryOpAssembler::Generate_SubtractWithFeedback(Node* context, Node* lhs, BIND(&if_overflow); { var_type_feedback->Bind(SmiConstant(BinaryOperationFeedback::kNumber)); - Node* value = Float64Sub(SmiToFloat64(lhs), SmiToFloat64(rhs)); + TNode<Float64T> value = Float64Sub(SmiToFloat64(lhs), SmiToFloat64(rhs)); var_result = AllocateHeapNumberWithValue(value); Goto(&end); } @@ -490,7 +495,7 @@ Node* BinaryOpAssembler::Generate_DivideWithFeedback( { var_type_feedback->Bind( SmiConstant(BinaryOperationFeedback::kSignedSmallInputs)); - Node* value = Float64Div(SmiToFloat64(lhs), SmiToFloat64(rhs)); + TNode<Float64T> value = Float64Div(SmiToFloat64(lhs), SmiToFloat64(rhs)); var_result.Bind(AllocateHeapNumberWithValue(value)); Goto(&end); } @@ -528,7 +533,7 @@ Node* BinaryOpAssembler::Generate_ExponentiateWithFeedback( Node* context, Node* base, Node* exponent, Node* slot_id, Node* feedback_vector, bool rhs_is_smi) { // We currently don't optimize exponentiation based on feedback. - Node* dummy_feedback = SmiConstant(BinaryOperationFeedback::kAny); + TNode<Smi> dummy_feedback = SmiConstant(BinaryOperationFeedback::kAny); UpdateFeedback(dummy_feedback, feedback_vector, slot_id); return CallBuiltin(Builtins::kExponentiate, context, base, exponent); } diff --git a/deps/v8/src/ic/handler-configuration-inl.h b/deps/v8/src/ic/handler-configuration-inl.h index f5cd0c1de7..c0ff8a4c9b 100644 --- a/deps/v8/src/ic/handler-configuration-inl.h +++ b/deps/v8/src/ic/handler-configuration-inl.h @@ -51,8 +51,8 @@ Handle<Smi> LoadHandler::LoadField(Isolate* isolate, FieldIndex field_index) { return handle(Smi::FromInt(config), isolate); } -Handle<Smi> LoadHandler::LoadConstant(Isolate* isolate, int descriptor) { - int config = KindBits::encode(kConstant) | DescriptorBits::encode(descriptor); +Handle<Smi> LoadHandler::LoadConstantFromPrototype(Isolate* isolate) { + int config = KindBits::encode(kConstantFromPrototype); return handle(Smi::FromInt(config), isolate); } diff --git a/deps/v8/src/ic/handler-configuration.cc b/deps/v8/src/ic/handler-configuration.cc index 0b8ebd2bbe..814935c6eb 100644 --- a/deps/v8/src/ic/handler-configuration.cc +++ b/deps/v8/src/ic/handler-configuration.cc @@ -30,7 +30,7 @@ int InitPrototypeChecksImpl(Isolate* isolate, Handle<ICHandler> handler, Handle<Smi>* smi_handler, Handle<Map> receiver_map, Handle<JSReceiver> holder, MaybeObjectHandle data1, MaybeObjectHandle maybe_data2) { - int checks_count = 0; + int data_size = 1; // Holder-is-receiver case itself does not add entries unless there is an // optional data2 value provided. @@ -51,7 +51,7 @@ int InitPrototypeChecksImpl(Isolate* isolate, Handle<ICHandler> handler, using Bit = typename ICHandler::DoAccessCheckOnReceiverBits; *smi_handler = SetBitFieldValue<Bit>(isolate, *smi_handler, true); } - checks_count++; + data_size++; } else if (receiver_map->is_dictionary_map() && !receiver_map->IsJSGlobalObjectMap()) { if (!fill_handler) { @@ -67,16 +67,16 @@ int InitPrototypeChecksImpl(Isolate* isolate, Handle<ICHandler> handler, if (fill_handler) { // This value will go either to data2 or data3 slot depending on whether // data2 slot is already occupied by native context. - if (checks_count == 0) { + if (data_size == 1) { handler->set_data2(*maybe_data2); } else { - DCHECK_EQ(1, checks_count); + DCHECK_EQ(2, data_size); handler->set_data3(*maybe_data2); } } - checks_count++; + data_size++; } - return checks_count; + return data_size; } // Returns 0 if the validity cell check is enough to ensure that the @@ -86,10 +86,10 @@ int InitPrototypeChecksImpl(Isolate* isolate, Handle<ICHandler> handler, // Returns -1 if the handler has to be compiled or the number of prototype // checks otherwise. template <typename ICHandler> -int GetPrototypeCheckCount( - Isolate* isolate, Handle<Smi>* smi_handler, Handle<Map> receiver_map, - Handle<JSReceiver> holder, MaybeObjectHandle data1, - MaybeObjectHandle maybe_data2 = MaybeObjectHandle()) { +int GetHandlerDataSize(Isolate* isolate, Handle<Smi>* smi_handler, + Handle<Map> receiver_map, Handle<JSReceiver> holder, + MaybeObjectHandle data1, + MaybeObjectHandle maybe_data2 = MaybeObjectHandle()) { DCHECK_NOT_NULL(smi_handler); return InitPrototypeChecksImpl<ICHandler, false>(isolate, Handle<ICHandler>(), smi_handler, receiver_map, @@ -121,14 +121,13 @@ Handle<Object> LoadHandler::LoadFromPrototype(Isolate* isolate, data1 = maybe_data1; } - int checks_count = GetPrototypeCheckCount<LoadHandler>( + int data_size = GetHandlerDataSize<LoadHandler>( isolate, &smi_handler, receiver_map, holder, data1, maybe_data2); Handle<Object> validity_cell = Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate); - int data_count = 1 + checks_count; - Handle<LoadHandler> handler = isolate->factory()->NewLoadHandler(data_count); + Handle<LoadHandler> handler = isolate->factory()->NewLoadHandler(data_size); handler->set_smi_handler(*smi_handler); handler->set_validity_cell(*validity_cell); @@ -144,19 +143,18 @@ Handle<Object> LoadHandler::LoadFullChain(Isolate* isolate, Handle<Smi> smi_handler) { Handle<JSReceiver> end; // null handle, means full prototype chain lookup. MaybeObjectHandle data1 = holder; - int checks_count = GetPrototypeCheckCount<LoadHandler>( - isolate, &smi_handler, receiver_map, end, data1); + int data_size = GetHandlerDataSize<LoadHandler>(isolate, &smi_handler, + receiver_map, end, data1); Handle<Object> validity_cell = Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate); if (validity_cell->IsSmi()) { - DCHECK_EQ(0, checks_count); + DCHECK_EQ(1, data_size); // Lookup on receiver isn't supported in case of a simple smi handler. if (!LookupOnReceiverBits::decode(smi_handler->value())) return smi_handler; } - int data_count = 1 + checks_count; - Handle<LoadHandler> handler = isolate->factory()->NewLoadHandler(data_count); + Handle<LoadHandler> handler = isolate->factory()->NewLoadHandler(data_size); handler->set_smi_handler(*smi_handler); handler->set_validity_cell(*validity_cell); @@ -251,16 +249,13 @@ Handle<Object> StoreHandler::StoreThroughPrototype( data1 = maybe_data1; } - int checks_count = GetPrototypeCheckCount<StoreHandler>( + int data_size = GetHandlerDataSize<StoreHandler>( isolate, &smi_handler, receiver_map, holder, data1, maybe_data2); Handle<Object> validity_cell = Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate); - DCHECK_IMPLIES(validity_cell->IsSmi(), checks_count == 0); - int data_count = 1 + checks_count; - Handle<StoreHandler> handler = - isolate->factory()->NewStoreHandler(data_count); + Handle<StoreHandler> handler = isolate->factory()->NewStoreHandler(data_size); handler->set_smi_handler(*smi_handler); handler->set_validity_cell(*validity_cell); diff --git a/deps/v8/src/ic/handler-configuration.h b/deps/v8/src/ic/handler-configuration.h index b8888868ec..80d19d73ec 100644 --- a/deps/v8/src/ic/handler-configuration.h +++ b/deps/v8/src/ic/handler-configuration.h @@ -37,7 +37,7 @@ class LoadHandler final : public DataHandler { kNormal, kGlobal, kField, - kConstant, + kConstantFromPrototype, kAccessor, kNativeDataProperty, kApiGetter, @@ -47,65 +47,58 @@ class LoadHandler final : public DataHandler { kNonExistent, kModuleExport }; - class KindBits : public BitField<Kind, 0, 4> {}; + using KindBits = BitField<Kind, 0, 4>; // Defines whether access rights check should be done on receiver object. // Applicable to named property kinds only when loading value from prototype // chain. Ignored when loading from holder. - class DoAccessCheckOnReceiverBits - : public BitField<bool, KindBits::kNext, 1> {}; + using DoAccessCheckOnReceiverBits = KindBits::Next<bool, 1>; // Defines whether a lookup should be done on receiver object before // proceeding to the prototype chain. Applicable to named property kinds only // when loading value from prototype chain. Ignored when loading from holder. - class LookupOnReceiverBits - : public BitField<bool, DoAccessCheckOnReceiverBits::kNext, 1> {}; + using LookupOnReceiverBits = DoAccessCheckOnReceiverBits::Next<bool, 1>; // // Encoding when KindBits contains kForConstants. // // Index of a value entry in the descriptor array. - class DescriptorBits : public BitField<unsigned, LookupOnReceiverBits::kNext, - kDescriptorIndexBitCount> {}; + using DescriptorBits = + LookupOnReceiverBits::Next<unsigned, kDescriptorIndexBitCount>; // Make sure we don't overflow the smi. - STATIC_ASSERT(DescriptorBits::kNext <= kSmiValueSize); + STATIC_ASSERT(DescriptorBits::kLastUsedBit < kSmiValueSize); // // Encoding when KindBits contains kField. // - class IsInobjectBits : public BitField<bool, LookupOnReceiverBits::kNext, 1> { - }; - class IsDoubleBits : public BitField<bool, IsInobjectBits::kNext, 1> {}; + using IsInobjectBits = LookupOnReceiverBits::Next<bool, 1>; + using IsDoubleBits = IsInobjectBits::Next<bool, 1>; // +1 here is to cover all possible JSObject header sizes. - class FieldIndexBits : public BitField<unsigned, IsDoubleBits::kNext, - kDescriptorIndexBitCount + 1> {}; + using FieldIndexBits = + IsDoubleBits::Next<unsigned, kDescriptorIndexBitCount + 1>; // Make sure we don't overflow the smi. - STATIC_ASSERT(FieldIndexBits::kNext <= kSmiValueSize); + STATIC_ASSERT(FieldIndexBits::kLastUsedBit < kSmiValueSize); // // Encoding when KindBits contains kElement or kIndexedString. // - class AllowOutOfBoundsBits - : public BitField<bool, LookupOnReceiverBits::kNext, 1> {}; + using AllowOutOfBoundsBits = LookupOnReceiverBits::Next<bool, 1>; // // Encoding when KindBits contains kElement. // - class IsJsArrayBits : public BitField<bool, AllowOutOfBoundsBits::kNext, 1> { - }; - class ConvertHoleBits : public BitField<bool, IsJsArrayBits::kNext, 1> {}; - class ElementsKindBits - : public BitField<ElementsKind, ConvertHoleBits::kNext, 8> {}; + using IsJsArrayBits = AllowOutOfBoundsBits::Next<bool, 1>; + using ConvertHoleBits = IsJsArrayBits::Next<bool, 1>; + using ElementsKindBits = ConvertHoleBits::Next<ElementsKind, 8>; // Make sure we don't overflow the smi. - STATIC_ASSERT(ElementsKindBits::kNext <= kSmiValueSize); + STATIC_ASSERT(ElementsKindBits::kLastUsedBit < kSmiValueSize); // // Encoding when KindBits contains kModuleExport. // - class ExportsIndexBits - : public BitField<unsigned, LookupOnReceiverBits::kNext, - kSmiValueSize - LookupOnReceiverBits::kNext> {}; + using ExportsIndexBits = LookupOnReceiverBits::Next< + unsigned, kSmiValueSize - LookupOnReceiverBits::kLastUsedBit - 1>; // Decodes kind from Smi-handler. static inline Kind GetHandlerKind(Smi smi_handler); @@ -123,8 +116,9 @@ class LoadHandler final : public DataHandler { // Creates a Smi-handler for loading a field from fast object. static inline Handle<Smi> LoadField(Isolate* isolate, FieldIndex field_index); - // Creates a Smi-handler for loading a constant from fast object. - static inline Handle<Smi> LoadConstant(Isolate* isolate, int descriptor); + // Creates a Smi-handler for loading a cached constant from fast + // prototype object. + static inline Handle<Smi> LoadConstantFromPrototype(Isolate* isolate); // Creates a Smi-handler for calling a getter on a fast object. static inline Handle<Smi> LoadAccessor(Isolate* isolate, int descriptor); @@ -206,47 +200,43 @@ class StoreHandler final : public DataHandler { kProxy, kKindsNumber // Keep last }; - class KindBits : public BitField<Kind, 0, 4> {}; + using KindBits = BitField<Kind, 0, 4>; enum FieldRepresentation { kSmi, kDouble, kHeapObject, kTagged }; // Applicable to kGlobalProxy, kProxy kinds. // Defines whether access rights check should be done on receiver object. - class DoAccessCheckOnReceiverBits - : public BitField<bool, KindBits::kNext, 1> {}; + using DoAccessCheckOnReceiverBits = KindBits::Next<bool, 1>; // Defines whether a lookup should be done on receiver object before // proceeding to the prototype chain. Applicable to named property kinds only // when storing through prototype chain. Ignored when storing to holder. - class LookupOnReceiverBits - : public BitField<bool, DoAccessCheckOnReceiverBits::kNext, 1> {}; + using LookupOnReceiverBits = DoAccessCheckOnReceiverBits::Next<bool, 1>; // Applicable to kField, kTransitionToField and kTransitionToConstant // kinds. // Index of a value entry in the descriptor array. - class DescriptorBits : public BitField<unsigned, LookupOnReceiverBits::kNext, - kDescriptorIndexBitCount> {}; + using DescriptorBits = + LookupOnReceiverBits::Next<unsigned, kDescriptorIndexBitCount>; // // Encoding when KindBits contains kTransitionToConstant. // // Make sure we don't overflow the smi. - STATIC_ASSERT(DescriptorBits::kNext <= kSmiValueSize); + STATIC_ASSERT(DescriptorBits::kLastUsedBit < kSmiValueSize); // // Encoding when KindBits contains kField or kTransitionToField. // - class IsInobjectBits : public BitField<bool, DescriptorBits::kNext, 1> {}; - class FieldRepresentationBits - : public BitField<FieldRepresentation, IsInobjectBits::kNext, 2> {}; + using IsInobjectBits = DescriptorBits::Next<bool, 1>; + using FieldRepresentationBits = IsInobjectBits::Next<FieldRepresentation, 2>; // +1 here is to cover all possible JSObject header sizes. - class FieldIndexBits - : public BitField<unsigned, FieldRepresentationBits::kNext, - kDescriptorIndexBitCount + 1> {}; + using FieldIndexBits = + FieldRepresentationBits::Next<unsigned, kDescriptorIndexBitCount + 1>; // Make sure we don't overflow the smi. - STATIC_ASSERT(FieldIndexBits::kNext <= kSmiValueSize); + STATIC_ASSERT(FieldIndexBits::kLastUsedBit < kSmiValueSize); // Creates a Smi-handler for storing a field to fast object. static inline Handle<Smi> StoreField(Isolate* isolate, int descriptor, diff --git a/deps/v8/src/ic/ic.cc b/deps/v8/src/ic/ic.cc index 377e3df6ae..3c8d1ea582 100644 --- a/deps/v8/src/ic/ic.cc +++ b/deps/v8/src/ic/ic.cc @@ -14,6 +14,7 @@ #include "src/execution/execution.h" #include "src/execution/frames-inl.h" #include "src/execution/isolate-inl.h" +#include "src/execution/runtime-profiler.h" #include "src/handles/handles-inl.h" #include "src/ic/call-optimization.h" #include "src/ic/handler-configuration-inl.h" @@ -28,14 +29,13 @@ #include "src/objects/heap-number-inl.h" #include "src/objects/js-array-inl.h" #include "src/objects/module-inl.h" -#include "src/objects/struct-inl.h" -#include "src/utils/ostreams.h" -#include "src/execution/runtime-profiler.h" #include "src/objects/prototype.h" +#include "src/objects/struct-inl.h" #include "src/runtime/runtime-utils.h" #include "src/runtime/runtime.h" #include "src/tracing/trace-event.h" #include "src/tracing/tracing-category-observer.h" +#include "src/utils/ostreams.h" namespace v8 { namespace internal { @@ -391,19 +391,23 @@ MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) { } if (*name == ReadOnlyRoots(isolate()).iterator_symbol()) { - return Runtime::ThrowIteratorError(isolate(), object); + return isolate()->Throw<Object>( + ErrorUtils::NewIteratorError(isolate(), object)); + } + + if (IsAnyHas()) { + return TypeError(MessageTemplate::kInvalidInOperatorUse, object, name); + } else { + DCHECK(object->IsNullOrUndefined(isolate())); + ErrorUtils::ThrowLoadFromNullOrUndefined(isolate(), object, name); + return MaybeHandle<Object>(); } - return TypeError(IsAnyHas() ? MessageTemplate::kInvalidInOperatorUse - : MessageTemplate::kNonObjectPropertyLoad, - object, name); } if (MigrateDeprecated(isolate(), object)) use_ic = false; - if (state() != UNINITIALIZED) { - JSObject::MakePrototypesFast(object, kStartAtReceiver, isolate()); - update_receiver_map(object); - } + JSObject::MakePrototypesFast(object, kStartAtReceiver, isolate()); + update_receiver_map(object); LookupIterator it(isolate(), object, name); @@ -414,7 +418,7 @@ MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) { if (name->IsPrivateName() && !it.IsFound()) { Handle<String> name_string(String::cast(Symbol::cast(*name).name()), isolate()); - return TypeError(MessageTemplate::kInvalidPrivateFieldRead, object, + return TypeError(MessageTemplate::kInvalidPrivateMemberRead, object, name_string); } @@ -618,7 +622,7 @@ void IC::PatchCache(Handle<Name> name, const MaybeObjectHandle& handler) { DCHECK(IsAnyLoad() || IsAnyStore() || IsAnyHas()); switch (state()) { case NO_FEEDBACK: - break; + UNREACHABLE(); case UNINITIALIZED: case PREMONOMORPHIC: UpdateMonomorphicIC(handler, name); @@ -648,15 +652,6 @@ void IC::PatchCache(Handle<Name> name, const MaybeObjectHandle& handler) { } void LoadIC::UpdateCaches(LookupIterator* lookup) { - if (state() == UNINITIALIZED && !IsLoadGlobalIC()) { - // This is the first time we execute this inline cache. Set the target to - // the pre monomorphic stub to delay setting the monomorphic state. - TRACE_HANDLER_STATS(isolate(), LoadIC_Premonomorphic); - ConfigureVectorState(receiver_map()); - TraceIC("LoadIC", lookup->name()); - return; - } - Handle<Object> code; if (lookup->state() == LookupIterator::ACCESS_CHECK) { code = slow_stub(); @@ -908,6 +903,33 @@ Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) { if (receiver_is_holder) return smi_handler; TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldFromPrototypeDH); } + if (lookup->constness() == PropertyConstness::kConst && + !receiver_is_holder) { + DCHECK(!lookup->is_dictionary_holder()); + + Handle<Object> value = lookup->GetDataValue(); + + if (value->IsThinString()) { + value = handle(ThinString::cast(*value)->actual(), isolate()); + } + + // Non internalized strings could turn into thin/cons strings + // when internalized. Weak references to thin/cons strings are + // not supported in the GC. If concurrent marking is running + // and the thin/cons string is marked but the actual string is + // not, then the weak reference could be missed. + if (!value->IsString() || + (value->IsString() && value->IsInternalizedString())) { + MaybeObjectHandle weak_value = + value->IsSmi() ? MaybeObjectHandle(*value, isolate()) + : MaybeObjectHandle::Weak(*value, isolate()); + + smi_handler = LoadHandler::LoadConstantFromPrototype(isolate()); + TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantFromPrototypeDH); + return LoadHandler::LoadFromPrototype(isolate(), map, holder, + smi_handler, weak_value); + } + } return LoadHandler::LoadFromPrototype(isolate(), map, holder, smi_handler); } @@ -1117,7 +1139,7 @@ Handle<Object> KeyedLoadIC::LoadElementHandler(Handle<Map> receiver_map, is_js_array, load_mode); } DCHECK(IsFastElementsKind(elements_kind) || - IsFrozenOrSealedElementsKind(elements_kind) || + IsAnyNonextensibleElementsKind(elements_kind) || IsTypedArrayElementsKind(elements_kind)); bool convert_hole_to_undefined = (elements_kind == HOLEY_SMI_ELEMENTS || @@ -1415,16 +1437,14 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name, return TypeError(MessageTemplate::kNonObjectPropertyStore, object, name); } - if (state() != UNINITIALIZED) { - JSObject::MakePrototypesFast(object, kStartAtPrototype, isolate()); - } + JSObject::MakePrototypesFast(object, kStartAtPrototype, isolate()); LookupIterator it(isolate(), object, name); if (name->IsPrivate()) { if (name->IsPrivateName() && !it.IsFound()) { Handle<String> name_string(String::cast(Symbol::cast(*name).name()), isolate()); - return TypeError(MessageTemplate::kInvalidPrivateFieldWrite, object, + return TypeError(MessageTemplate::kInvalidPrivateMemberWrite, object, name_string); } @@ -1442,15 +1462,6 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name, void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value, StoreOrigin store_origin) { - if (state() == UNINITIALIZED && !IsStoreGlobalIC()) { - // This is the first time we execute this inline cache. Transition - // to premonomorphic state to delay setting the monomorphic state. - TRACE_HANDLER_STATS(isolate(), StoreIC_Premonomorphic); - ConfigureVectorState(receiver_map()); - TraceIC("StoreIC", lookup->name()); - return; - } - MaybeObjectHandle handler; if (LookupForWrite(lookup, value, store_origin)) { if (IsStoreGlobalIC()) { @@ -1810,10 +1821,8 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map, handlers.reserve(target_receiver_maps.size()); StoreElementPolymorphicHandlers(&target_receiver_maps, &handlers, store_mode); if (target_receiver_maps.size() == 0) { - // Transition to PREMONOMORPHIC state here and remember a weak-reference - // to the {receiver_map} in case TurboFan sees this function before the - // IC can transition further. - ConfigureVectorState(receiver_map); + Handle<Object> handler = StoreElementHandler(receiver_map, store_mode); + ConfigureVectorState(Handle<Name>(), receiver_map, handler); } else if (target_receiver_maps.size() == 1) { ConfigureVectorState(Handle<Name>(), target_receiver_maps[0], handlers[0]); } else { @@ -1840,6 +1849,7 @@ Handle<Object> KeyedStoreIC::StoreElementHandler( CodeFactory::KeyedStoreIC_SloppyArguments(isolate(), store_mode).code(); } else if (receiver_map->has_fast_elements() || receiver_map->has_sealed_elements() || + receiver_map->has_nonextensible_elements() || receiver_map->has_typed_array_elements()) { TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreFastElementStub); code = CodeFactory::StoreFastElementIC(isolate(), store_mode).code(); diff --git a/deps/v8/src/ic/keyed-store-generic.cc b/deps/v8/src/ic/keyed-store-generic.cc index 7e87b015d4..bb4e6cb427 100644 --- a/deps/v8/src/ic/keyed-store-generic.cc +++ b/deps/v8/src/ic/keyed-store-generic.cc @@ -30,7 +30,7 @@ class KeyedStoreGenericAssembler : public AccessorAssembler { void KeyedStoreGeneric(); - void StoreIC_Uninitialized(); + void StoreIC_NoFeedback(); // Generates code for [[Set]] operation, the |unique_name| is supposed to be // unique otherwise this code will always go to runtime. @@ -62,8 +62,8 @@ class KeyedStoreGenericAssembler : public AccessorAssembler { TNode<Object> key, TNode<Object> value, Maybe<LanguageMode> language_mode); - void EmitGenericElementStore(Node* receiver, Node* receiver_map, - Node* instance_type, Node* intptr_index, + void EmitGenericElementStore(Node* receiver, TNode<Map> receiver_map, + Node* instance_type, TNode<IntPtrT> index, Node* value, Node* context, Label* slow); // If language mode is not provided it is deduced from the feedback slot's @@ -82,35 +82,38 @@ class KeyedStoreGenericAssembler : public AccessorAssembler { Nothing<LanguageMode>()); } - void BranchIfPrototypesHaveNonFastElements(Node* receiver_map, + void BranchIfPrototypesHaveNonFastElements(TNode<Map> receiver_map, Label* non_fast_elements, Label* only_fast_elements); - void TryRewriteElements(Node* receiver, Node* receiver_map, Node* elements, - Node* native_context, ElementsKind from_kind, - ElementsKind to_kind, Label* bailout); + void TryRewriteElements(Node* receiver, TNode<Map> receiver_map, + Node* elements, Node* native_context, + ElementsKind from_kind, ElementsKind to_kind, + Label* bailout); - void StoreElementWithCapacity(Node* receiver, Node* receiver_map, - Node* elements, Node* elements_kind, - Node* intptr_index, Node* value, Node* context, - Label* slow, UpdateLength update_length); + void StoreElementWithCapacity(Node* receiver, TNode<Map> receiver_map, + SloppyTNode<FixedArrayBase> elements, + TNode<Word32T> elements_kind, + TNode<IntPtrT> index, Node* value, + Node* context, Label* slow, + UpdateLength update_length); void MaybeUpdateLengthAndReturn(Node* receiver, Node* index, Node* value, UpdateLength update_length); - void TryChangeToHoleyMapHelper(Node* receiver, Node* receiver_map, + void TryChangeToHoleyMapHelper(Node* receiver, TNode<Map> receiver_map, Node* native_context, ElementsKind packed_kind, ElementsKind holey_kind, Label* done, Label* map_mismatch, Label* bailout); - void TryChangeToHoleyMap(Node* receiver, Node* receiver_map, - Node* current_elements_kind, Node* context, + void TryChangeToHoleyMap(Node* receiver, TNode<Map> receiver_map, + TNode<Word32T> current_elements_kind, Node* context, ElementsKind packed_kind, Label* bailout); - void TryChangeToHoleyMapMulti(Node* receiver, Node* receiver_map, - Node* current_elements_kind, Node* context, - ElementsKind packed_kind, + void TryChangeToHoleyMapMulti(Node* receiver, TNode<Map> receiver_map, + TNode<Word32T> current_elements_kind, + Node* context, ElementsKind packed_kind, ElementsKind packed_kind_2, Label* bailout); - void LookupPropertyOnPrototypeChain(Node* receiver_map, Node* name, + void LookupPropertyOnPrototypeChain(TNode<Map> receiver_map, Node* name, Label* accessor, Variable* var_accessor_pair, Variable* var_accessor_holder, @@ -138,10 +141,9 @@ void KeyedStoreGenericGenerator::Generate(compiler::CodeAssemblerState* state) { assembler.KeyedStoreGeneric(); } -void StoreICUninitializedGenerator::Generate( - compiler::CodeAssemblerState* state) { +void StoreICNoFeedbackGenerator::Generate(compiler::CodeAssemblerState* state) { KeyedStoreGenericAssembler assembler(state, StoreMode::kOrdinary); - assembler.StoreIC_Uninitialized(); + assembler.StoreIC_NoFeedback(); } void KeyedStoreGenericGenerator::SetProperty( @@ -169,7 +171,8 @@ void KeyedStoreGenericGenerator::SetPropertyInLiteral( } void KeyedStoreGenericAssembler::BranchIfPrototypesHaveNonFastElements( - Node* receiver_map, Label* non_fast_elements, Label* only_fast_elements) { + TNode<Map> receiver_map, Label* non_fast_elements, + Label* only_fast_elements) { VARIABLE(var_map, MachineRepresentation::kTagged); var_map.Bind(receiver_map); Label loop_body(this, &var_map); @@ -178,11 +181,11 @@ void KeyedStoreGenericAssembler::BranchIfPrototypesHaveNonFastElements( BIND(&loop_body); { Node* map = var_map.value(); - Node* prototype = LoadMapPrototype(map); + TNode<HeapObject> prototype = LoadMapPrototype(map); GotoIf(IsNull(prototype), only_fast_elements); - Node* prototype_map = LoadMap(prototype); + TNode<Map> prototype_map = LoadMap(prototype); var_map.Bind(prototype_map); - TNode<Int32T> instance_type = LoadMapInstanceType(prototype_map); + TNode<Uint16T> instance_type = LoadMapInstanceType(prototype_map); GotoIf(IsCustomElementsReceiverInstanceType(instance_type), non_fast_elements); TNode<Int32T> elements_kind = LoadMapElementsKind(prototype_map); @@ -193,8 +196,9 @@ void KeyedStoreGenericAssembler::BranchIfPrototypesHaveNonFastElements( } void KeyedStoreGenericAssembler::TryRewriteElements( - Node* receiver, Node* receiver_map, Node* elements, Node* native_context, - ElementsKind from_kind, ElementsKind to_kind, Label* bailout) { + Node* receiver, TNode<Map> receiver_map, Node* elements, + Node* native_context, ElementsKind from_kind, ElementsKind to_kind, + Label* bailout) { DCHECK(IsFastPackedElementsKind(from_kind)); ElementsKind holey_from_kind = GetHoleyElementsKind(from_kind); ElementsKind holey_to_kind = GetHoleyElementsKind(to_kind); @@ -205,8 +209,8 @@ void KeyedStoreGenericAssembler::TryRewriteElements( VARIABLE(var_target_map, MachineRepresentation::kTagged); // Check if the receiver has the default |from_kind| map. { - Node* packed_map = LoadJSArrayElementsMap(from_kind, native_context); - GotoIf(WordNotEqual(receiver_map, packed_map), &check_holey_map); + TNode<Map> packed_map = LoadJSArrayElementsMap(from_kind, native_context); + GotoIf(TaggedNotEqual(receiver_map, packed_map), &check_holey_map); var_target_map.Bind( LoadContextElement(native_context, Context::ArrayMapIndex(to_kind))); Goto(&perform_transition); @@ -215,9 +219,9 @@ void KeyedStoreGenericAssembler::TryRewriteElements( // Check if the receiver has the default |holey_from_kind| map. BIND(&check_holey_map); { - Node* holey_map = LoadContextElement( + TNode<Object> holey_map = LoadContextElement( native_context, Context::ArrayMapIndex(holey_from_kind)); - GotoIf(WordNotEqual(receiver_map, holey_map), bailout); + GotoIf(TaggedNotEqual(receiver_map, holey_map), bailout); var_target_map.Bind(LoadContextElement( native_context, Context::ArrayMapIndex(holey_to_kind))); Goto(&perform_transition); @@ -227,7 +231,7 @@ void KeyedStoreGenericAssembler::TryRewriteElements( BIND(&perform_transition); { if (IsDoubleElementsKind(from_kind) != IsDoubleElementsKind(to_kind)) { - Node* capacity = SmiUntag(LoadFixedArrayBaseLength(elements)); + TNode<IntPtrT> capacity = SmiUntag(LoadFixedArrayBaseLength(elements)); GrowElementsCapacity(receiver, elements, from_kind, to_kind, capacity, capacity, INTPTR_PARAMETERS, bailout); } @@ -236,38 +240,39 @@ void KeyedStoreGenericAssembler::TryRewriteElements( } void KeyedStoreGenericAssembler::TryChangeToHoleyMapHelper( - Node* receiver, Node* receiver_map, Node* native_context, + Node* receiver, TNode<Map> receiver_map, Node* native_context, ElementsKind packed_kind, ElementsKind holey_kind, Label* done, Label* map_mismatch, Label* bailout) { - Node* packed_map = LoadJSArrayElementsMap(packed_kind, native_context); - GotoIf(WordNotEqual(receiver_map, packed_map), map_mismatch); + TNode<Map> packed_map = LoadJSArrayElementsMap(packed_kind, native_context); + GotoIf(TaggedNotEqual(receiver_map, packed_map), map_mismatch); if (AllocationSite::ShouldTrack(packed_kind, holey_kind)) { TrapAllocationMemento(receiver, bailout); } - Node* holey_map = + TNode<Object> holey_map = LoadContextElement(native_context, Context::ArrayMapIndex(holey_kind)); StoreMap(receiver, holey_map); Goto(done); } void KeyedStoreGenericAssembler::TryChangeToHoleyMap( - Node* receiver, Node* receiver_map, Node* current_elements_kind, - Node* context, ElementsKind packed_kind, Label* bailout) { + Node* receiver, TNode<Map> receiver_map, + TNode<Word32T> current_elements_kind, Node* context, + ElementsKind packed_kind, Label* bailout) { ElementsKind holey_kind = GetHoleyElementsKind(packed_kind); Label already_holey(this); GotoIf(Word32Equal(current_elements_kind, Int32Constant(holey_kind)), &already_holey); - Node* native_context = LoadNativeContext(context); + TNode<Context> native_context = LoadNativeContext(context); TryChangeToHoleyMapHelper(receiver, receiver_map, native_context, packed_kind, holey_kind, &already_holey, bailout, bailout); BIND(&already_holey); } void KeyedStoreGenericAssembler::TryChangeToHoleyMapMulti( - Node* receiver, Node* receiver_map, Node* current_elements_kind, - Node* context, ElementsKind packed_kind, ElementsKind packed_kind_2, - Label* bailout) { + Node* receiver, TNode<Map> receiver_map, + TNode<Word32T> current_elements_kind, Node* context, + ElementsKind packed_kind, ElementsKind packed_kind_2, Label* bailout) { ElementsKind holey_kind = GetHoleyElementsKind(packed_kind); ElementsKind holey_kind_2 = GetHoleyElementsKind(packed_kind_2); Label already_holey(this), check_other_kind(this); @@ -277,7 +282,7 @@ void KeyedStoreGenericAssembler::TryChangeToHoleyMapMulti( GotoIf(Word32Equal(current_elements_kind, Int32Constant(holey_kind_2)), &already_holey); - Node* native_context = LoadNativeContext(context); + TNode<Context> native_context = LoadNativeContext(context); TryChangeToHoleyMapHelper(receiver, receiver_map, native_context, packed_kind, holey_kind, &already_holey, &check_other_kind, bailout); @@ -291,7 +296,7 @@ void KeyedStoreGenericAssembler::TryChangeToHoleyMapMulti( void KeyedStoreGenericAssembler::MaybeUpdateLengthAndReturn( Node* receiver, Node* index, Node* value, UpdateLength update_length) { if (update_length != kDontChangeLength) { - Node* new_length = SmiTag(Signed(IntPtrAdd(index, IntPtrConstant(1)))); + TNode<Smi> new_length = SmiTag(Signed(IntPtrAdd(index, IntPtrConstant(1)))); StoreObjectFieldNoWriteBarrier(receiver, JSArray::kLengthOffset, new_length, MachineRepresentation::kTagged); } @@ -299,8 +304,9 @@ void KeyedStoreGenericAssembler::MaybeUpdateLengthAndReturn( } void KeyedStoreGenericAssembler::StoreElementWithCapacity( - Node* receiver, Node* receiver_map, Node* elements, Node* elements_kind, - Node* intptr_index, Node* value, Node* context, Label* slow, + Node* receiver, TNode<Map> receiver_map, + SloppyTNode<FixedArrayBase> elements, TNode<Word32T> elements_kind, + TNode<IntPtrT> index, Node* value, Node* context, Label* slow, UpdateLength update_length) { if (update_length != kDontChangeLength) { CSA_ASSERT(this, InstanceTypeEqual(LoadMapInstanceType(receiver_map), @@ -319,14 +325,14 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( const int kHeaderSize = FixedArray::kHeaderSize - kHeapObjectTag; Label check_double_elements(this), check_cow_elements(this); - Node* elements_map = LoadMap(elements); - GotoIf(WordNotEqual(elements_map, LoadRoot(RootIndex::kFixedArrayMap)), + TNode<Map> elements_map = LoadMap(elements); + GotoIf(TaggedNotEqual(elements_map, FixedArrayMapConstant()), &check_double_elements); // FixedArray backing store -> Smi or object elements. { - Node* offset = ElementOffsetFromIndex(intptr_index, PACKED_ELEMENTS, - INTPTR_PARAMETERS, kHeaderSize); + TNode<IntPtrT> offset = ElementOffsetFromIndex( + index, PACKED_ELEMENTS, INTPTR_PARAMETERS, kHeaderSize); // Check if we're about to overwrite the hole. We can safely do that // only if there can be no setters on the prototype chain. // If we know that we're storing beyond the previous array length, we @@ -334,8 +340,9 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( { Label hole_check_passed(this); if (update_length == kDontChangeLength) { - Node* element = Load(MachineType::AnyTagged(), elements, offset); - GotoIf(WordNotEqual(element, TheHoleConstant()), &hole_check_passed); + TNode<Object> element = + CAST(Load(MachineType::AnyTagged(), elements, offset)); + GotoIf(TaggedNotEqual(element, TheHoleConstant()), &hole_check_passed); } BranchIfPrototypesHaveNonFastElements(receiver_map, slow, &hole_check_passed); @@ -354,7 +361,7 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( } StoreNoWriteBarrier(MachineRepresentation::kTaggedSigned, elements, offset, value); - MaybeUpdateLengthAndReturn(receiver, intptr_index, value, update_length); + MaybeUpdateLengthAndReturn(receiver, index, value, update_length); BIND(&non_smi_value); } @@ -372,7 +379,7 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( PACKED_ELEMENTS, slow); } Store(elements, offset, value); - MaybeUpdateLengthAndReturn(receiver, intptr_index, value, update_length); + MaybeUpdateLengthAndReturn(receiver, index, value, update_length); BIND(&must_transition); } @@ -380,8 +387,8 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( // Transition to the required ElementsKind. { Label transition_to_double(this), transition_to_object(this); - Node* native_context = LoadNativeContext(context); - Branch(WordEqual(LoadMap(value), LoadRoot(RootIndex::kHeapNumberMap)), + TNode<Context> native_context = LoadNativeContext(context); + Branch(TaggedEqual(LoadMap(value), HeapNumberMapConstant()), &transition_to_double, &transition_to_object); BIND(&transition_to_double); { @@ -393,16 +400,15 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( TryRewriteElements(receiver, receiver_map, elements, native_context, PACKED_SMI_ELEMENTS, target_kind, slow); // Reload migrated elements. - Node* double_elements = LoadElements(receiver); - Node* double_offset = - ElementOffsetFromIndex(intptr_index, PACKED_DOUBLE_ELEMENTS, - INTPTR_PARAMETERS, kHeaderSize); + TNode<FixedArrayBase> double_elements = LoadElements(receiver); + TNode<IntPtrT> double_offset = ElementOffsetFromIndex( + index, PACKED_DOUBLE_ELEMENTS, INTPTR_PARAMETERS, kHeaderSize); // Make sure we do not store signalling NaNs into double arrays. - Node* double_value = Float64SilenceNaN(LoadHeapNumberValue(value)); + TNode<Float64T> double_value = + Float64SilenceNaN(LoadHeapNumberValue(value)); StoreNoWriteBarrier(MachineRepresentation::kFloat64, double_elements, double_offset, double_value); - MaybeUpdateLengthAndReturn(receiver, intptr_index, value, - update_length); + MaybeUpdateLengthAndReturn(receiver, index, value, update_length); } BIND(&transition_to_object); @@ -415,22 +421,21 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( TryRewriteElements(receiver, receiver_map, elements, native_context, PACKED_SMI_ELEMENTS, target_kind, slow); // The elements backing store didn't change, no reload necessary. - CSA_ASSERT(this, WordEqual(elements, LoadElements(receiver))); + CSA_ASSERT(this, TaggedEqual(elements, LoadElements(receiver))); Store(elements, offset, value); - MaybeUpdateLengthAndReturn(receiver, intptr_index, value, - update_length); + MaybeUpdateLengthAndReturn(receiver, index, value, update_length); } } } BIND(&check_double_elements); - Node* fixed_double_array_map = LoadRoot(RootIndex::kFixedDoubleArrayMap); - GotoIf(WordNotEqual(elements_map, fixed_double_array_map), + TNode<Map> fixed_double_array_map = FixedDoubleArrayMapConstant(); + GotoIf(TaggedNotEqual(elements_map, fixed_double_array_map), &check_cow_elements); // FixedDoubleArray backing store -> double elements. { - Node* offset = ElementOffsetFromIndex(intptr_index, PACKED_DOUBLE_ELEMENTS, - INTPTR_PARAMETERS, kHeaderSize); + TNode<IntPtrT> offset = ElementOffsetFromIndex( + index, PACKED_DOUBLE_ELEMENTS, INTPTR_PARAMETERS, kHeaderSize); // Check if we're about to overwrite the hole. We can safely do that // only if there can be no setters on the prototype chain. { @@ -463,25 +468,25 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( } StoreNoWriteBarrier(MachineRepresentation::kFloat64, elements, offset, double_value); - MaybeUpdateLengthAndReturn(receiver, intptr_index, value, update_length); + MaybeUpdateLengthAndReturn(receiver, index, value, update_length); BIND(&non_number_value); } // Transition to object elements. { - Node* native_context = LoadNativeContext(context); + TNode<Context> native_context = LoadNativeContext(context); ElementsKind target_kind = update_length == kBumpLengthWithGap ? HOLEY_ELEMENTS : PACKED_ELEMENTS; TryRewriteElements(receiver, receiver_map, elements, native_context, PACKED_DOUBLE_ELEMENTS, target_kind, slow); // Reload migrated elements. - Node* fast_elements = LoadElements(receiver); - Node* fast_offset = ElementOffsetFromIndex( - intptr_index, PACKED_ELEMENTS, INTPTR_PARAMETERS, kHeaderSize); + TNode<FixedArrayBase> fast_elements = LoadElements(receiver); + TNode<IntPtrT> fast_offset = ElementOffsetFromIndex( + index, PACKED_ELEMENTS, INTPTR_PARAMETERS, kHeaderSize); Store(fast_elements, fast_offset, value); - MaybeUpdateLengthAndReturn(receiver, intptr_index, value, update_length); + MaybeUpdateLengthAndReturn(receiver, index, value, update_length); } } @@ -493,13 +498,13 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( } void KeyedStoreGenericAssembler::EmitGenericElementStore( - Node* receiver, Node* receiver_map, Node* instance_type, Node* intptr_index, - Node* value, Node* context, Label* slow) { + Node* receiver, TNode<Map> receiver_map, Node* instance_type, + TNode<IntPtrT> index, Node* value, Node* context, Label* slow) { Label if_fast(this), if_in_bounds(this), if_out_of_bounds(this), if_increment_length_by_one(this), if_bump_length_with_gap(this), if_grow(this), if_nonfast(this), if_typed_array(this), if_dictionary(this); - Node* elements = LoadElements(receiver); + TNode<FixedArrayBase> elements = LoadElements(receiver); TNode<Int32T> elements_kind = LoadMapElementsKind(receiver_map); Branch(IsFastElementsKind(elements_kind), &if_fast, &if_nonfast); BIND(&if_fast); @@ -507,25 +512,23 @@ void KeyedStoreGenericAssembler::EmitGenericElementStore( Label if_array(this); GotoIf(InstanceTypeEqual(instance_type, JS_ARRAY_TYPE), &if_array); { - Node* capacity = SmiUntag(LoadFixedArrayBaseLength(elements)); - Branch(UintPtrLessThan(intptr_index, capacity), &if_in_bounds, - &if_out_of_bounds); + TNode<IntPtrT> capacity = SmiUntag(LoadFixedArrayBaseLength(elements)); + Branch(UintPtrLessThan(index, capacity), &if_in_bounds, &if_out_of_bounds); } BIND(&if_array); { - Node* length = SmiUntag(LoadFastJSArrayLength(receiver)); - GotoIf(UintPtrLessThan(intptr_index, length), &if_in_bounds); - Node* capacity = SmiUntag(LoadFixedArrayBaseLength(elements)); - GotoIf(UintPtrGreaterThanOrEqual(intptr_index, capacity), &if_grow); - Branch(WordEqual(intptr_index, length), &if_increment_length_by_one, + TNode<IntPtrT> length = SmiUntag(LoadFastJSArrayLength(receiver)); + GotoIf(UintPtrLessThan(index, length), &if_in_bounds); + TNode<IntPtrT> capacity = SmiUntag(LoadFixedArrayBaseLength(elements)); + GotoIf(UintPtrGreaterThanOrEqual(index, capacity), &if_grow); + Branch(WordEqual(index, length), &if_increment_length_by_one, &if_bump_length_with_gap); } BIND(&if_in_bounds); { StoreElementWithCapacity(receiver, receiver_map, elements, elements_kind, - intptr_index, value, context, slow, - kDontChangeLength); + index, value, context, slow, kDontChangeLength); } BIND(&if_out_of_bounds); @@ -541,15 +544,14 @@ void KeyedStoreGenericAssembler::EmitGenericElementStore( BIND(&if_increment_length_by_one); { StoreElementWithCapacity(receiver, receiver_map, elements, elements_kind, - intptr_index, value, context, slow, + index, value, context, slow, kIncrementLengthByOne); } BIND(&if_bump_length_with_gap); { StoreElementWithCapacity(receiver, receiver_map, elements, elements_kind, - intptr_index, value, context, slow, - kBumpLengthWithGap); + index, value, context, slow, kBumpLengthWithGap); } // Out-of-capacity accesses (index >= capacity) jump here. Additionally, @@ -593,7 +595,7 @@ void KeyedStoreGenericAssembler::EmitGenericElementStore( } void KeyedStoreGenericAssembler::LookupPropertyOnPrototypeChain( - Node* receiver_map, Node* name, Label* accessor, + TNode<Map> receiver_map, Node* name, Label* accessor, Variable* var_accessor_pair, Variable* var_accessor_holder, Label* readonly, Label* bailout) { Label ok_to_write(this); @@ -610,7 +612,7 @@ void KeyedStoreGenericAssembler::LookupPropertyOnPrototypeChain( Node* holder = var_holder.value(); GotoIf(IsNull(holder), &ok_to_write); Node* holder_map = var_holder_map.value(); - Node* instance_type = LoadMapInstanceType(holder_map); + TNode<Uint16T> instance_type = LoadMapInstanceType(holder_map); Label next_proto(this); { Label found(this), found_fast(this), found_dict(this), found_global(this); @@ -623,7 +625,7 @@ void KeyedStoreGenericAssembler::LookupPropertyOnPrototypeChain( { TNode<DescriptorArray> descriptors = CAST(var_meta_storage.value()); TNode<IntPtrT> name_index = var_entry.value(); - Node* details = LoadDetailsByKeyIndex(descriptors, name_index); + TNode<Uint32T> details = LoadDetailsByKeyIndex(descriptors, name_index); JumpIfDataProperty(details, &ok_to_write, readonly); // Accessor case. @@ -638,9 +640,9 @@ void KeyedStoreGenericAssembler::LookupPropertyOnPrototypeChain( BIND(&found_dict); { - Node* dictionary = var_meta_storage.value(); - Node* entry = var_entry.value(); - Node* details = + TNode<HeapObject> dictionary = var_meta_storage.value(); + TNode<IntPtrT> entry = var_entry.value(); + TNode<Uint32T> details = LoadDetailsByKeyIndex<NameDictionary>(dictionary, entry); JumpIfDataProperty(details, &ok_to_write, readonly); @@ -657,14 +659,14 @@ void KeyedStoreGenericAssembler::LookupPropertyOnPrototypeChain( BIND(&found_global); { - Node* dictionary = var_meta_storage.value(); - Node* entry = var_entry.value(); - Node* property_cell = - LoadValueByKeyIndex<GlobalDictionary>(dictionary, entry); - Node* value = + TNode<HeapObject> dictionary = var_meta_storage.value(); + TNode<IntPtrT> entry = var_entry.value(); + TNode<PropertyCell> property_cell = + CAST(LoadValueByKeyIndex<GlobalDictionary>(dictionary, entry)); + TNode<Object> value = LoadObjectField(property_cell, PropertyCell::kValueOffset); - GotoIf(WordEqual(value, TheHoleConstant()), &next_proto); - Node* details = LoadAndUntagToWord32ObjectField( + GotoIf(TaggedEqual(value, TheHoleConstant()), &next_proto); + TNode<Int32T> details = LoadAndUntagToWord32ObjectField( property_cell, PropertyCell::kPropertyDetailsRawOffset); JumpIfDataProperty(details, &ok_to_write, readonly); @@ -682,7 +684,7 @@ void KeyedStoreGenericAssembler::LookupPropertyOnPrototypeChain( BIND(&next_proto); // Bailout if it can be an integer indexed exotic case. GotoIf(InstanceTypeEqual(instance_type, JS_TYPED_ARRAY_TYPE), bailout); - Node* proto = LoadMapPrototype(holder_map); + TNode<HeapObject> proto = LoadMapPrototype(holder_map); GotoIf(IsNull(proto), &ok_to_write); var_holder.Bind(proto); var_holder_map.Bind(LoadMap(proto)); @@ -765,7 +767,8 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( VARIABLE(var_accessor_holder, MachineRepresentation::kTagged); Label fast_properties(this), dictionary_properties(this), accessor(this), readonly(this); - Node* bitfield3 = LoadMapBitField3(receiver_map); + TNode<Uint32T> bitfield3 = LoadMapBitField3(receiver_map); + TNode<Name> name = CAST(p->name()); Branch(IsSetWord32<Map::IsDictionaryMapBit>(bitfield3), &dictionary_properties, &fast_properties); @@ -775,13 +778,13 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( TNode<DescriptorArray> descriptors = LoadMapDescriptors(receiver_map); Label descriptor_found(this), lookup_transition(this); TVARIABLE(IntPtrT, var_name_index); - DescriptorLookup(p->name(), descriptors, bitfield3, &descriptor_found, + DescriptorLookup(name, descriptors, bitfield3, &descriptor_found, &var_name_index, &lookup_transition); BIND(&descriptor_found); { TNode<IntPtrT> name_index = var_name_index.value(); - Node* details = LoadDetailsByKeyIndex(descriptors, name_index); + TNode<Uint32T> details = LoadDetailsByKeyIndex(descriptors, name_index); Label data_property(this); JumpIfDataProperty(details, &data_property, ShouldReconfigureExisting() ? nullptr : &readonly); @@ -796,12 +799,13 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( var_accessor_holder.Bind(receiver); Goto(&accessor); } else { - Goto(&data_property); + // Handle accessor to data property reconfiguration in runtime. + Goto(slow); } BIND(&data_property); { - CheckForAssociatedProtector(p->name(), slow); + CheckForAssociatedProtector(name, slow); OverwriteExistingFastDataProperty(receiver, receiver_map, descriptors, name_index, details, p->value(), slow, false); @@ -811,8 +815,8 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( BIND(&lookup_transition); { Comment("lookup transition"); - TNode<Map> transition_map = FindCandidateStoreICTransitionMapHandler( - receiver_map, CAST(p->name()), slow); + TNode<Map> transition_map = + FindCandidateStoreICTransitionMapHandler(receiver_map, name, slow); // Validate the transition handler candidate and apply the transition. StoreTransitionMapFlags flags = kValidateTransitionHandler; @@ -833,9 +837,8 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( TVARIABLE(IntPtrT, var_name_index); Label dictionary_found(this, &var_name_index), not_found(this); TNode<NameDictionary> properties = CAST(LoadSlowProperties(CAST(receiver))); - NameDictionaryLookup<NameDictionary>(properties, CAST(p->name()), - &dictionary_found, &var_name_index, - ¬_found); + NameDictionaryLookup<NameDictionary>(properties, name, &dictionary_found, + &var_name_index, ¬_found); BIND(&dictionary_found); { Label overwrite(this); @@ -858,7 +861,7 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( BIND(&overwrite); { - CheckForAssociatedProtector(p->name(), slow); + CheckForAssociatedProtector(name, slow); StoreValueByKeyIndex<NameDictionary>(properties, var_name_index.value(), p->value()); exit_point->Return(p->value()); @@ -867,37 +870,37 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( BIND(¬_found); { - CheckForAssociatedProtector(p->name(), slow); + CheckForAssociatedProtector(name, slow); Label extensible(this), is_private_symbol(this); - Node* bitfield3 = LoadMapBitField3(receiver_map); - GotoIf(IsPrivateSymbol(p->name()), &is_private_symbol); + TNode<Uint32T> bitfield3 = LoadMapBitField3(receiver_map); + GotoIf(IsPrivateSymbol(name), &is_private_symbol); Branch(IsSetWord32<Map::IsExtensibleBit>(bitfield3), &extensible, slow); BIND(&is_private_symbol); { - CSA_ASSERT(this, IsPrivateSymbol(p->name())); + CSA_ASSERT(this, IsPrivateSymbol(name)); // For private names, we miss to the runtime which will throw. // For private symbols, we extend and store an own property. - Branch(IsPrivateName(p->name()), slow, &extensible); + Branch(IsPrivateName(CAST(name)), slow, &extensible); } BIND(&extensible); if (ShouldCheckPrototype()) { DCHECK(ShouldCallSetter()); LookupPropertyOnPrototypeChain( - receiver_map, p->name(), &accessor, &var_accessor_pair, + receiver_map, name, &accessor, &var_accessor_pair, &var_accessor_holder, ShouldReconfigureExisting() ? nullptr : &readonly, slow); } Label add_dictionary_property_slow(this); InvalidateValidityCellIfPrototype(receiver_map, bitfield3); - Add<NameDictionary>(properties, CAST(p->name()), p->value(), + Add<NameDictionary>(properties, name, p->value(), &add_dictionary_property_slow); exit_point->Return(p->value()); BIND(&add_dictionary_property_slow); exit_point->ReturnCallRuntime(Runtime::kAddDictionaryProperty, - p->context(), p->receiver(), p->name(), + p->context(), p->receiver(), name, p->value()); } } @@ -909,9 +912,9 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( Node* accessor_pair = var_accessor_pair.value(); GotoIf(IsAccessorInfoMap(LoadMap(accessor_pair)), slow); CSA_ASSERT(this, HasInstanceType(accessor_pair, ACCESSOR_PAIR_TYPE)); - Node* setter = - LoadObjectField(accessor_pair, AccessorPair::kSetterOffset); - Node* setter_map = LoadMap(setter); + TNode<HeapObject> setter = + CAST(LoadObjectField(accessor_pair, AccessorPair::kSetterOffset)); + TNode<Map> setter_map = LoadMap(setter); // FunctionTemplateInfo setters are not supported yet. GotoIf(IsFunctionTemplateInfoMap(setter_map), slow); GotoIfNot(IsCallableMap(setter_map), ¬_callable); @@ -927,15 +930,15 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( if (language_mode == LanguageMode::kStrict) { exit_point->ReturnCallRuntime( Runtime::kThrowTypeError, p->context(), - SmiConstant(MessageTemplate::kNoSetterInCallback), p->name(), + SmiConstant(MessageTemplate::kNoSetterInCallback), name, var_accessor_holder.value()); } else { exit_point->Return(p->value()); } } else { CallRuntime(Runtime::kThrowTypeErrorIfStrict, p->context(), - SmiConstant(MessageTemplate::kNoSetterInCallback), - p->name(), var_accessor_holder.value()); + SmiConstant(MessageTemplate::kNoSetterInCallback), name, + var_accessor_holder.value()); exit_point->Return(p->value()); } } @@ -950,14 +953,14 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( if (language_mode == LanguageMode::kStrict) { Node* type = Typeof(p->receiver()); ThrowTypeError(p->context(), MessageTemplate::kStrictReadOnlyProperty, - p->name(), type, p->receiver()); + name, type, p->receiver()); } else { exit_point->Return(p->value()); } } else { CallRuntime(Runtime::kThrowTypeErrorIfStrict, p->context(), - SmiConstant(MessageTemplate::kStrictReadOnlyProperty), - p->name(), Typeof(p->receiver()), p->receiver()); + SmiConstant(MessageTemplate::kStrictReadOnlyProperty), name, + Typeof(p->receiver()), p->receiver()); exit_point->Return(p->value()); } } @@ -975,7 +978,7 @@ void KeyedStoreGenericAssembler::KeyedStoreGeneric( GotoIf(TaggedIsSmi(receiver), &slow); TNode<Map> receiver_map = LoadMap(CAST(receiver)); - TNode<Int32T> instance_type = LoadMapInstanceType(receiver_map); + TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map); // Receivers requiring non-standard element accesses (interceptors, access // checks, strings and string wrappers, proxies) are handled in the runtime. GotoIf(IsCustomElementsReceiverInstanceType(instance_type), &slow); @@ -1043,51 +1046,33 @@ void KeyedStoreGenericAssembler::SetProperty(TNode<Context> context, KeyedStoreGeneric(context, receiver, key, value, Just(language_mode)); } -void KeyedStoreGenericAssembler::StoreIC_Uninitialized() { - using Descriptor = StoreWithVectorDescriptor; +void KeyedStoreGenericAssembler::StoreIC_NoFeedback() { + using Descriptor = StoreDescriptor; Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); + TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* value = Parameter(Descriptor::kValue); Node* slot = Parameter(Descriptor::kSlot); - Node* vector = Parameter(Descriptor::kVector); Node* context = Parameter(Descriptor::kContext); Label miss(this, Label::kDeferred), store_property(this); GotoIf(TaggedIsSmi(receiver), &miss); - Node* receiver_map = LoadMap(receiver); - TNode<Int32T> instance_type = LoadMapInstanceType(receiver_map); + TNode<Map> receiver_map = LoadMap(receiver); + TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map); // Receivers requiring non-standard element accesses (interceptors, access // checks, strings and string wrappers, proxies) are handled in the runtime. GotoIf(IsSpecialReceiverInstanceType(instance_type), &miss); - - // Optimistically write the state transition to the vector. - GotoIf(IsUndefined(vector), &store_property); - StoreFeedbackVectorSlot(vector, slot, - LoadRoot(RootIndex::kpremonomorphic_symbol), - SKIP_WRITE_BARRIER, 0, SMI_PARAMETERS); - Goto(&store_property); - - BIND(&store_property); { - StoreICParameters p(CAST(context), receiver, name, value, slot, vector); + StoreICParameters p(CAST(context), receiver, name, value, slot, + UndefinedConstant()); EmitGenericPropertyStore(receiver, receiver_map, &p, &miss); } BIND(&miss); { - Label call_runtime(this); - // Undo the optimistic state transition. - GotoIf(IsUndefined(vector), &call_runtime); - StoreFeedbackVectorSlot(vector, slot, - LoadRoot(RootIndex::kuninitialized_symbol), - SKIP_WRITE_BARRIER, 0, SMI_PARAMETERS); - Goto(&call_runtime); - - BIND(&call_runtime); - TailCallRuntime(Runtime::kStoreIC_Miss, context, value, slot, vector, - receiver, name); + TailCallRuntime(Runtime::kStoreIC_Miss, context, value, slot, + UndefinedConstant(), receiver, name); } } diff --git a/deps/v8/src/ic/keyed-store-generic.h b/deps/v8/src/ic/keyed-store-generic.h index 322bb63321..efee0da80e 100644 --- a/deps/v8/src/ic/keyed-store-generic.h +++ b/deps/v8/src/ic/keyed-store-generic.h @@ -37,7 +37,7 @@ class KeyedStoreGenericGenerator { TNode<Object> value); }; -class StoreICUninitializedGenerator { +class StoreICNoFeedbackGenerator { public: static void Generate(compiler::CodeAssemblerState* state); }; |