summaryrefslogtreecommitdiff
path: root/deps/v8/src/ic
diff options
context:
space:
mode:
authorMyles Borins <mylesborins@google.com>2019-09-24 11:56:38 -0400
committerMyles Borins <myles.borins@gmail.com>2019-10-07 03:19:23 -0400
commitf7f6c928c1c9c136b7926f892b8a2fda11d8b4b2 (patch)
treef5edbccb3ffda2573d70a6e291e7157f290e0ae0 /deps/v8/src/ic
parentffd22e81983056d09c064c59343a0e488236272d (diff)
downloadandroid-node-v8-f7f6c928c1c9c136b7926f892b8a2fda11d8b4b2.tar.gz
android-node-v8-f7f6c928c1c9c136b7926f892b8a2fda11d8b4b2.tar.bz2
android-node-v8-f7f6c928c1c9c136b7926f892b8a2fda11d8b4b2.zip
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/OWNERS1
-rw-r--r--deps/v8/src/ic/accessor-assembler.cc803
-rw-r--r--deps/v8/src/ic/accessor-assembler.h50
-rw-r--r--deps/v8/src/ic/binary-op-assembler.cc33
-rw-r--r--deps/v8/src/ic/handler-configuration-inl.h4
-rw-r--r--deps/v8/src/ic/handler-configuration.cc41
-rw-r--r--deps/v8/src/ic/handler-configuration.h76
-rw-r--r--deps/v8/src/ic/ic.cc90
-rw-r--r--deps/v8/src/ic/keyed-store-generic.cc309
-rw-r--r--deps/v8/src/ic/keyed-store-generic.h2
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) {
&not_function_prototype);
GotoIfNot(IsPrototypeString(p->name()), &not_function_prototype);
- GotoIfPrototypeRequiresRuntimeLookup(CAST(receiver), CAST(receiver_map),
+ GotoIfPrototypeRequiresRuntimeLookup(CAST(receiver), receiver_map,
&not_function_prototype);
- Return(LoadJSFunctionPrototype(receiver, &miss));
+ Return(LoadJSFunctionPrototype(CAST(receiver), &miss));
BIND(&not_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(&not_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,
- &not_found);
+ NameDictionaryLookup<NameDictionary>(properties, name, &dictionary_found,
+ &var_name_index, &not_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(&not_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), &not_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);
};