diff options
author | Michaël Zasso <targos@protonmail.com> | 2018-09-07 17:07:13 +0200 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2018-09-07 20:59:13 +0200 |
commit | 586db2414a338e1bf6eaf6e672a3adc7ce309f6a (patch) | |
tree | 139fa972aef648481ddee22a3a85b99707d28df5 /deps/v8/src/ic | |
parent | 12ed7c94e5160aa6d38e3d2cb2a73dae0a6f9342 (diff) | |
download | android-node-v8-586db2414a338e1bf6eaf6e672a3adc7ce309f6a.tar.gz android-node-v8-586db2414a338e1bf6eaf6e672a3adc7ce309f6a.tar.bz2 android-node-v8-586db2414a338e1bf6eaf6e672a3adc7ce309f6a.zip |
deps: update V8 to 6.9.427.22
PR-URL: https://github.com/nodejs/node/pull/21983
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Diffstat (limited to 'deps/v8/src/ic')
-rw-r--r-- | deps/v8/src/ic/accessor-assembler.cc | 446 | ||||
-rw-r--r-- | deps/v8/src/ic/accessor-assembler.h | 30 | ||||
-rw-r--r-- | deps/v8/src/ic/call-optimization.cc | 33 | ||||
-rw-r--r-- | deps/v8/src/ic/call-optimization.h | 10 | ||||
-rw-r--r-- | deps/v8/src/ic/handler-configuration-inl.h | 5 | ||||
-rw-r--r-- | deps/v8/src/ic/handler-configuration.cc | 8 | ||||
-rw-r--r-- | deps/v8/src/ic/ic-inl.h | 6 | ||||
-rw-r--r-- | deps/v8/src/ic/ic.cc | 180 | ||||
-rw-r--r-- | deps/v8/src/ic/ic.h | 5 | ||||
-rw-r--r-- | deps/v8/src/ic/keyed-store-generic.cc | 18 | ||||
-rw-r--r-- | deps/v8/src/ic/stub-cache.cc | 25 | ||||
-rw-r--r-- | deps/v8/src/ic/stub-cache.h | 6 |
12 files changed, 373 insertions, 399 deletions
diff --git a/deps/v8/src/ic/accessor-assembler.cc b/deps/v8/src/ic/accessor-assembler.cc index a40ec297a6..f471381dd8 100644 --- a/deps/v8/src/ic/accessor-assembler.cc +++ b/deps/v8/src/ic/accessor-assembler.cc @@ -11,6 +11,7 @@ #include "src/ic/ic.h" #include "src/ic/stub-cache.h" #include "src/objects-inl.h" +#include "src/objects/module.h" namespace v8 { namespace internal { @@ -25,7 +26,7 @@ using SloppyTNode = compiler::SloppyTNode<T>; //////////////////// Private helpers. // Loads dataX field from the DataHandler object. -TNode<Object> AccessorAssembler::LoadHandlerDataField( +TNode<MaybeObject> AccessorAssembler::LoadHandlerDataField( SloppyTNode<DataHandler> handler, int data_index) { #ifdef DEBUG TNode<Map> handler_map = LoadMap(handler); @@ -57,14 +58,12 @@ TNode<Object> AccessorAssembler::LoadHandlerDataField( CSA_ASSERT(this, UintPtrGreaterThanOrEqual( LoadMapInstanceSizeInWords(handler_map), IntPtrConstant(minimum_size / kPointerSize))); - return LoadObjectField(handler, offset); + return LoadMaybeWeakObjectField(handler, offset); } -Node* AccessorAssembler::TryMonomorphicCase(Node* slot, Node* vector, - Node* receiver_map, - Label* if_handler, - TVariable<MaybeObject>* var_handler, - Label* if_miss) { +TNode<MaybeObject> AccessorAssembler::TryMonomorphicCase( + Node* slot, Node* vector, Node* receiver_map, Label* if_handler, + TVariable<MaybeObject>* var_handler, Label* if_miss) { Comment("TryMonomorphicCase"); DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); @@ -76,15 +75,13 @@ Node* AccessorAssembler::TryMonomorphicCase(Node* slot, Node* vector, // 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<Object> feedback = - CAST(Load(MachineType::AnyTagged(), vector, - IntPtrAdd(offset, IntPtrConstant(header_size)))); + TNode<MaybeObject> feedback = ReinterpretCast<MaybeObject>( + Load(MachineType::AnyTagged(), vector, + IntPtrAdd(offset, IntPtrConstant(header_size)))); // Try to quickly handle the monomorphic case without knowing for sure - // if we have a weak cell in feedback. We do know it's safe to look - // at WeakCell::kValueOffset. - GotoIf(WordNotEqual(receiver_map, LoadWeakCellValueUnchecked(CAST(feedback))), - if_miss); + // if we have a weak reference in feedback. + GotoIf(IsNotWeakReferenceTo(feedback, CAST(receiver_map)), if_miss); TNode<MaybeObject> handler = UncheckedCast<MaybeObject>( Load(MachineType::AnyTagged(), vector, @@ -128,10 +125,11 @@ void AccessorAssembler::HandlePolymorphicCase( } Label next_entry(this); - TNode<MaybeObject> element = LoadWeakFixedArrayElement(feedback, map_index); - CSA_ASSERT(this, IsStrongHeapObject(element)); - Node* cached_map = LoadWeakCellValue(CAST(ToStrongHeapObject(element))); - GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry); + TNode<MaybeObject> maybe_cached_map = + LoadWeakFixedArrayElement(feedback, map_index); + CSA_ASSERT(this, IsWeakOrClearedHeapObject(maybe_cached_map)); + GotoIf(IsNotWeakReferenceTo(maybe_cached_map, CAST(receiver_map)), + &next_entry); // Found, now call handler. TNode<MaybeObject> handler = @@ -150,12 +148,12 @@ void AccessorAssembler::HandlePolymorphicCase( BuildFastLoop( start_index, end_index, [this, receiver_map, feedback, if_handler, var_handler](Node* index) { - TNode<MaybeObject> element = LoadWeakFixedArrayElement(feedback, index); - CSA_ASSERT(this, IsStrongHeapObject(element)); - Node* cached_map = LoadWeakCellValue(CAST(ToStrongHeapObject(element))); - Label next_entry(this); - GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry); + TNode<MaybeObject> maybe_cached_map = + LoadWeakFixedArrayElement(feedback, index); + CSA_ASSERT(this, IsWeakOrClearedHeapObject(maybe_cached_map)); + GotoIf(IsNotWeakReferenceTo(maybe_cached_map, CAST(receiver_map)), + &next_entry); // Found, now call handler. TNode<MaybeObject> handler = @@ -175,7 +173,6 @@ void AccessorAssembler::HandleLoadICHandlerCase( ExitPoint* exit_point, ICMode ic_mode, OnNonExistent on_nonexistent, ElementSupport support_elements) { Comment("have_handler"); - CSA_ASSERT(this, IsObject(handler)); VARIABLE(var_holder, MachineRepresentation::kTagged, p->holder); VARIABLE(var_smi_handler, MachineRepresentation::kTagged, handler); @@ -205,8 +202,7 @@ void AccessorAssembler::HandleLoadICHandlerCase( BIND(&call_handler); { - typedef LoadWithVectorDescriptor Descriptor; - exit_point->ReturnCallStub(Descriptor(isolate()), handler, p->context, + exit_point->ReturnCallStub(LoadWithVectorDescriptor{}, handler, p->context, p->receiver, p->name, p->slot, p->vector); } } @@ -254,16 +250,22 @@ void AccessorAssembler::HandleLoadField(Node* holder, Node* handler_word, } } -Node* AccessorAssembler::LoadDescriptorValue(Node* map, Node* descriptor) { - Node* descriptors = LoadMapDescriptors(map); +TNode<Object> AccessorAssembler::LoadDescriptorValue(Node* map, + Node* descriptor) { + return CAST(LoadDescriptorValueOrFieldType(map, descriptor)); +} + +TNode<MaybeObject> AccessorAssembler::LoadDescriptorValueOrFieldType( + Node* map, Node* descriptor) { + TNode<DescriptorArray> descriptors = LoadMapDescriptors(map); Node* scaled_descriptor = IntPtrMul(descriptor, IntPtrConstant(DescriptorArray::kEntrySize)); Node* value_index = IntPtrAdd( scaled_descriptor, IntPtrConstant(DescriptorArray::kFirstIndex + DescriptorArray::kEntryValueIndex)); - CSA_ASSERT(this, UintPtrLessThan(descriptor, LoadAndUntagFixedArrayBaseLength( + CSA_ASSERT(this, UintPtrLessThan(descriptor, LoadAndUntagWeakFixedArrayLength( descriptors))); - return LoadFixedArrayElement(descriptors, value_index); + return LoadWeakFixedArrayElement(descriptors, value_index); } void AccessorAssembler::HandleLoadICSmiHandlerCase( @@ -479,8 +481,8 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( // the access check is enabled for this handler or not. TNode<Object> context_cell = Select<Object>( IsSetWord<LoadHandler::DoAccessCheckOnReceiverBits>(handler_word), - [=] { return LoadHandlerDataField(handler, 3); }, - [=] { return LoadHandlerDataField(handler, 2); }); + [=] { return CAST(LoadHandlerDataField(handler, 3)); }, + [=] { return CAST(LoadHandlerDataField(handler, 2)); }); Node* context = LoadWeakCellValueUnchecked(CAST(context_cell)); Node* foreign = @@ -518,13 +520,16 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( to_name_failed(this, Label::kDeferred); if (support_elements == kSupportElements) { + DCHECK_NE(on_nonexistent, OnNonExistent::kThrowReferenceError); + TryToName(p->name, &if_index, &var_index, &if_unique_name, &var_unique, &to_name_failed); BIND(&if_unique_name); exit_point->ReturnCallStub( Builtins::CallableFor(isolate(), Builtins::kProxyGetProperty), - p->context, holder, var_unique.value(), p->receiver); + p->context, holder, var_unique.value(), p->receiver, + SmiConstant(on_nonexistent)); BIND(&if_index); // TODO(mslekova): introduce TryToName that doesn't try to compute @@ -533,12 +538,13 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( BIND(&to_name_failed); exit_point->ReturnCallRuntime(Runtime::kGetPropertyWithReceiver, - p->context, holder, p->name, p->receiver); - + p->context, holder, p->name, p->receiver, + SmiConstant(on_nonexistent)); } else { exit_point->ReturnCallStub( Builtins::CallableFor(isolate(), Builtins::kProxyGetProperty), - p->context, holder, p->name, p->receiver); + p->context, holder, p->name, p->receiver, + SmiConstant(on_nonexistent)); } } @@ -664,7 +670,7 @@ Node* AccessorAssembler::HandleProtoHandler( BIND(&if_do_access_check); { - Node* data2 = LoadHandlerDataField(handler, 2); + TNode<WeakCell> data2 = CAST(LoadHandlerDataField(handler, 2)); Node* expected_native_context = LoadWeakCellValue(data2, miss); EmitAccessCheck(expected_native_context, p->context, p->receiver, &done, miss); @@ -725,7 +731,7 @@ void AccessorAssembler::HandleLoadICProtoHandler( }, miss, ic_mode); - Node* maybe_holder_cell = LoadHandlerDataField(handler, 1); + TNode<Object> maybe_holder_cell = CAST(LoadHandlerDataField(handler, 1)); Label load_from_cached_holder(this), done(this); @@ -736,7 +742,7 @@ void AccessorAssembler::HandleLoadICProtoHandler( // For regular holders, having passed the receiver map check and the // validity cell check implies that |holder| is alive. However, for // global object receivers, the |maybe_holder_cell| may be cleared. - Node* holder = LoadWeakCellValue(maybe_holder_cell, miss); + Node* holder = LoadWeakCellValue(CAST(maybe_holder_cell), miss); var_holder->Bind(holder); Goto(&done); @@ -803,8 +809,7 @@ void AccessorAssembler::HandleStoreICHandlerCase( BIND(&if_smi_handler); { Node* holder = p->receiver; - CSA_ASSERT(this, IsObject(handler)); - Node* handler_word = SmiUntag(CAST(ToObject(handler))); + Node* handler_word = SmiUntag(CAST(handler)); Label if_fast_smi(this), if_proxy(this); @@ -870,8 +875,7 @@ void AccessorAssembler::HandleStoreICHandlerCase( BIND(&if_nonsmi_handler); { GotoIf(IsWeakOrClearedHeapObject(handler), &store_transition_or_global); - CSA_ASSERT(this, IsStrongHeapObject(handler)); - TNode<HeapObject> strong_handler = ToStrongHeapObject(handler); + TNode<HeapObject> strong_handler = CAST(handler); TNode<Map> handler_map = LoadMap(strong_handler); Branch(IsCodeMap(handler_map), &call_handler, &if_proto_handler); @@ -884,9 +888,9 @@ void AccessorAssembler::HandleStoreICHandlerCase( // |handler| is a heap object. Must be code, call it. BIND(&call_handler); { - StoreWithVectorDescriptor descriptor(isolate()); - TailCallStub(descriptor, strong_handler, p->context, p->receiver, p->name, - p->value, p->slot, p->vector); + TailCallStub(StoreWithVectorDescriptor{}, CAST(strong_handler), + CAST(p->context), p->receiver, p->name, p->value, p->slot, + p->vector); } } @@ -929,21 +933,21 @@ void AccessorAssembler::HandleStoreICTransitionMapHandlerCase( // Load last descriptor details. Node* nof = DecodeWordFromWord32<Map::NumberOfOwnDescriptorsBits>(bitfield3); CSA_ASSERT(this, WordNotEqual(nof, IntPtrConstant(0))); - Node* descriptors = LoadMapDescriptors(transition_map); + TNode<DescriptorArray> descriptors = LoadMapDescriptors(transition_map); Node* factor = IntPtrConstant(DescriptorArray::kEntrySize); - Node* last_key_index = IntPtrAdd( - IntPtrConstant(DescriptorArray::ToKeyIndex(-1)), IntPtrMul(nof, factor)); + TNode<IntPtrT> last_key_index = UncheckedCast<IntPtrT>(IntPtrAdd( + IntPtrConstant(DescriptorArray::ToKeyIndex(-1)), IntPtrMul(nof, factor))); if (validate_transition_handler) { - Node* key = LoadFixedArrayElement(descriptors, last_key_index); + Node* key = LoadWeakFixedArrayElement(descriptors, last_key_index); GotoIf(WordNotEqual(key, p->name), miss); } else { - CSA_ASSERT( - this, - WordEqual(LoadFixedArrayElement(descriptors, last_key_index), p->name)); + CSA_ASSERT(this, + WordEqual(BitcastMaybeObjectToWord(LoadWeakFixedArrayElement( + descriptors, last_key_index)), + p->name)); } - Node* details = - LoadDetailsByKeyIndex<DescriptorArray>(descriptors, last_key_index); + Node* details = LoadDetailsByKeyIndex(descriptors, last_key_index); if (validate_transition_handler) { // Follow transitions only in the following cases: // 1) name is a non-private symbol and attributes equal to NONE, @@ -969,9 +973,9 @@ void AccessorAssembler::HandleStoreICTransitionMapHandlerCase( true); } -void AccessorAssembler::CheckFieldType(Node* descriptors, Node* name_index, - Node* representation, Node* value, - Label* bailout) { +void AccessorAssembler::CheckFieldType(TNode<DescriptorArray> descriptors, + Node* name_index, Node* 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, // because this builtin is part of the snapshot and therefore should @@ -1007,20 +1011,25 @@ void AccessorAssembler::CheckFieldType(Node* descriptors, Node* name_index, BIND(&r_heapobject); { GotoIf(TaggedIsSmi(value), bailout); - Node* field_type = - LoadValueByKeyIndex<DescriptorArray>(descriptors, name_index); + TNode<MaybeObject> field_type = LoadFieldTypeByKeyIndex( + descriptors, UncheckedCast<IntPtrT>(name_index)); intptr_t kNoneType = reinterpret_cast<intptr_t>(FieldType::None()); intptr_t kAnyType = reinterpret_cast<intptr_t>(FieldType::Any()); + DCHECK_NE(kNoneType, kClearedWeakHeapObject); + DCHECK_NE(kAnyType, kClearedWeakHeapObject); // FieldType::None can't hold any value. - GotoIf(WordEqual(field_type, IntPtrConstant(kNoneType)), bailout); + GotoIf(WordEqual(BitcastMaybeObjectToWord(field_type), + IntPtrConstant(kNoneType)), + bailout); // FieldType::Any can hold any value. - GotoIf(WordEqual(field_type, IntPtrConstant(kAnyType)), &all_fine); - CSA_ASSERT(this, IsWeakCell(field_type)); - // Cleared WeakCells count as FieldType::None, which can't hold any value. - field_type = LoadWeakCellValue(field_type, bailout); + GotoIf(WordEqual(BitcastMaybeObjectToWord(field_type), + IntPtrConstant(kAnyType)), + &all_fine); + // Cleared weak references count as FieldType::None, which can't hold any + // value. + TNode<Map> field_type_map = CAST(ToWeakHeapObject(field_type, bailout)); // FieldType::Class(...) performs a map check. - CSA_ASSERT(this, IsMap(field_type)); - Branch(WordEqual(LoadMap(value), field_type), &all_fine, bailout); + Branch(WordEqual(LoadMap(value), field_type_map), &all_fine, bailout); } BIND(&all_fine); @@ -1045,16 +1054,17 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( if (FLAG_track_constant_fields && !do_transitioning_store) { // TODO(ishell): Taking the slow path is not necessary if new and old // values are identical. - GotoIf(Word32Equal(DecodeWord32<PropertyDetails::ConstnessField>(details), - Int32Constant(kConst)), + GotoIf(Word32Equal( + DecodeWord32<PropertyDetails::ConstnessField>(details), + Int32Constant(static_cast<int32_t>(VariableMode::kConst))), slow); } Node* representation = DecodeWord32<PropertyDetails::RepresentationField>(details); - CheckFieldType(descriptors, descriptor_name_index, representation, value, - slow); + CheckFieldType(CAST(descriptors), descriptor_name_index, representation, + value, slow); Node* field_index = DecodeWordFromWord32<PropertyDetails::FieldIndexField>(details); @@ -1085,7 +1095,7 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( } else { if (do_transitioning_store) { Node* mutable_heap_number = - AllocateHeapNumberWithValue(double_value, MUTABLE); + AllocateMutableHeapNumberWithValue(double_value); StoreMap(object, object_map); StoreObjectField(object, field_offset, mutable_heap_number); } else { @@ -1124,7 +1134,7 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( { Node* double_value = ChangeNumberToFloat64(value); Node* mutable_heap_number = - AllocateHeapNumberWithValue(double_value, MUTABLE); + AllocateMutableHeapNumberWithValue(double_value); var_value.Bind(mutable_heap_number); Goto(&cont); } @@ -1164,8 +1174,8 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( BIND(&if_descriptor); { // Check that constant matches value. - Node* constant = LoadValueByKeyIndex<DescriptorArray>( - descriptors, descriptor_name_index); + Node* constant = LoadValueByKeyIndex( + CAST(descriptors), UncheckedCast<IntPtrT>(descriptor_name_index)); GotoIf(WordNotEqual(value, constant), slow); if (do_transitioning_store) { @@ -1218,22 +1228,22 @@ void AccessorAssembler::HandleStoreICProtoHandler( &if_transitioning_element_store); BIND(&if_element_store); { - StoreWithVectorDescriptor descriptor(isolate()); - TailCallStub(descriptor, code_handler, p->context, p->receiver, p->name, - p->value, p->slot, p->vector); + TailCallStub(StoreWithVectorDescriptor{}, code_handler, p->context, + p->receiver, p->name, p->value, p->slot, p->vector); } BIND(&if_transitioning_element_store); { - Node* transition_map_cell = LoadHandlerDataField(handler, 1); - Node* transition_map = LoadWeakCellValue(transition_map_cell, miss); - CSA_ASSERT(this, IsMap(transition_map)); + TNode<MaybeObject> maybe_transition_map = + LoadHandlerDataField(handler, 1); + TNode<Map> transition_map = + CAST(ToWeakHeapObject(maybe_transition_map, miss)); GotoIf(IsDeprecatedMap(transition_map), miss); - StoreTransitionDescriptor descriptor(isolate()); - TailCallStub(descriptor, code_handler, p->context, p->receiver, p->name, - transition_map, p->value, p->slot, p->vector); + TailCallStub(StoreTransitionDescriptor{}, code_handler, p->context, + p->receiver, p->name, transition_map, p->value, p->slot, + p->vector); } }; } @@ -1267,7 +1277,7 @@ void AccessorAssembler::HandleStoreICProtoHandler( GotoIf(WordEqual(handler_kind, IntPtrConstant(StoreHandler::kNormal)), &if_add_normal); - Node* holder_cell = LoadHandlerDataField(handler, 1); + TNode<WeakCell> holder_cell = CAST(LoadHandlerDataField(handler, 1)); Node* holder = LoadWeakCellValue(holder_cell, miss); GotoIf(WordEqual(handler_kind, IntPtrConstant(StoreHandler::kGlobalProxy)), @@ -1326,8 +1336,8 @@ void AccessorAssembler::HandleStoreICProtoHandler( // the access check is enabled for this handler or not. TNode<Object> context_cell = Select<Object>( IsSetWord<LoadHandler::DoAccessCheckOnReceiverBits>(handler_word), - [=] { return LoadHandlerDataField(handler, 3); }, - [=] { return LoadHandlerDataField(handler, 2); }); + [=] { return CAST(LoadHandlerDataField(handler, 3)); }, + [=] { return CAST(LoadHandlerDataField(handler, 2)); }); Node* context = LoadWeakCellValueUnchecked(CAST(context_cell)); @@ -1520,12 +1530,13 @@ Node* AccessorAssembler::PrepareValueForStore(Node* handler_word, Node* holder, &done); } Node* descriptor = DecodeWord<StoreHandler::DescriptorBits>(handler_word); - Node* maybe_field_type = LoadDescriptorValue(LoadMap(holder), descriptor); + TNode<MaybeObject> maybe_field_type = + LoadDescriptorValueOrFieldType(LoadMap(holder), descriptor); GotoIf(TaggedIsSmi(maybe_field_type), &done); // Check that value type matches the field type. { - Node* field_type = LoadWeakCellValue(maybe_field_type, bailout); + Node* field_type = ToWeakHeapObject(maybe_field_type, bailout); Branch(WordEqual(LoadMap(value), field_type), &done, bailout); } BIND(&done); @@ -1791,19 +1802,10 @@ void AccessorAssembler::EmitElementLoad( { Comment("dictionary elements"); GotoIf(IntPtrLessThan(intptr_index, IntPtrConstant(0)), out_of_bounds); - TVARIABLE(IntPtrT, var_entry); - Label if_found(this); - NumberDictionaryLookup(CAST(elements), intptr_index, &if_found, &var_entry, - if_hole); - BIND(&if_found); - // Check that the value is a data property. - TNode<IntPtrT> index = EntryToIndex<NumberDictionary>(var_entry.value()); - Node* details = LoadDetailsByKeyIndex<NumberDictionary>(elements, index); - Node* kind = DecodeWord32<PropertyDetails::KindField>(details); - // TODO(jkummerow): Support accessors without missing? - GotoIfNot(Word32Equal(kind, Int32Constant(kData)), miss); - // Finally, load the value. - exit_point->Return(LoadValueByKeyIndex<NumberDictionary>(elements, index)); + + TNode<Object> value = BasicLoadNumberDictionaryElement( + CAST(elements), intptr_index, miss, if_hole); + exit_point->Return(value); } BIND(&if_typed_array); @@ -1814,8 +1816,7 @@ void AccessorAssembler::EmitElementLoad( GotoIf(IsDetachedBuffer(buffer), miss); // Bounds check. - Node* length = - SmiUntag(CAST(LoadObjectField(object, JSTypedArray::kLengthOffset))); + Node* length = SmiUntag(LoadTypedArrayLength(CAST(object))); GotoIfNot(UintPtrLessThan(intptr_index, length), out_of_bounds); Node* backing_store = LoadFixedTypedArrayBackingStore(CAST(elements)); @@ -2074,7 +2075,7 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, // Try looking up the property on the receiver; if unsuccessful, look // for a handler in the stub cache. - Node* descriptors = LoadMapDescriptors(receiver_map); + TNode<DescriptorArray> descriptors = LoadMapDescriptors(receiver_map); Label if_descriptor_found(this), stub_cache(this); TVARIABLE(IntPtrT, var_name_index); @@ -2094,7 +2095,7 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, if (use_stub_cache == kUseStubCache) { BIND(&stub_cache); Comment("stub cache probe for fast property load"); - VARIABLE(var_handler, MachineRepresentation::kTagged); + TVARIABLE(MaybeObject, var_handler); Label found_handler(this, &var_handler), stub_cache_miss(this); TryProbeStubCache(isolate()->load_stub_cache(), receiver, p->name, &found_handler, &var_handler, &stub_cache_miss); @@ -2199,7 +2200,7 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, direct_exit.ReturnCallStub( Builtins::CallableFor(isolate(), Builtins::kProxyGetProperty), p->context, receiver /*holder is the same as receiver*/, p->name, - receiver); + receiver, SmiConstant(OnNonExistent::kReturnUndefined)); } } @@ -2243,12 +2244,10 @@ Node* AccessorAssembler::StubCacheSecondaryOffset(Node* name, Node* seed) { return ChangeUint32ToWord(Word32And(hash, Int32Constant(mask))); } -void AccessorAssembler::TryProbeStubCacheTable(StubCache* stub_cache, - StubCacheTable table_id, - Node* entry_offset, Node* name, - Node* map, Label* if_handler, - Variable* var_handler, - Label* if_miss) { +void AccessorAssembler::TryProbeStubCacheTable( + StubCache* stub_cache, StubCacheTable table_id, Node* entry_offset, + Node* name, Node* map, Label* if_handler, + TVariable<MaybeObject>* var_handler, Label* if_miss) { StubCache::Table table = static_cast<StubCache::Table>(table_id); #ifdef DEBUG if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) { @@ -2280,17 +2279,18 @@ void AccessorAssembler::TryProbeStubCacheTable(StubCache* stub_cache, DCHECK_EQ(kPointerSize, stub_cache->value_reference(table).address() - stub_cache->key_reference(table).address()); - Node* handler = Load(MachineType::TaggedPointer(), key_base, - IntPtrAdd(entry_offset, IntPtrConstant(kPointerSize))); + TNode<MaybeObject> handler = ReinterpretCast<MaybeObject>( + Load(MachineType::TaggedPointer(), key_base, + IntPtrAdd(entry_offset, IntPtrConstant(kPointerSize)))); // We found the handler. - var_handler->Bind(handler); + *var_handler = handler; Goto(if_handler); } void AccessorAssembler::TryProbeStubCache(StubCache* stub_cache, Node* receiver, Node* name, Label* if_handler, - Variable* var_handler, + TVariable<MaybeObject>* var_handler, Label* if_miss) { Label try_secondary(this), miss(this); @@ -2347,20 +2347,19 @@ void AccessorAssembler::LoadIC_BytecodeHandler(const LoadICParameters* p, TVARIABLE(MaybeObject, var_handler); Label try_polymorphic(this), if_handler(this, &var_handler); - Node* feedback = + TNode<MaybeObject> feedback = TryMonomorphicCase(p->slot, p->vector, recv_map, &if_handler, &var_handler, &try_polymorphic); BIND(&if_handler); - CSA_ASSERT(this, IsObject(var_handler.value())); - HandleLoadICHandlerCase(p, ToObject(var_handler.value()), &miss, - exit_point); + HandleLoadICHandlerCase(p, CAST(var_handler.value()), &miss, exit_point); BIND(&try_polymorphic); { - GotoIfNot(IsWeakFixedArrayMap(LoadMap(feedback)), &stub_call); - HandlePolymorphicCase(recv_map, CAST(feedback), &if_handler, &var_handler, - &miss, 2); + TNode<HeapObject> strong_feedback = ToStrongHeapObject(feedback, &miss); + GotoIfNot(IsWeakFixedArrayMap(LoadMap(strong_feedback)), &stub_call); + HandlePolymorphicCase(recv_map, CAST(strong_feedback), &if_handler, + &var_handler, &miss, 2); } } @@ -2398,26 +2397,27 @@ void AccessorAssembler::LoadIC(const LoadICParameters* p) { GotoIf(IsDeprecatedMap(receiver_map), &miss); // Check monomorphic case. - Node* feedback = + TNode<MaybeObject> feedback = TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, &var_handler, &try_polymorphic); BIND(&if_handler); - CSA_ASSERT(this, IsObject(var_handler.value())); - HandleLoadICHandlerCase(p, ToObject(var_handler.value()), &miss, - &direct_exit); + HandleLoadICHandlerCase(p, CAST(var_handler.value()), &miss, &direct_exit); BIND(&try_polymorphic); + TNode<HeapObject> strong_feedback = ToStrongHeapObject(feedback, &miss); { // Check polymorphic case. Comment("LoadIC_try_polymorphic"); - GotoIfNot(IsWeakFixedArrayMap(LoadMap(feedback)), &non_inlined); - HandlePolymorphicCase(receiver_map, CAST(feedback), &if_handler, + GotoIfNot(IsWeakFixedArrayMap(LoadMap(strong_feedback)), &non_inlined); + HandlePolymorphicCase(receiver_map, CAST(strong_feedback), &if_handler, &var_handler, &miss, 2); } BIND(&non_inlined); - LoadIC_Noninlined(p, receiver_map, feedback, &var_handler, &if_handler, &miss, - &direct_exit); + { + LoadIC_Noninlined(p, receiver_map, strong_feedback, &var_handler, + &if_handler, &miss, &direct_exit); + } BIND(&miss); direct_exit.ReturnCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver, @@ -2425,8 +2425,9 @@ void AccessorAssembler::LoadIC(const LoadICParameters* p) { } void AccessorAssembler::LoadIC_Noninlined(const LoadICParameters* p, - Node* receiver_map, Node* feedback, - Variable* var_handler, + Node* receiver_map, + TNode<HeapObject> feedback, + TVariable<MaybeObject>* var_handler, Label* if_handler, Label* miss, ExitPoint* exit_point) { Label try_uninitialized(this, Label::kDeferred); @@ -2434,8 +2435,7 @@ void AccessorAssembler::LoadIC_Noninlined(const LoadICParameters* p, // 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, LoadWeakCellValueUnchecked(feedback))); + CSA_ASSERT(this, WordNotEqual(receiver_map, feedback)); CSA_ASSERT(this, Word32BinaryNot(IsWeakFixedArrayMap(LoadMap(feedback)))); DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); @@ -2539,19 +2539,16 @@ void AccessorAssembler::LoadGlobalIC_TryPropertyCellCase( Comment("LoadGlobalIC_TryPropertyCellCase"); Label if_lexical_var(this), if_property_cell(this); - TNode<MaybeObject> feedback_element = + TNode<MaybeObject> maybe_weak_ref = LoadFeedbackVectorSlot(vector, slot, 0, slot_mode); - CSA_ASSERT(this, IsObject(feedback_element)); - TNode<Object> maybe_weak_cell = ToObject(feedback_element); - Branch(TaggedIsSmi(maybe_weak_cell), &if_lexical_var, &if_property_cell); + Branch(TaggedIsSmi(maybe_weak_ref), &if_lexical_var, &if_property_cell); BIND(&if_property_cell); { - TNode<WeakCell> weak_cell = CAST(maybe_weak_cell); - - // Load value or try handler case if the {weak_cell} is cleared. + // Load value or try handler case if the weak reference is cleared. + CSA_ASSERT(this, IsWeakOrClearedHeapObject(maybe_weak_ref)); TNode<PropertyCell> property_cell = - CAST(LoadWeakCellValue(weak_cell, try_handler)); + CAST(ToWeakHeapObject(maybe_weak_ref, try_handler)); TNode<Object> value = LoadObjectField(property_cell, PropertyCell::kValueOffset); GotoIf(WordEqual(value, TheHoleConstant()), miss); @@ -2561,7 +2558,7 @@ void AccessorAssembler::LoadGlobalIC_TryPropertyCellCase( BIND(&if_lexical_var); { Comment("Load lexical variable"); - TNode<IntPtrT> lexical_handler = SmiUntag(CAST(maybe_weak_cell)); + TNode<IntPtrT> lexical_handler = SmiUntag(CAST(maybe_weak_ref)); TNode<IntPtrT> context_index = Signed(DecodeWord<FeedbackNexus::ContextIndexBits>(lexical_handler)); TNode<IntPtrT> slot_index = @@ -2584,8 +2581,7 @@ void AccessorAssembler::LoadGlobalIC_TryHandlerCase( TNode<MaybeObject> feedback_element = LoadFeedbackVectorSlot(vector, slot, kPointerSize, slot_mode); - CSA_ASSERT(this, IsObject(feedback_element)); - TNode<Object> handler = ToObject(feedback_element); + TNode<Object> handler = CAST(feedback_element); GotoIf(WordEqual(handler, LoadRoot(Heap::kuninitialized_symbolRootIndex)), miss); @@ -2619,23 +2615,23 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p) { GotoIf(IsDeprecatedMap(receiver_map), &miss); // Check monomorphic case. - Node* feedback = + TNode<MaybeObject> feedback = TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, &var_handler, &try_polymorphic); BIND(&if_handler); { - CSA_ASSERT(this, IsObject(var_handler.value())); - HandleLoadICHandlerCase(p, ToObject(var_handler.value()), &miss, - &direct_exit, ICMode::kNonGlobalIC, + HandleLoadICHandlerCase(p, CAST(var_handler.value()), &miss, &direct_exit, + ICMode::kNonGlobalIC, OnNonExistent::kReturnUndefined, kSupportElements); } BIND(&try_polymorphic); + TNode<HeapObject> strong_feedback = ToStrongHeapObject(feedback, &miss); { // Check polymorphic case. Comment("KeyedLoadIC_try_polymorphic"); - GotoIfNot(IsWeakFixedArrayMap(LoadMap(feedback)), &try_megamorphic); - HandlePolymorphicCase(receiver_map, CAST(feedback), &if_handler, + GotoIfNot(IsWeakFixedArrayMap(LoadMap(strong_feedback)), &try_megamorphic); + HandlePolymorphicCase(receiver_map, CAST(strong_feedback), &if_handler, &var_handler, &miss, 2); } @@ -2643,7 +2639,8 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p) { { // Check megamorphic case. Comment("KeyedLoadIC_try_megamorphic"); - GotoIfNot(WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), + GotoIfNot(WordEqual(strong_feedback, + LoadRoot(Heap::kmegamorphic_symbolRootIndex)), &try_polymorphic_name); // TODO(jkummerow): Inline this? Or some of it? TailCallBuiltin(Builtins::kKeyedLoadIC_Megamorphic, p->context, p->receiver, @@ -2661,7 +2658,7 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p) { if_notinternalized(this, Label::kDeferred); // Fast-case: The recorded {feedback} matches the {name}. - GotoIf(WordEqual(feedback, name), &if_polymorphic_name); + GotoIf(WordEqual(strong_feedback, name), &if_polymorphic_name); // Try to internalize the {name} if it isn't already. TryToName(name, &miss, &var_index, &if_internalized, &var_name, &miss, @@ -2670,7 +2667,7 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p) { BIND(&if_internalized); { // The {var_name} now contains a unique name. - Branch(WordEqual(feedback, var_name.value()), &if_polymorphic_name, + Branch(WordEqual(strong_feedback, var_name.value()), &if_polymorphic_name, &miss); } @@ -2679,8 +2676,11 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p) { // Try to internalize the {name}. Node* function = ExternalConstant( ExternalReference::try_internalize_string_function()); - var_name.Bind(CallCFunction1(MachineType::AnyTagged(), - MachineType::AnyTagged(), function, name)); + Node* const isolate_ptr = + ExternalConstant(ExternalReference::isolate_address(isolate())); + var_name.Bind(CallCFunction2( + MachineType::AnyTagged(), MachineType::Pointer(), + MachineType::AnyTagged(), function, isolate_ptr, name)); Goto(&if_internalized); } @@ -2783,25 +2783,21 @@ void AccessorAssembler::KeyedLoadICPolymorphicName(const LoadICParameters* p) { // LoadIC handler logic below. CSA_ASSERT(this, IsName(name)); CSA_ASSERT(this, Word32BinaryNot(IsDeprecatedMap(receiver_map))); - CSA_ASSERT(this, IsStrongHeapObject(LoadFeedbackVectorSlot(vector, slot, 0, - SMI_PARAMETERS))); - CSA_ASSERT(this, WordEqual(name, ToStrongHeapObject(LoadFeedbackVectorSlot( + CSA_ASSERT(this, WordEqual(name, CAST(LoadFeedbackVectorSlot( vector, slot, 0, SMI_PARAMETERS)))); // Check if we have a matching handler for the {receiver_map}. TNode<MaybeObject> feedback_element = LoadFeedbackVectorSlot(vector, slot, kPointerSize, SMI_PARAMETERS); - CSA_ASSERT(this, IsObject(feedback_element)); - TNode<WeakFixedArray> array = CAST(ToObject(feedback_element)); + TNode<WeakFixedArray> array = CAST(feedback_element); HandlePolymorphicCase(receiver_map, array, &if_handler, &var_handler, &miss, 1); BIND(&if_handler); { ExitPoint direct_exit(this); - CSA_ASSERT(this, IsObject(var_handler.value())); - HandleLoadICHandlerCase(p, ToObject(var_handler.value()), &miss, - &direct_exit, ICMode::kNonGlobalIC, + HandleLoadICHandlerCase(p, CAST(var_handler.value()), &miss, &direct_exit, + ICMode::kNonGlobalIC, OnNonExistent::kReturnUndefined, kOnlyProperties); } @@ -2827,7 +2823,7 @@ void AccessorAssembler::StoreIC(const StoreICParameters* p) { GotoIf(IsDeprecatedMap(receiver_map), &miss); // Check monomorphic case. - Node* feedback = + TNode<MaybeObject> feedback = TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, &var_handler, &try_polymorphic); BIND(&if_handler); @@ -2838,49 +2834,31 @@ void AccessorAssembler::StoreIC(const StoreICParameters* p) { } BIND(&try_polymorphic); + TNode<HeapObject> strong_feedback = ToStrongHeapObject(feedback, &miss); { // Check polymorphic case. Comment("StoreIC_try_polymorphic"); - GotoIfNot(IsWeakFixedArrayMap(LoadMap(feedback)), &try_megamorphic); - HandlePolymorphicCase(receiver_map, CAST(feedback), &if_handler, + GotoIfNot(IsWeakFixedArrayMap(LoadMap(strong_feedback)), &try_megamorphic); + HandlePolymorphicCase(receiver_map, CAST(strong_feedback), &if_handler, &var_handler, &miss, 2); } BIND(&try_megamorphic); { // Check megamorphic case. - GotoIfNot(WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), + GotoIfNot(WordEqual(strong_feedback, + LoadRoot(Heap::kmegamorphic_symbolRootIndex)), &try_uninitialized); TryProbeStubCache(isolate()->store_stub_cache(), p->receiver, p->name, - &if_handler_from_stub_cache, &var_handler, &miss); - } - BIND(&if_handler_from_stub_cache); - { - // If the stub cache contains a WeakCell pointing to a Map, convert it to an - // in-place weak reference. TODO(marja): This well get simplified once more - // WeakCells are converted into in-place weak references. - Comment("StoreIC_if_handler_from_stub_cache"); - GotoIf(TaggedIsSmi(var_handler.value()), &if_handler); - - CSA_ASSERT(this, IsStrongHeapObject(var_handler.value())); - TNode<HeapObject> handler = ToStrongHeapObject(var_handler.value()); - GotoIfNot(IsWeakCell(handler), &if_handler); - - TNode<HeapObject> value = CAST(LoadWeakCellValue(CAST(handler), &miss)); - TNode<Map> value_map = LoadMap(value); - GotoIfNot(Word32Or(IsMetaMap(value_map), IsPropertyCellMap(value_map)), - &if_handler); - - TNode<MaybeObject> weak_handler = MakeWeak(value); - HandleStoreICHandlerCase(p, weak_handler, &miss, ICMode::kNonGlobalIC); + &if_handler, &var_handler, &miss); } BIND(&try_uninitialized); { // Check uninitialized case. - GotoIfNot( - WordEqual(feedback, LoadRoot(Heap::kuninitialized_symbolRootIndex)), - &miss); + GotoIfNot(WordEqual(strong_feedback, + LoadRoot(Heap::kuninitialized_symbolRootIndex)), + &miss); TailCallBuiltin(Builtins::kStoreIC_Uninitialized, p->context, p->receiver, p->name, p->value, p->slot, p->vector); } @@ -2893,17 +2871,16 @@ void AccessorAssembler::StoreIC(const StoreICParameters* p) { void AccessorAssembler::StoreGlobalIC(const StoreICParameters* pp) { Label if_lexical_var(this), if_property_cell(this); - TNode<MaybeObject> feedback_element = + TNode<MaybeObject> maybe_weak_ref = LoadFeedbackVectorSlot(pp->vector, pp->slot, 0, SMI_PARAMETERS); - CSA_ASSERT(this, IsObject(feedback_element)); - TNode<Object> maybe_weak_cell = ToObject(feedback_element); - Branch(TaggedIsSmi(maybe_weak_cell), &if_lexical_var, &if_property_cell); + Branch(TaggedIsSmi(maybe_weak_ref), &if_lexical_var, &if_property_cell); BIND(&if_property_cell); { Label try_handler(this), miss(this, Label::kDeferred); + CSA_ASSERT(this, IsWeakOrClearedHeapObject(maybe_weak_ref)); TNode<PropertyCell> property_cell = - CAST(LoadWeakCellValue(CAST(maybe_weak_cell), &try_handler)); + CAST(ToWeakHeapObject(maybe_weak_ref, &try_handler)); ExitPoint direct_exit(this); StoreGlobalIC_PropertyCellCase(property_cell, pp->value, &direct_exit, @@ -2937,7 +2914,7 @@ void AccessorAssembler::StoreGlobalIC(const StoreICParameters* pp) { BIND(&if_lexical_var); { Comment("Store lexical variable"); - TNode<IntPtrT> lexical_handler = SmiUntag(CAST(maybe_weak_cell)); + TNode<IntPtrT> lexical_handler = SmiUntag(CAST(maybe_weak_ref)); TNode<IntPtrT> context_index = Signed(DecodeWord<FeedbackNexus::ContextIndexBits>(lexical_handler)); TNode<IntPtrT> slot_index = @@ -3027,7 +3004,7 @@ void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p) { GotoIf(IsDeprecatedMap(receiver_map), &miss); // Check monomorphic case. - Node* feedback = + TNode<MaybeObject> feedback = TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, &var_handler, &try_polymorphic); BIND(&if_handler); @@ -3038,11 +3015,13 @@ void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p) { } BIND(&try_polymorphic); + TNode<HeapObject> strong_feedback = ToStrongHeapObject(feedback, &miss); { // CheckPolymorphic case. Comment("KeyedStoreIC_try_polymorphic"); - GotoIfNot(IsWeakFixedArrayMap(LoadMap(feedback)), &try_megamorphic); - HandlePolymorphicCase(receiver_map, CAST(feedback), &if_handler, + GotoIfNot(IsWeakFixedArrayMap(LoadMap(strong_feedback)), + &try_megamorphic); + HandlePolymorphicCase(receiver_map, CAST(strong_feedback), &if_handler, &var_handler, &miss, 2); } @@ -3050,9 +3029,9 @@ void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p) { { // Check megamorphic case. Comment("KeyedStoreIC_try_megamorphic"); - GotoIfNot( - WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), - &try_polymorphic_name); + GotoIfNot(WordEqual(strong_feedback, + LoadRoot(Heap::kmegamorphic_symbolRootIndex)), + &try_polymorphic_name); TailCallBuiltin(Builtins::kKeyedStoreIC_Megamorphic, p->context, p->receiver, p->name, p->value, p->slot, p->vector); } @@ -3061,13 +3040,12 @@ 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(feedback, p->name), &miss); + GotoIfNot(WordEqual(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( p->vector, p->slot, kPointerSize, SMI_PARAMETERS); - CSA_ASSERT(this, IsObject(feedback_element)); - TNode<WeakFixedArray> array = CAST(ToObject(feedback_element)); + TNode<WeakFixedArray> array = CAST(feedback_element); HandlePolymorphicCase(receiver_map, array, &if_handler, &var_handler, &miss, 1); } @@ -3091,7 +3069,7 @@ void AccessorAssembler::StoreInArrayLiteralIC(const StoreICParameters* p) { Node* array_map = LoadReceiverMap(p->receiver); GotoIf(IsDeprecatedMap(array_map), &miss); - Node* feedback = + TNode<MaybeObject> feedback = TryMonomorphicCase(p->slot, p->vector, array_map, &if_handler, &var_handler, &try_polymorphic); @@ -3100,33 +3078,33 @@ void AccessorAssembler::StoreInArrayLiteralIC(const StoreICParameters* p) { Comment("StoreInArrayLiteralIC_if_handler"); // This is a stripped-down version of HandleStoreICHandlerCase. - CSA_ASSERT(this, IsStrongHeapObject(var_handler.value())); - TNode<HeapObject> handler = ToStrongHeapObject(var_handler.value()); + TNode<HeapObject> handler = CAST(var_handler.value()); Label if_transitioning_element_store(this); GotoIfNot(IsCode(handler), &if_transitioning_element_store); - StoreWithVectorDescriptor descriptor(isolate()); - TailCallStub(descriptor, handler, p->context, p->receiver, p->name, - p->value, p->slot, p->vector); + TailCallStub(StoreWithVectorDescriptor{}, CAST(handler), CAST(p->context), + p->receiver, p->name, p->value, p->slot, p->vector); BIND(&if_transitioning_element_store); { - Node* transition_map_cell = LoadHandlerDataField(CAST(handler), 1); - Node* transition_map = LoadWeakCellValue(transition_map_cell, &miss); - CSA_ASSERT(this, IsMap(transition_map)); + TNode<MaybeObject> maybe_transition_map = + LoadHandlerDataField(CAST(handler), 1); + TNode<Map> transition_map = + CAST(ToWeakHeapObject(maybe_transition_map, &miss)); GotoIf(IsDeprecatedMap(transition_map), &miss); Node* code = LoadObjectField(handler, StoreHandler::kSmiHandlerOffset); CSA_ASSERT(this, IsCode(code)); - StoreTransitionDescriptor descriptor(isolate()); - TailCallStub(descriptor, code, p->context, p->receiver, p->name, - transition_map, p->value, p->slot, p->vector); + TailCallStub(StoreTransitionDescriptor{}, code, p->context, p->receiver, + p->name, transition_map, p->value, p->slot, p->vector); } } BIND(&try_polymorphic); + TNode<HeapObject> strong_feedback = ToStrongHeapObject(feedback, &miss); { Comment("StoreInArrayLiteralIC_try_polymorphic"); - GotoIfNot(IsWeakFixedArrayMap(LoadMap(feedback)), &try_megamorphic); - HandlePolymorphicCase(array_map, CAST(feedback), &if_handler, + GotoIfNot(IsWeakFixedArrayMap(LoadMap(strong_feedback)), + &try_megamorphic); + HandlePolymorphicCase(array_map, CAST(strong_feedback), &if_handler, &var_handler, &miss, 2); } @@ -3135,16 +3113,13 @@ void AccessorAssembler::StoreInArrayLiteralIC(const StoreICParameters* p) { Comment("StoreInArrayLiteralIC_try_megamorphic"); CSA_ASSERT( this, - Word32Or( - Word32Or( - IsWeakCellMap(LoadMap(feedback)), - WordEqual(feedback, - LoadRoot(Heap::kuninitialized_symbolRootIndex))), - WordEqual(feedback, - LoadRoot(Heap::kmegamorphic_symbolRootIndex)))); - GotoIfNot( - WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), - &miss); + Word32Or(WordEqual(strong_feedback, + LoadRoot(Heap::kuninitialized_symbolRootIndex)), + WordEqual(strong_feedback, + LoadRoot(Heap::kmegamorphic_symbolRootIndex)))); + GotoIfNot(WordEqual(strong_feedback, + LoadRoot(Heap::kmegamorphic_symbolRootIndex)), + &miss); TailCallRuntime(Runtime::kStoreInArrayLiteralIC_Slow, p->context, p->value, p->receiver, p->name); } @@ -3184,14 +3159,13 @@ void AccessorAssembler::GenerateLoadIC_Noninlined() { Node* context = Parameter(Descriptor::kContext); ExitPoint direct_exit(this); - VARIABLE(var_handler, MachineRepresentation::kTagged); + TVARIABLE(MaybeObject, var_handler); Label if_handler(this, &var_handler), miss(this, Label::kDeferred); Node* receiver_map = LoadReceiverMap(receiver); TNode<MaybeObject> feedback_element = LoadFeedbackVectorSlot(vector, slot, 0, SMI_PARAMETERS); - CSA_ASSERT(this, IsObject(feedback_element)); - TNode<Object> feedback = ToObject(feedback_element); + TNode<HeapObject> feedback = CAST(feedback_element); LoadICParameters p(context, receiver, name, slot, vector); LoadIC_Noninlined(&p, receiver_map, feedback, &var_handler, &if_handler, diff --git a/deps/v8/src/ic/accessor-assembler.h b/deps/v8/src/ic/accessor-assembler.h index 24a47376a5..0aa9f0ab41 100644 --- a/deps/v8/src/ic/accessor-assembler.h +++ b/deps/v8/src/ic/accessor-assembler.h @@ -49,7 +49,7 @@ class AccessorAssembler : public CodeStubAssembler { void GenerateStoreInArrayLiteralIC(); void TryProbeStubCache(StubCache* stub_cache, Node* receiver, Node* name, - Label* if_handler, Variable* var_handler, + Label* if_handler, TVariable<MaybeObject>* var_handler, Label* if_miss); Node* StubCachePrimaryOffsetForTesting(Node* name, Node* map) { @@ -88,8 +88,8 @@ class AccessorAssembler : public CodeStubAssembler { void LoadIC_BytecodeHandler(const LoadICParameters* p, ExitPoint* exit_point); // Loads dataX field from the DataHandler object. - TNode<Object> LoadHandlerDataField(SloppyTNode<DataHandler> handler, - int data_index); + TNode<MaybeObject> LoadHandlerDataField(SloppyTNode<DataHandler> handler, + int data_index); protected: struct StoreICParameters : public LoadICParameters { @@ -123,8 +123,8 @@ class AccessorAssembler : public CodeStubAssembler { Label* slow, bool do_transitioning_store); - void CheckFieldType(Node* descriptors, Node* name_index, Node* representation, - Node* value, Label* bailout); + void CheckFieldType(TNode<DescriptorArray> descriptors, Node* name_index, + Node* representation, Node* value, Label* bailout); private: // Stub generation entry points. @@ -133,10 +133,13 @@ class AccessorAssembler : public CodeStubAssembler { // logic not inlined into Ignition bytecode handlers. void LoadIC(const LoadICParameters* p); void LoadIC_Noninlined(const LoadICParameters* p, Node* receiver_map, - Node* feedback, Variable* var_handler, - Label* if_handler, Label* miss, ExitPoint* exit_point); + TNode<HeapObject> feedback, + TVariable<MaybeObject>* var_handler, Label* if_handler, + Label* miss, ExitPoint* exit_point); - Node* LoadDescriptorValue(Node* map, Node* descriptor); + TNode<Object> LoadDescriptorValue(Node* map, Node* descriptor); + TNode<MaybeObject> LoadDescriptorValueOrFieldType(Node* map, + Node* descriptor); void LoadIC_Uninitialized(const LoadICParameters* p); @@ -153,16 +156,16 @@ class AccessorAssembler : public CodeStubAssembler { // IC dispatcher behavior. // Checks monomorphic case. Returns {feedback} entry of the vector. - Node* TryMonomorphicCase(Node* slot, Node* vector, Node* receiver_map, - Label* if_handler, - TVariable<MaybeObject>* var_handler, Label* if_miss); + TNode<MaybeObject> TryMonomorphicCase(Node* slot, Node* vector, + Node* receiver_map, Label* if_handler, + TVariable<MaybeObject>* var_handler, + Label* if_miss); void HandlePolymorphicCase(Node* receiver_map, TNode<WeakFixedArray> feedback, Label* if_handler, TVariable<MaybeObject>* var_handler, Label* if_miss, int min_feedback_capacity); // LoadIC implementation. - enum class OnNonExistent { kThrowReferenceError, kReturnUndefined }; void HandleLoadICHandlerCase( const LoadICParameters* p, TNode<Object> handler, Label* miss, ExitPoint* exit_point, ICMode ic_mode = ICMode::kNonGlobalIC, @@ -285,7 +288,8 @@ class AccessorAssembler : public CodeStubAssembler { void TryProbeStubCacheTable(StubCache* stub_cache, StubCacheTable table_id, Node* entry_offset, Node* name, Node* map, - Label* if_handler, Variable* var_handler, + Label* if_handler, + TVariable<MaybeObject>* var_handler, Label* if_miss); }; diff --git a/deps/v8/src/ic/call-optimization.cc b/deps/v8/src/ic/call-optimization.cc index c8705bc6c9..41928f1c08 100644 --- a/deps/v8/src/ic/call-optimization.cc +++ b/deps/v8/src/ic/call-optimization.cc @@ -8,15 +8,15 @@ namespace v8 { namespace internal { -CallOptimization::CallOptimization(Handle<Object> function) { +CallOptimization::CallOptimization(Isolate* isolate, Handle<Object> function) { constant_function_ = Handle<JSFunction>::null(); is_simple_api_call_ = false; expected_receiver_type_ = Handle<FunctionTemplateInfo>::null(); api_call_info_ = Handle<CallHandlerInfo>::null(); if (function->IsJSFunction()) { - Initialize(Handle<JSFunction>::cast(function)); + Initialize(isolate, Handle<JSFunction>::cast(function)); } else if (function->IsFunctionTemplateInfo()) { - Initialize(Handle<FunctionTemplateInfo>::cast(function)); + Initialize(isolate, Handle<FunctionTemplateInfo>::cast(function)); } } @@ -48,8 +48,9 @@ Handle<JSObject> CallOptimization::LookupHolderOfExpectedType( return Handle<JSObject>::null(); } if (object_map->has_hidden_prototype()) { - Handle<JSObject> prototype(JSObject::cast(object_map->prototype())); - object_map = handle(prototype->map()); + JSObject* raw_prototype = JSObject::cast(object_map->prototype()); + Handle<JSObject> prototype(raw_prototype, raw_prototype->GetIsolate()); + object_map = handle(prototype->map(), prototype->GetIsolate()); if (expected_receiver_type_->IsTemplateFor(*object_map)) { *holder_lookup = kHolderFound; return prototype; @@ -64,7 +65,7 @@ bool CallOptimization::IsCompatibleReceiver(Handle<Object> receiver, Handle<JSObject> holder) const { DCHECK(is_simple_api_call()); if (!receiver->IsHeapObject()) return false; - Handle<Map> map(HeapObject::cast(*receiver)->map()); + Handle<Map> map(HeapObject::cast(*receiver)->map(), holder->GetIsolate()); return IsCompatibleReceiverMap(map, holder); } @@ -96,30 +97,30 @@ bool CallOptimization::IsCompatibleReceiverMap(Handle<Map> map, } void CallOptimization::Initialize( - Handle<FunctionTemplateInfo> function_template_info) { - Isolate* isolate = function_template_info->GetIsolate(); + Isolate* isolate, Handle<FunctionTemplateInfo> function_template_info) { if (function_template_info->call_code()->IsUndefined(isolate)) return; - api_call_info_ = - handle(CallHandlerInfo::cast(function_template_info->call_code())); + api_call_info_ = handle( + CallHandlerInfo::cast(function_template_info->call_code()), isolate); if (!function_template_info->signature()->IsUndefined(isolate)) { expected_receiver_type_ = - handle(FunctionTemplateInfo::cast(function_template_info->signature())); + handle(FunctionTemplateInfo::cast(function_template_info->signature()), + isolate); } is_simple_api_call_ = true; } -void CallOptimization::Initialize(Handle<JSFunction> function) { +void CallOptimization::Initialize(Isolate* isolate, + Handle<JSFunction> function) { if (function.is_null() || !function->is_compiled()) return; constant_function_ = function; - AnalyzePossibleApiFunction(function); + AnalyzePossibleApiFunction(isolate, function); } - -void CallOptimization::AnalyzePossibleApiFunction(Handle<JSFunction> function) { +void CallOptimization::AnalyzePossibleApiFunction(Isolate* isolate, + Handle<JSFunction> function) { if (!function->shared()->IsApiFunction()) return; - Isolate* isolate = function->GetIsolate(); Handle<FunctionTemplateInfo> info(function->shared()->get_api_func_data(), isolate); diff --git a/deps/v8/src/ic/call-optimization.h b/deps/v8/src/ic/call-optimization.h index ee421355e6..d87ec4fdb1 100644 --- a/deps/v8/src/ic/call-optimization.h +++ b/deps/v8/src/ic/call-optimization.h @@ -14,7 +14,7 @@ namespace internal { // Holds information about possible function call optimizations. class CallOptimization BASE_EMBEDDED { public: - explicit CallOptimization(Handle<Object> function); + CallOptimization(Isolate* isolate, Handle<Object> function); Context* GetAccessorContext(Map* holder_map) const; bool IsCrossContextLazyAccessorPair(Context* native_context, @@ -52,12 +52,14 @@ class CallOptimization BASE_EMBEDDED { Handle<JSObject> holder) const; private: - void Initialize(Handle<JSFunction> function); - void Initialize(Handle<FunctionTemplateInfo> function_template_info); + void Initialize(Isolate* isolate, Handle<JSFunction> function); + void Initialize(Isolate* isolate, + Handle<FunctionTemplateInfo> function_template_info); // Determines whether the given function can be called using the // fast api call builtin. - void AnalyzePossibleApiFunction(Handle<JSFunction> function); + void AnalyzePossibleApiFunction(Isolate* isolate, + Handle<JSFunction> function); Handle<JSFunction> constant_function_; bool is_simple_api_call_; diff --git a/deps/v8/src/ic/handler-configuration-inl.h b/deps/v8/src/ic/handler-configuration-inl.h index e4d3d33c40..74ee29edaf 100644 --- a/deps/v8/src/ic/handler-configuration-inl.h +++ b/deps/v8/src/ic/handler-configuration-inl.h @@ -163,8 +163,9 @@ Handle<Smi> StoreHandler::StoreField(Isolate* isolate, int descriptor, FieldIndex field_index, PropertyConstness constness, Representation representation) { - DCHECK_IMPLIES(!FLAG_track_constant_fields, constness == kMutable); - Kind kind = constness == kMutable ? kField : kConstField; + DCHECK_IMPLIES(!FLAG_track_constant_fields, + constness == PropertyConstness::kMutable); + Kind kind = constness == PropertyConstness::kMutable ? kField : kConstField; return StoreField(isolate, kind, descriptor, field_index, representation); } diff --git a/deps/v8/src/ic/handler-configuration.cc b/deps/v8/src/ic/handler-configuration.cc index bd4ba68c34..c95e036e1c 100644 --- a/deps/v8/src/ic/handler-configuration.cc +++ b/deps/v8/src/ic/handler-configuration.cc @@ -59,7 +59,7 @@ int InitPrototypeChecksImpl(Isolate* isolate, Handle<ICHandler> handler, } } if (fill_handler) { - handler->set_data1(*data1); + handler->set_data1(MaybeObject::FromObject(*data1)); } Handle<Object> data2; if (maybe_data2.ToHandle(&data2)) { @@ -187,11 +187,10 @@ Handle<Object> StoreHandler::StoreElementTransition( .GetCode(); Handle<Object> validity_cell = Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate); - Handle<WeakCell> cell = Map::WeakCellForMap(transition); Handle<StoreHandler> handler = isolate->factory()->NewStoreHandler(1); handler->set_smi_handler(*stub); handler->set_validity_cell(*validity_cell); - handler->set_data1(*cell); + handler->set_data1(HeapObjectReference::Weak(*transition)); return handler; } @@ -201,7 +200,8 @@ MaybeObjectHandle StoreHandler::StoreTransition(Isolate* isolate, #ifdef DEBUG if (!is_dictionary_map) { int descriptor = transition_map->LastAdded(); - Handle<DescriptorArray> descriptors(transition_map->instance_descriptors()); + Handle<DescriptorArray> descriptors(transition_map->instance_descriptors(), + isolate); PropertyDetails details = descriptors->GetDetails(descriptor); if (descriptors->GetKey(descriptor)->IsPrivate()) { DCHECK_EQ(DONT_ENUM, details.attributes()); diff --git a/deps/v8/src/ic/ic-inl.h b/deps/v8/src/ic/ic-inl.h index 835b39efda..7c95f2fcf0 100644 --- a/deps/v8/src/ic/ic-inl.h +++ b/deps/v8/src/ic/ic-inl.h @@ -39,17 +39,13 @@ Address IC::raw_constant_pool() const { } } -bool IC::IsHandler(MaybeObject* object, bool from_stub_cache) { +bool IC::IsHandler(MaybeObject* object) { HeapObject* heap_object; return (object->IsSmi() && (object != nullptr)) || (object->ToWeakHeapObject(&heap_object) && (heap_object->IsMap() || heap_object->IsPropertyCell())) || (object->ToStrongHeapObject(&heap_object) && (heap_object->IsDataHandler() || - (from_stub_cache && heap_object->IsWeakCell() && - (WeakCell::cast(heap_object)->cleared() || - WeakCell::cast(heap_object)->value()->IsMap() || - WeakCell::cast(heap_object)->value()->IsPropertyCell())) || heap_object->IsCode())); } diff --git a/deps/v8/src/ic/ic.cc b/deps/v8/src/ic/ic.cc index b11bc9de98..0937d792c2 100644 --- a/deps/v8/src/ic/ic.cc +++ b/deps/v8/src/ic/ic.cc @@ -22,6 +22,7 @@ #include "src/macro-assembler.h" #include "src/objects/api-callbacks.h" #include "src/objects/hash-table-inl.h" +#include "src/objects/module-inl.h" #include "src/prototype.h" #include "src/runtime-profiler.h" #include "src/runtime/runtime-utils.h" @@ -206,7 +207,7 @@ JSFunction* IC::GetHostFunction() const { return frame->function(); } -static void LookupForRead(LookupIterator* it) { +static void LookupForRead(Isolate* isolate, LookupIterator* it) { for (; it->IsFound(); it->Next()) { switch (it->state()) { case LookupIterator::NOT_FOUND: @@ -217,8 +218,7 @@ static void LookupForRead(LookupIterator* it) { case LookupIterator::INTERCEPTOR: { // If there is a getter, return; otherwise loop to perform the lookup. Handle<JSObject> holder = it->GetHolder<JSObject>(); - if (!holder->GetNamedInterceptor()->getter()->IsUndefined( - it->isolate())) { + if (!holder->GetNamedInterceptor()->getter()->IsUndefined(isolate)) { return; } break; @@ -255,7 +255,7 @@ bool IC::ShouldRecomputeHandler(Handle<String> name) { if (!receiver_map()->IsJSObjectMap()) return false; Map* first_map = FirstTargetMap(); if (first_map == nullptr) return false; - Handle<Map> old_map(first_map); + Handle<Map> old_map(first_map, isolate()); if (old_map->is_deprecated()) return true; return IsMoreGeneralElementsKindTransition(old_map->elements_kind(), receiver_map()->elements_kind()); @@ -333,7 +333,7 @@ void IC::OnFeedbackChanged(Isolate* isolate, FeedbackVector* vector, if (FLAG_trace_feedback_updates) { int slot_count = vector->metadata()->slot_count(); - OFStream os(stdout); + StdoutStream os; if (slot.IsInvalid()) { os << "[Feedback slots in "; } else { @@ -429,7 +429,7 @@ MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) { TraceIC("LoadIC", name); } - if (*name == isolate()->heap()->iterator_symbol()) { + if (*name == ReadOnlyRoots(isolate()).iterator_symbol()) { return Runtime::ThrowIteratorError(isolate(), object); } return TypeError(MessageTemplate::kNonObjectPropertyLoad, object, name); @@ -442,8 +442,8 @@ MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) { update_receiver_map(object); } // Named lookup in the object. - LookupIterator it(object, name); - LookupForRead(&it); + LookupIterator it(isolate(), object, name); + LookupForRead(isolate(), &it); if (name->IsPrivate()) { if (name->IsPrivateField() && !it.IsFound()) { @@ -484,14 +484,15 @@ MaybeHandle<Object> LoadGlobalIC::Load(Handle<Name> name) { // Look up in script context table. Handle<String> str_name = Handle<String>::cast(name); Handle<ScriptContextTable> script_contexts( - global->native_context()->script_context_table()); + global->native_context()->script_context_table(), isolate()); ScriptContextTable::LookupResult lookup_result; - if (ScriptContextTable::Lookup(script_contexts, str_name, &lookup_result)) { - Handle<Object> result = - FixedArray::get(*ScriptContextTable::GetContext( - script_contexts, lookup_result.context_index), - lookup_result.slot_index, isolate()); + if (ScriptContextTable::Lookup(isolate(), script_contexts, str_name, + &lookup_result)) { + Handle<Object> result = FixedArray::get( + *ScriptContextTable::GetContext(isolate(), script_contexts, + lookup_result.context_index), + lookup_result.slot_index, isolate()); if (result->IsTheHole(isolate())) { // Do not install stubs and stay pre-monomorphic for // uninitialized accesses. @@ -625,8 +626,9 @@ bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) { Map* transitioned_map = nullptr; if (more_general_transition) { MapHandles map_list; - map_list.push_back(handle(target_map)); - transitioned_map = source_map->FindElementsKindTransitionedMap(map_list); + map_list.push_back(handle(target_map, isolate_)); + transitioned_map = + source_map->FindElementsKindTransitionedMap(isolate(), map_list); } return transitioned_map == target_map; } @@ -720,21 +722,7 @@ StubCache* IC::stub_cache() { void IC::UpdateMegamorphicCache(Handle<Map> map, Handle<Name> name, const MaybeObjectHandle& handler) { - HeapObject* heap_object; - if (handler->ToWeakHeapObject(&heap_object)) { - // TODO(marja): remove this conversion once megamorphic stub cache supports - // weak handlers. - Handle<Object> weak_cell; - if (heap_object->IsMap()) { - weak_cell = Map::WeakCellForMap(handle(Map::cast(heap_object))); - } else { - weak_cell = isolate_->factory()->NewWeakCell( - handle(PropertyCell::cast(heap_object))); - } - stub_cache()->Set(*name, *map, *weak_cell); - } else { - stub_cache()->Set(*name, *map, handler->ToObject()); - } + stub_cache()->Set(*name, *map, *handler); } void IC::TraceHandlerCacheHitStats(LookupIterator* lookup) { @@ -750,21 +738,19 @@ void IC::TraceHandlerCacheHitStats(LookupIterator* lookup) { Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) { Handle<Object> receiver = lookup->GetReceiver(); - if (receiver->IsString() && - *lookup->name() == isolate()->heap()->length_string()) { + ReadOnlyRoots roots(isolate()); + if (receiver->IsString() && *lookup->name() == roots.length_string()) { TRACE_HANDLER_STATS(isolate(), LoadIC_StringLength); return BUILTIN_CODE(isolate(), LoadIC_StringLength); } - if (receiver->IsStringWrapper() && - *lookup->name() == isolate()->heap()->length_string()) { + if (receiver->IsStringWrapper() && *lookup->name() == roots.length_string()) { TRACE_HANDLER_STATS(isolate(), LoadIC_StringWrapperLength); return BUILTIN_CODE(isolate(), LoadIC_StringWrapperLength); } // Use specialized code for getting prototype of functions. - if (receiver->IsJSFunction() && - *lookup->name() == isolate()->heap()->prototype_string() && + if (receiver->IsJSFunction() && *lookup->name() == roots.prototype_string() && JSFunction::cast(*receiver)->has_prototype_slot() && !JSFunction::cast(*receiver)->map()->has_non_instance_prototype()) { Handle<Code> stub; @@ -810,7 +796,8 @@ Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) { // The method will only return true for absolute truths based on the // receiver maps. FieldIndex index; - if (Accessors::IsJSObjectFieldAccessor(map, lookup->name(), &index)) { + if (Accessors::IsJSObjectFieldAccessor(isolate(), map, lookup->name(), + &index)) { TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldDH); return LoadHandler::LoadField(isolate(), index); } @@ -818,7 +805,7 @@ Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) { Handle<ObjectHashTable> exports( Handle<JSModuleNamespace>::cast(holder)->module()->exports(), isolate()); - int entry = exports->FindEntry(isolate(), lookup->name(), + int entry = exports->FindEntry(roots, lookup->name(), Smi::ToInt(lookup->name()->GetHash())); // We found the accessor, so the entry must exist. DCHECK_NE(entry, ObjectHashTable::kNotFound); @@ -849,7 +836,7 @@ Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) { Handle<Smi> smi_handler; - CallOptimization call_optimization(getter); + CallOptimization call_optimization(isolate(), getter); if (call_optimization.is_simple_api_call()) { if (!call_optimization.IsCompatibleReceiverMap(map, holder) || !holder->HasFastProperties()) { @@ -864,7 +851,7 @@ Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) { isolate(), holder_lookup == CallOptimization::kHolderIsReceiver); Handle<Context> context( - call_optimization.GetAccessorContext(holder->map())); + call_optimization.GetAccessorContext(holder->map()), isolate()); Handle<WeakCell> context_cell = isolate()->factory()->NewWeakCell(context); Handle<WeakCell> data_cell = isolate()->factory()->NewWeakCell( @@ -1145,9 +1132,10 @@ void KeyedLoadIC::LoadElementPolymorphicHandlers( // among receiver_maps as unstable because the optimizing compilers may // generate an elements kind transition for this kind of receivers. if (receiver_map->is_stable()) { - Map* tmap = receiver_map->FindElementsKindTransitionedMap(*receiver_maps); + Map* tmap = receiver_map->FindElementsKindTransitionedMap(isolate(), + *receiver_maps); if (tmap != nullptr) { - receiver_map->NotifyLeafMapLayoutChange(); + receiver_map->NotifyLeafMapLayoutChange(isolate()); } } handlers->push_back( @@ -1195,7 +1183,8 @@ bool IsOutOfBoundsAccess(Handle<Object> receiver, uint32_t index) { return index >= length; } -KeyedAccessLoadMode GetLoadMode(Handle<Object> receiver, uint32_t index) { +KeyedAccessLoadMode GetLoadMode(Isolate* isolate, Handle<Object> receiver, + uint32_t index) { if (IsOutOfBoundsAccess(receiver, index)) { if (receiver->IsJSTypedArray()) { // For JSTypedArray we never lookup elements in the prototype chain. @@ -1203,7 +1192,6 @@ KeyedAccessLoadMode GetLoadMode(Handle<Object> receiver, uint32_t index) { } // For other {receiver}s we need to check the "no elements" protector. - Isolate* isolate = Handle<HeapObject>::cast(receiver)->GetIsolate(); if (isolate->IsNoElementsProtectorIntact()) { if (receiver->IsString()) { // ToObject(receiver) will have the initial String.prototype. @@ -1254,7 +1242,7 @@ MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object, LoadIC::Load(object, Handle<Name>::cast(key)), Object); } else if (ConvertKeyToIndex(object, key, &index)) { - KeyedAccessLoadMode load_mode = GetLoadMode(object, index); + KeyedAccessLoadMode load_mode = GetLoadMode(isolate(), object, index); UpdateLoadElement(Handle<HeapObject>::cast(object), load_mode); if (is_vector_set()) { TraceIC("LoadIC", key); @@ -1298,9 +1286,9 @@ bool StoreIC::LookupForWrite(LookupIterator* it, Handle<Object> value, InterceptorInfo* info = holder->GetNamedInterceptor(); if (it->HolderIsReceiverOrHiddenPrototype()) { return !info->non_masking() && receiver.is_identical_to(holder) && - !info->setter()->IsUndefined(it->isolate()); - } else if (!info->getter()->IsUndefined(it->isolate()) || - !info->query()->IsUndefined(it->isolate())) { + !info->setter()->IsUndefined(isolate()); + } else if (!info->getter()->IsUndefined(isolate()) || + !info->query()->IsUndefined(isolate())) { return false; } break; @@ -1325,7 +1313,7 @@ bool StoreIC::LookupForWrite(LookupIterator* it, Handle<Object> value, // Receiver != holder. if (receiver->IsJSGlobalProxy()) { - PrototypeIterator iter(it->isolate(), receiver); + PrototypeIterator iter(isolate(), receiver); return it->GetHolder<Object>().is_identical_to( PrototypeIterator::GetCurrent(iter)); } @@ -1355,13 +1343,14 @@ MaybeHandle<Object> StoreGlobalIC::Store(Handle<Name> name, Handle<String> str_name = Handle<String>::cast(name); Handle<JSGlobalObject> global = isolate()->global_object(); Handle<ScriptContextTable> script_contexts( - global->native_context()->script_context_table()); + global->native_context()->script_context_table(), isolate()); ScriptContextTable::LookupResult lookup_result; - if (ScriptContextTable::Lookup(script_contexts, str_name, &lookup_result)) { + if (ScriptContextTable::Lookup(isolate(), script_contexts, str_name, + &lookup_result)) { Handle<Context> script_context = ScriptContextTable::GetContext( - script_contexts, lookup_result.context_index); - if (lookup_result.mode == CONST) { + isolate(), script_contexts, lookup_result.context_index); + if (lookup_result.mode == VariableMode::kConst) { return TypeError(MessageTemplate::kConstAssign, global, name); } @@ -1402,7 +1391,8 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name, Handle<Object> result; ASSIGN_RETURN_ON_EXCEPTION( isolate(), result, - Object::SetProperty(object, name, value, language_mode()), Object); + Object::SetProperty(isolate(), object, name, value, language_mode()), + Object); return result; } @@ -1422,7 +1412,7 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name, if (state() != UNINITIALIZED) { JSObject::MakePrototypesFast(object, kStartAtPrototype, isolate()); } - LookupIterator it(object, name); + LookupIterator it(isolate(), object, name); bool use_ic = FLAG_use_ic; if (name->IsPrivate()) { @@ -1581,7 +1571,7 @@ MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) { return MaybeObjectHandle(slow_stub()); } - CallOptimization call_optimization(setter); + CallOptimization call_optimization(isolate(), setter); if (call_optimization.is_simple_api_call()) { if (call_optimization.IsCompatibleReceiver(receiver, holder)) { CallOptimization::HolderLookup holder_lookup; @@ -1593,7 +1583,7 @@ MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) { holder_lookup == CallOptimization::kHolderIsReceiver); Handle<Context> context( - call_optimization.GetAccessorContext(holder->map())); + call_optimization.GetAccessorContext(holder->map()), isolate()); Handle<WeakCell> context_cell = isolate()->factory()->NewWeakCell(context); Handle<WeakCell> data_cell = isolate()->factory()->NewWeakCell( @@ -1653,10 +1643,12 @@ MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) { int descriptor = lookup->GetFieldDescriptorIndex(); FieldIndex index = lookup->GetFieldIndex(); PropertyConstness constness = lookup->constness(); - if (constness == kConst && IsStoreOwnICKind(nexus()->kind())) { + if (constness == PropertyConstness::kConst && + IsStoreOwnICKind(nexus()->kind())) { // StoreOwnICs are used for initializing object literals therefore - // we must store the value unconditionally even to kConst fields. - constness = kMutable; + // we must store the value unconditionally even to + // VariableMode::kConst fields. + constness = PropertyConstness::kMutable; } return MaybeObjectHandle(StoreHandler::StoreField( isolate(), descriptor, index, constness, lookup->representation())); @@ -1820,14 +1812,14 @@ Handle<Map> KeyedStoreIC::ComputeTransitionedMap( ElementsKind kind = IsHoleyElementsKind(map->elements_kind()) ? HOLEY_ELEMENTS : PACKED_ELEMENTS; - return Map::TransitionElementsTo(map, kind); + return Map::TransitionElementsTo(isolate(), map, kind); } case STORE_TRANSITION_TO_DOUBLE: case STORE_AND_GROW_TRANSITION_TO_DOUBLE: { ElementsKind kind = IsHoleyElementsKind(map->elements_kind()) ? HOLEY_DOUBLE_ELEMENTS : PACKED_DOUBLE_ELEMENTS; - return Map::TransitionElementsTo(map, kind); + return Map::TransitionElementsTo(isolate(), map, kind); } case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS: DCHECK(map->has_fixed_typed_array_elements()); @@ -1846,8 +1838,9 @@ Handle<Object> KeyedStoreIC::StoreElementHandler( store_mode == STORE_AND_GROW_NO_TRANSITION_HANDLE_COW || store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || store_mode == STORE_NO_TRANSITION_HANDLE_COW); - DCHECK_IMPLIES(receiver_map->DictionaryElementsInPrototypeChainOnly(), - IsStoreInArrayLiteralICKind(kind())); + DCHECK_IMPLIES( + receiver_map->DictionaryElementsInPrototypeChainOnly(isolate()), + IsStoreInArrayLiteralICKind(kind())); if (receiver_map->IsJSProxyMap()) { return StoreHandler::StoreProxy(isolate()); @@ -1910,7 +1903,7 @@ void KeyedStoreIC::StoreElementPolymorphicHandlers( Handle<Map> transition; if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE || - receiver_map->DictionaryElementsInPrototypeChainOnly()) { + receiver_map->DictionaryElementsInPrototypeChainOnly(isolate())) { // TODO(mvstanton): Consider embedding store_mode in the state of the slow // keyed store ic for uniformity. TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_SlowStub); @@ -1918,13 +1911,13 @@ void KeyedStoreIC::StoreElementPolymorphicHandlers( } else { { - Map* tmap = - receiver_map->FindElementsKindTransitionedMap(*receiver_maps); + Map* tmap = receiver_map->FindElementsKindTransitionedMap( + isolate(), *receiver_maps); if (tmap != nullptr) { if (receiver_map->is_stable()) { - receiver_map->NotifyLeafMapLayoutChange(); + receiver_map->NotifyLeafMapLayoutChange(isolate()); } - transition = handle(tmap); + transition = handle(tmap, isolate()); } } @@ -2040,7 +2033,7 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object, // expect to be able to trap element sets to objects with those maps in // the runtime to enable optimization of element hole access. Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object); - if (heap_object->map()->IsMapInArrayPrototypeChain()) { + if (heap_object->map()->IsMapInArrayPrototypeChain(isolate())) { set_slow_stub_reason("map in array prototype"); use_ic = false; } @@ -2087,8 +2080,8 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object, } else if (key_is_valid_index) { if (old_receiver_map->is_abandoned_prototype_map()) { set_slow_stub_reason("receiver with prototype map"); - } else if (!old_receiver_map - ->DictionaryElementsInPrototypeChainOnly()) { + } else if (!old_receiver_map->DictionaryElementsInPrototypeChainOnly( + isolate())) { // We should go generic if receiver isn't a dictionary, but our // prototype chain does have dictionary elements. This ensures that // other non-dictionary receivers in the polymorphic case benefit @@ -2114,12 +2107,12 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object, } namespace { -void StoreOwnElement(Handle<JSArray> array, Handle<Object> index, - Handle<Object> value) { +void StoreOwnElement(Isolate* isolate, Handle<JSArray> array, + Handle<Object> index, Handle<Object> value) { DCHECK(index->IsNumber()); bool success = false; LookupIterator it = LookupIterator::PropertyOrElement( - array->GetIsolate(), array, index, &success, LookupIterator::OWN); + isolate, array, index, &success, LookupIterator::OWN); DCHECK(success); CHECK(JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, NONE, @@ -2130,11 +2123,11 @@ void StoreOwnElement(Handle<JSArray> array, Handle<Object> index, void StoreInArrayLiteralIC::Store(Handle<JSArray> array, Handle<Object> index, Handle<Object> value) { - DCHECK(!array->map()->IsMapInArrayPrototypeChain()); + DCHECK(!array->map()->IsMapInArrayPrototypeChain(isolate())); DCHECK(index->IsNumber()); if (!FLAG_use_ic || MigrateDeprecated(array)) { - StoreOwnElement(array, index, value); + StoreOwnElement(isolate(), array, index, value); TraceIC("StoreInArrayLiteralIC", index); return; } @@ -2150,7 +2143,7 @@ void StoreInArrayLiteralIC::Store(Handle<JSArray> array, Handle<Object> index, Handle<Map> old_array_map(array->map(), isolate()); bool array_was_cow = array->elements()->IsCowArray(); - StoreOwnElement(array, index, value); + StoreOwnElement(isolate(), array, index, value); if (index->IsSmi()) { DCHECK(!old_array_map->is_abandoned_prototype_map()); @@ -2227,15 +2220,16 @@ RUNTIME_FUNCTION(Runtime_LoadGlobalIC_Slow) { Handle<Context> native_context = isolate->native_context(); Handle<ScriptContextTable> script_contexts( - native_context->script_context_table()); + native_context->script_context_table(), isolate); ScriptContextTable::LookupResult lookup_result; - if (ScriptContextTable::Lookup(script_contexts, name, &lookup_result)) { + if (ScriptContextTable::Lookup(isolate, script_contexts, name, + &lookup_result)) { Handle<Context> script_context = ScriptContextTable::GetContext( - script_contexts, lookup_result.context_index); + isolate, script_contexts, lookup_result.context_index); Handle<Object> result = FixedArray::get(*script_context, lookup_result.slot_index, isolate); - if (*result == isolate->heap()->the_hole_value()) { + if (*result == ReadOnlyRoots(isolate).the_hole_value()) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewReferenceError(MessageTemplate::kNotDefined, name)); } @@ -2343,13 +2337,14 @@ RUNTIME_FUNCTION(Runtime_StoreGlobalIC_Slow) { Handle<JSGlobalObject> global = isolate->global_object(); Handle<Context> native_context = isolate->native_context(); Handle<ScriptContextTable> script_contexts( - native_context->script_context_table()); + native_context->script_context_table(), isolate); ScriptContextTable::LookupResult lookup_result; - if (ScriptContextTable::Lookup(script_contexts, name, &lookup_result)) { + if (ScriptContextTable::Lookup(isolate, script_contexts, name, + &lookup_result)) { Handle<Context> script_context = ScriptContextTable::GetContext( - script_contexts, lookup_result.context_index); - if (lookup_result.mode == CONST) { + isolate, script_contexts, lookup_result.context_index); + if (lookup_result.mode == VariableMode::kConst) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kConstAssign, global, name)); } @@ -2427,7 +2422,7 @@ RUNTIME_FUNCTION(Runtime_StoreInArrayLiteralIC_Slow) { Handle<Object> value = args.at(0); Handle<Object> array = args.at(1); Handle<Object> index = args.at(2); - StoreOwnElement(Handle<JSArray>::cast(array), index, value); + StoreOwnElement(isolate, Handle<JSArray>::cast(array), index, value); return *value; } @@ -2450,7 +2445,7 @@ RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) { } if (IsStoreInArrayLiteralICKind(kind)) { - StoreOwnElement(Handle<JSArray>::cast(object), key, value); + StoreOwnElement(isolate, Handle<JSArray>::cast(object), key, value); return *value; } else { DCHECK(IsKeyedStoreICKind(kind) || IsStoreICKind(kind)); @@ -2480,7 +2475,8 @@ RUNTIME_FUNCTION(Runtime_StoreCallbackProperty) { Handle<AccessorInfo> info( callback_or_cell->IsWeakCell() ? AccessorInfo::cast(WeakCell::cast(*callback_or_cell)->value()) - : AccessorInfo::cast(*callback_or_cell)); + : AccessorInfo::cast(*callback_or_cell), + isolate); DCHECK(info->IsCompatibleReceiver(*receiver)); @@ -2539,7 +2535,7 @@ RUNTIME_FUNCTION(Runtime_LoadPropertyWithInterceptor) { // It could actually be any kind of load IC slot here but the predicate // handles all the cases properly. if (!LoadIC::ShouldThrowReferenceError(slot_kind)) { - return isolate->heap()->undefined_value(); + return ReadOnlyRoots(isolate).undefined_value(); } // Throw a reference error. @@ -2593,7 +2589,7 @@ RUNTIME_FUNCTION(Runtime_StorePropertyWithInterceptor) { MAYBE_RETURN(Object::SetProperty(&it, value, language_mode, JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED), - isolate->heap()->exception()); + ReadOnlyRoots(isolate).exception()); return *value; } diff --git a/deps/v8/src/ic/ic.h b/deps/v8/src/ic/ic.h index 22f3cb9c26..feac4dc63b 100644 --- a/deps/v8/src/ic/ic.h +++ b/deps/v8/src/ic/ic.h @@ -59,8 +59,7 @@ class IC { IsKeyedStoreIC() || IsStoreInArrayLiteralICKind(kind()); } - static inline bool IsHandler(MaybeObject* object, - bool from_stub_cache = false); + static inline bool IsHandler(MaybeObject* object); // Nofity the IC system that a feedback has changed. static void OnFeedbackChanged(Isolate* isolate, FeedbackVector* vector, @@ -145,7 +144,7 @@ class IC { if (receiver->IsSmi()) { receiver_map_ = isolate_->factory()->heap_number_map(); } else { - receiver_map_ = handle(HeapObject::cast(*receiver)->map()); + receiver_map_ = handle(HeapObject::cast(*receiver)->map(), isolate_); } } diff --git a/deps/v8/src/ic/keyed-store-generic.cc b/deps/v8/src/ic/keyed-store-generic.cc index 13eaee8e2b..4257f05914 100644 --- a/deps/v8/src/ic/keyed-store-generic.cc +++ b/deps/v8/src/ic/keyed-store-generic.cc @@ -262,8 +262,8 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( // The length property is non-configurable, so it's guaranteed to always // be the first property. TNode<DescriptorArray> descriptors = LoadMapDescriptors(receiver_map); - TNode<Int32T> details = LoadAndUntagToWord32FixedArrayElement( - descriptors, DescriptorArray::ToDetailsIndex(0)); + TNode<Uint32T> details = LoadDetailsByKeyIndex( + descriptors, IntPtrConstant(DescriptorArray::ToKeyIndex(0))); GotoIf(IsSetWord32(details, PropertyDetails::kAttributesReadOnlyMask), slow); } @@ -573,10 +573,9 @@ void KeyedStoreGenericAssembler::LookupPropertyOnPrototypeChain( &var_entry, &next_proto, bailout); BIND(&found_fast); { - Node* descriptors = var_meta_storage.value(); - Node* name_index = var_entry.value(); - Node* details = - LoadDetailsByKeyIndex<DescriptorArray>(descriptors, name_index); + TNode<DescriptorArray> descriptors = CAST(var_meta_storage.value()); + TNode<IntPtrT> name_index = var_entry.value(); + Node* details = LoadDetailsByKeyIndex(descriptors, name_index); JumpIfDataProperty(details, &ok_to_write, readonly); // Accessor case. @@ -651,7 +650,7 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( BIND(&fast_properties); { Comment("fast property store"); - Node* descriptors = LoadMapDescriptors(receiver_map); + 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, @@ -659,9 +658,8 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( BIND(&descriptor_found); { - Node* name_index = var_name_index.value(); - Node* details = - LoadDetailsByKeyIndex<DescriptorArray>(descriptors, name_index); + TNode<IntPtrT> name_index = var_name_index.value(); + Node* details = LoadDetailsByKeyIndex(descriptors, name_index); Label data_property(this); JumpIfDataProperty(details, &data_property, &readonly); diff --git a/deps/v8/src/ic/stub-cache.cc b/deps/v8/src/ic/stub-cache.cc index a9cafd6648..4958726a22 100644 --- a/deps/v8/src/ic/stub-cache.cc +++ b/deps/v8/src/ic/stub-cache.cc @@ -58,31 +58,32 @@ int StubCache::SecondaryOffset(Name* name, int seed) { namespace { bool CommonStubCacheChecks(StubCache* stub_cache, Name* name, Map* map, - Object* handler) { + MaybeObject* handler) { // Validate that the name and handler do not move on scavenge, and that we // can use identity checks instead of structural equality checks. - DCHECK(!name->GetHeap()->InNewSpace(name)); - DCHECK(!name->GetHeap()->InNewSpace(handler)); + DCHECK(!Heap::InNewSpace(name)); + DCHECK(!Heap::InNewSpace(handler)); DCHECK(name->IsUniqueName()); DCHECK(name->HasHashCode()); - if (handler) DCHECK(IC::IsHandler(MaybeObject::FromObject(handler), true)); + if (handler) DCHECK(IC::IsHandler(handler)); return true; } } // namespace #endif -Object* StubCache::Set(Name* name, Map* map, Object* handler) { +MaybeObject* StubCache::Set(Name* name, Map* map, MaybeObject* handler) { DCHECK(CommonStubCacheChecks(this, name, map, handler)); // Compute the primary entry. int primary_offset = PrimaryOffset(name, map); Entry* primary = entry(primary_, primary_offset); - Object* old_handler = primary->value; + MaybeObject* old_handler = primary->value; // If the primary entry has useful data in it, we retire it to the // secondary cache before overwriting it. - if (old_handler != isolate_->builtins()->builtin(Builtins::kIllegal)) { + if (old_handler != MaybeObject::FromObject( + isolate_->builtins()->builtin(Builtins::kIllegal))) { Map* old_map = primary->map; int seed = PrimaryOffset(primary->key, old_map); int secondary_offset = SecondaryOffset(primary->key, seed); @@ -98,7 +99,7 @@ Object* StubCache::Set(Name* name, Map* map, Object* handler) { return handler; } -Object* StubCache::Get(Name* name, Map* map) { +MaybeObject* StubCache::Get(Name* name, Map* map) { DCHECK(CommonStubCacheChecks(this, name, map, nullptr)); int primary_offset = PrimaryOffset(name, map); Entry* primary = entry(primary_, primary_offset); @@ -115,14 +116,16 @@ Object* StubCache::Get(Name* name, Map* map) { void StubCache::Clear() { - Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal); + MaybeObject* empty = MaybeObject::FromObject( + isolate_->builtins()->builtin(Builtins::kIllegal)); + Name* empty_string = ReadOnlyRoots(isolate()).empty_string(); for (int i = 0; i < kPrimaryTableSize; i++) { - primary_[i].key = isolate()->heap()->empty_string(); + primary_[i].key = empty_string; primary_[i].map = nullptr; primary_[i].value = empty; } for (int j = 0; j < kSecondaryTableSize; j++) { - secondary_[j].key = isolate()->heap()->empty_string(); + secondary_[j].key = empty_string; secondary_[j].map = nullptr; secondary_[j].value = empty; } diff --git a/deps/v8/src/ic/stub-cache.h b/deps/v8/src/ic/stub-cache.h index 870266eefd..5cff496b15 100644 --- a/deps/v8/src/ic/stub-cache.h +++ b/deps/v8/src/ic/stub-cache.h @@ -34,14 +34,14 @@ class StubCache { public: struct Entry { Name* key; - Object* value; + MaybeObject* value; Map* map; }; void Initialize(); // Access cache for entry hash(name, map). - Object* Set(Name* name, Map* map, Object* handler); - Object* Get(Name* name, Map* map); + MaybeObject* Set(Name* name, Map* map, MaybeObject* handler); + MaybeObject* Get(Name* name, Map* map); // Clear the lookup table (@ mark compact collection). void Clear(); |