diff options
Diffstat (limited to 'deps/v8/src/ic/accessor-assembler.cc')
-rw-r--r-- | deps/v8/src/ic/accessor-assembler.cc | 741 |
1 files changed, 382 insertions, 359 deletions
diff --git a/deps/v8/src/ic/accessor-assembler.cc b/deps/v8/src/ic/accessor-assembler.cc index 98c86c2263..7aebf857a2 100644 --- a/deps/v8/src/ic/accessor-assembler.cc +++ b/deps/v8/src/ic/accessor-assembler.cc @@ -107,12 +107,12 @@ void AccessorAssembler::HandlePolymorphicCase( // Load the {feedback} array length. TNode<IntPtrT> length = LoadAndUntagWeakFixedArrayLength(feedback); - CSA_ASSERT(this, IntPtrLessThanOrEqual(IntPtrConstant(1), length)); + CSA_ASSERT(this, IntPtrLessThanOrEqual(IntPtrConstant(kEntrySize), length)); - // This is a hand-crafted loop that only compares against the {length} - // in the end, since we already know that we will have at least a single - // entry in the {feedback} array anyways. - TVARIABLE(IntPtrT, var_index, IntPtrConstant(0)); + // This is a hand-crafted loop that iterates backwards and only compares + // against zero at the end, since we already know that we will have at least a + // single entry in the {feedback} array anyways. + TVARIABLE(IntPtrT, var_index, IntPtrSub(length, IntPtrConstant(kEntrySize))); Label loop(this, &var_index), loop_next(this); Goto(&loop); BIND(&loop); @@ -131,18 +131,19 @@ void AccessorAssembler::HandlePolymorphicCase( BIND(&loop_next); var_index = - Signed(IntPtrAdd(var_index.value(), IntPtrConstant(kEntrySize))); - Branch(IntPtrLessThan(var_index.value(), length), &loop, if_miss); + Signed(IntPtrSub(var_index.value(), IntPtrConstant(kEntrySize))); + Branch(IntPtrGreaterThanOrEqual(var_index.value(), IntPtrConstant(0)), + &loop, if_miss); } } void AccessorAssembler::HandleLoadICHandlerCase( - const LoadICParameters* p, TNode<Object> handler, Label* miss, + const LazyLoadICParameters* p, TNode<Object> handler, Label* miss, ExitPoint* exit_point, ICMode ic_mode, OnNonExistent on_nonexistent, ElementSupport support_elements, LoadAccessMode access_mode) { Comment("have_handler"); - VARIABLE(var_holder, MachineRepresentation::kTagged, p->holder); + VARIABLE(var_holder, MachineRepresentation::kTagged, p->holder()); VARIABLE(var_smi_handler, MachineRepresentation::kTagged, handler); Variable* vars[] = {&var_holder, &var_smi_handler}; @@ -152,6 +153,14 @@ void AccessorAssembler::HandleLoadICHandlerCase( Branch(TaggedIsSmi(handler), &if_smi_handler, &try_proto_handler); + BIND(&try_proto_handler); + { + GotoIf(IsCodeMap(LoadMap(CAST(handler))), &call_handler); + HandleLoadICProtoHandler(p, handler, &var_holder, &var_smi_handler, + &if_smi_handler, miss, exit_point, ic_mode, + access_mode); + } + // |handler| is a Smi, encoding what to do. See SmiHandler methods // for the encoding format. BIND(&if_smi_handler); @@ -161,49 +170,34 @@ void AccessorAssembler::HandleLoadICHandlerCase( support_elements, access_mode); } - BIND(&try_proto_handler); - { - GotoIf(IsCodeMap(LoadMap(CAST(handler))), &call_handler); - HandleLoadICProtoHandler(p, handler, &var_holder, &var_smi_handler, - &if_smi_handler, miss, exit_point, ic_mode, - access_mode); - } - BIND(&call_handler); { - exit_point->ReturnCallStub(LoadWithVectorDescriptor{}, handler, p->context, - p->receiver, p->name, p->slot, p->vector); + exit_point->ReturnCallStub(LoadWithVectorDescriptor{}, handler, + p->context(), p->receiver(), p->name(), + p->slot(), p->vector()); } } -void AccessorAssembler::HandleLoadCallbackProperty(const LoadICParameters* p, - TNode<JSObject> holder, - TNode<WordT> handler_word, - ExitPoint* exit_point) { +void AccessorAssembler::HandleLoadCallbackProperty( + const LazyLoadICParameters* p, TNode<JSObject> holder, + TNode<WordT> handler_word, ExitPoint* exit_point) { Comment("native_data_property_load"); TNode<IntPtrT> descriptor = Signed(DecodeWord<LoadHandler::DescriptorBits>(handler_word)); - Label runtime(this, Label::kDeferred); Callable callable = CodeFactory::ApiGetter(isolate()); TNode<AccessorInfo> accessor_info = CAST(LoadDescriptorValue(LoadMap(holder), descriptor)); - GotoIf(IsRuntimeCallStatsEnabled(), &runtime); - exit_point->ReturnCallStub(callable, p->context, p->receiver, holder, + exit_point->ReturnCallStub(callable, p->context(), p->receiver(), holder, accessor_info); - - BIND(&runtime); - exit_point->ReturnCallRuntime(Runtime::kLoadCallbackProperty, p->context, - p->receiver, holder, accessor_info, p->name); } void AccessorAssembler::HandleLoadAccessor( - const LoadICParameters* p, TNode<CallHandlerInfo> call_handler_info, + const LazyLoadICParameters* p, TNode<CallHandlerInfo> call_handler_info, TNode<WordT> handler_word, TNode<DataHandler> handler, TNode<IntPtrT> handler_kind, ExitPoint* exit_point) { Comment("api_getter"); - Label runtime(this, Label::kDeferred); // Context is stored either in data2 or data3 field depending on whether // the access check is enabled for this handler or not. TNode<MaybeObject> maybe_context = Select<MaybeObject>( @@ -215,39 +209,31 @@ void AccessorAssembler::HandleLoadAccessor( CSA_CHECK(this, IsNotCleared(maybe_context)); TNode<Object> context = GetHeapObjectAssumeWeak(maybe_context); - GotoIf(IsRuntimeCallStatsEnabled(), &runtime); - { - TNode<Foreign> foreign = CAST( - LoadObjectField(call_handler_info, CallHandlerInfo::kJsCallbackOffset)); - TNode<WordT> callback = TNode<WordT>::UncheckedCast(LoadObjectField( - foreign, Foreign::kForeignAddressOffset, MachineType::Pointer())); - TNode<Object> data = - LoadObjectField(call_handler_info, CallHandlerInfo::kDataOffset); - - VARIABLE(api_holder, MachineRepresentation::kTagged, p->receiver); - Label load(this); - GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kApiGetter)), - &load); + TNode<Foreign> foreign = CAST( + LoadObjectField(call_handler_info, CallHandlerInfo::kJsCallbackOffset)); + TNode<WordT> callback = TNode<WordT>::UncheckedCast(LoadObjectField( + foreign, Foreign::kForeignAddressOffset, MachineType::Pointer())); + TNode<Object> data = + LoadObjectField(call_handler_info, CallHandlerInfo::kDataOffset); - CSA_ASSERT( - this, - WordEqual(handler_kind, - IntPtrConstant(LoadHandler::kApiGetterHolderIsPrototype))); + VARIABLE(api_holder, MachineRepresentation::kTagged, p->receiver()); + Label load(this); + GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kApiGetter)), + &load); - api_holder.Bind(LoadMapPrototype(LoadMap(p->receiver))); - Goto(&load); + CSA_ASSERT( + this, + WordEqual(handler_kind, + IntPtrConstant(LoadHandler::kApiGetterHolderIsPrototype))); - BIND(&load); - Callable callable = CodeFactory::CallApiCallback(isolate()); - TNode<IntPtrT> argc = IntPtrConstant(0); - exit_point->Return(CallStub(callable, context, callback, argc, data, - api_holder.value(), p->receiver)); - } + api_holder.Bind(LoadMapPrototype(LoadMap(p->receiver()))); + Goto(&load); - BIND(&runtime); - exit_point->ReturnCallRuntime(Runtime::kLoadAccessorProperty, context, - p->receiver, SmiTag(handler_kind), - call_handler_info); + BIND(&load); + Callable callable = CodeFactory::CallApiCallback(isolate()); + TNode<IntPtrT> argc = IntPtrConstant(0); + exit_point->Return(CallStub(callable, context, callback, argc, data, + api_holder.value(), p->receiver())); } void AccessorAssembler::HandleLoadField(Node* holder, Node* handler_word, @@ -305,7 +291,7 @@ TNode<MaybeObject> AccessorAssembler::LoadDescriptorValueOrFieldType( } void AccessorAssembler::HandleLoadICSmiHandlerCase( - const LoadICParameters* p, Node* holder, SloppyTNode<Smi> smi_handler, + const LazyLoadICParameters* p, Node* holder, SloppyTNode<Smi> smi_handler, SloppyTNode<Object> handler, Label* miss, ExitPoint* exit_point, OnNonExistent on_nonexistent, ElementSupport support_elements, LoadAccessMode access_mode) { @@ -333,7 +319,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( BIND(&if_element); Comment("element_load"); - Node* intptr_index = TryToIntptr(p->name, miss); + Node* intptr_index = TryToIntptr(p->name(), miss); Node* is_jsarray_condition = IsSetWord<LoadHandler::IsJsArrayBits>(handler_word); Node* elements_kind = @@ -399,7 +385,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( Label if_oob(this, Label::kDeferred); Comment("indexed string"); - Node* intptr_index = TryToIntptr(p->name, miss); + Node* intptr_index = TryToIntptr(p->name(), miss); Node* length = LoadStringLengthAsWord(holder); GotoIf(UintPtrGreaterThanOrEqual(intptr_index, length), &if_oob); TNode<Int32T> code = StringCharCodeAt(holder, intptr_index); @@ -430,7 +416,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( } void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( - const LoadICParameters* p, Node* holder, TNode<IntPtrT> handler_kind, + const LazyLoadICParameters* p, Node* holder, TNode<IntPtrT> handler_kind, TNode<WordT> handler_word, Label* rebox_double, Variable* var_double_value, SloppyTNode<Object> handler, Label* miss, ExitPoint* exit_point, OnNonExistent on_nonexistent, ElementSupport support_elements) { @@ -438,7 +424,8 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( interceptor(this, Label::kDeferred), nonexistent(this), accessor(this, Label::kDeferred), global(this, Label::kDeferred), module_export(this, Label::kDeferred), proxy(this, Label::kDeferred), - native_data_property(this), api_getter(this); + 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)), @@ -479,8 +466,8 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( BIND(&nonexistent); // This is a handler for a load of a non-existent value. if (on_nonexistent == OnNonExistent::kThrowReferenceError) { - exit_point->ReturnCallRuntime(Runtime::kThrowReferenceError, p->context, - p->name); + exit_point->ReturnCallRuntime(Runtime::kThrowReferenceError, p->context(), + p->name()); } else { DCHECK_EQ(OnNonExistent::kReturnUndefined, on_nonexistent); exit_point->Return(UndefinedConstant()); @@ -502,7 +489,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( TNode<NameDictionary> properties = CAST(LoadSlowProperties(holder)); TVARIABLE(IntPtrT, var_name_index); Label found(this, &var_name_index); - NameDictionaryLookup<NameDictionary>(properties, CAST(p->name), &found, + NameDictionaryLookup<NameDictionary>(properties, CAST(p->name()), &found, &var_name_index, miss); BIND(&found); { @@ -511,7 +498,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( LoadPropertyFromNameDictionary(properties, var_name_index.value(), &var_details, &var_value); Node* value = CallGetterIfAccessor(var_value.value(), var_details.value(), - p->context, p->receiver, miss); + p->context(), p->receiver(), miss); exit_point->Return(value); } } @@ -527,7 +514,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( CSA_ASSERT(this, Word32BinaryNot(IsTheHole(getter))); Callable callable = CodeFactory::Call(isolate()); - exit_point->Return(CallJS(callable, p->context, getter, p->receiver)); + exit_point->Return(CallJS(callable, p->context(), getter, p->receiver())); } BIND(&native_data_property); @@ -548,13 +535,13 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( if (support_elements == kSupportElements) { DCHECK_NE(on_nonexistent, OnNonExistent::kThrowReferenceError); - TryToName(p->name, &if_index, &var_index, &if_unique_name, &var_unique, + 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); @@ -563,13 +550,15 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( Goto(&to_name_failed); BIND(&to_name_failed); + // TODO(duongn): use GetPropertyWithReceiver builtin once + // |lookup_element_in_holder| supports elements. exit_point->ReturnCallRuntime(Runtime::kGetPropertyWithReceiver, - p->context, holder, p->name, p->receiver, - SmiConstant(on_nonexistent)); + 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)); } } @@ -583,16 +572,16 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( holder, PropertyCell::kPropertyDetailsRawOffset); GotoIf(IsTheHole(value), miss); - exit_point->Return( - CallGetterIfAccessor(value, details, p->context, p->receiver, miss)); + exit_point->Return(CallGetterIfAccessor(value, details, p->context(), + p->receiver(), miss)); } BIND(&interceptor); { Comment("load_interceptor"); exit_point->ReturnCallRuntime(Runtime::kLoadPropertyWithInterceptor, - p->context, p->name, p->receiver, holder, - p->slot, p->vector); + p->context(), p->name(), p->receiver(), + holder, p->slot(), p->vector()); } BIND(&module_export); @@ -600,7 +589,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( Comment("module export"); Node* index = DecodeWord<LoadHandler::ExportsIndexBits>(handler_word); Node* module = - LoadObjectField(p->receiver, JSModuleNamespace::kModuleOffset, + LoadObjectField(p->receiver(), JSModuleNamespace::kModuleOffset, MachineType::TaggedPointer()); TNode<ObjectHashTable> exports = CAST(LoadObjectField( module, Module::kExportsOffset, MachineType::TaggedPointer())); @@ -615,8 +604,8 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( BIND(&is_the_hole); { Node* message = SmiConstant(MessageTemplate::kNotDefined); - exit_point->ReturnCallRuntime(Runtime::kThrowReferenceError, p->context, - message, p->name); + exit_point->ReturnCallRuntime(Runtime::kThrowReferenceError, p->context(), + message, p->name()); } } @@ -625,7 +614,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( } void AccessorAssembler::HandleLoadICSmiHandlerHasNamedCase( - const LoadICParameters* p, Node* holder, TNode<IntPtrT> handler_kind, + const LazyLoadICParameters* p, Node* holder, TNode<IntPtrT> handler_kind, Label* miss, ExitPoint* exit_point) { Label return_true(this), return_false(this), return_lookup(this), normal(this), global(this); @@ -676,8 +665,8 @@ void AccessorAssembler::HandleLoadICSmiHandlerHasNamedCase( WordEqual(handler_kind, IntPtrConstant(LoadHandler::kModuleExport))))); exit_point->ReturnCallStub( - Builtins::CallableFor(isolate(), Builtins::kHasProperty), p->context, - p->receiver, p->name); + Builtins::CallableFor(isolate(), Builtins::kHasProperty), p->context(), + p->receiver(), p->name()); } BIND(&normal); @@ -686,7 +675,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerHasNamedCase( TNode<NameDictionary> properties = CAST(LoadSlowProperties(holder)); TVARIABLE(IntPtrT, var_name_index); Label found(this); - NameDictionaryLookup<NameDictionary>(properties, CAST(p->name), &found, + NameDictionaryLookup<NameDictionary>(properties, CAST(p->name()), &found, &var_name_index, miss); BIND(&found); @@ -780,8 +769,8 @@ Node* AccessorAssembler::HandleProtoHandler( CSA_ASSERT(this, IsWeakOrCleared(data2)); TNode<Object> expected_native_context = GetHeapObjectAssumeWeak(data2, miss); - EmitAccessCheck(expected_native_context, p->context, p->receiver, &done, - miss); + EmitAccessCheck(expected_native_context, p->context(), p->receiver(), + &done, miss); } // Dictionary lookup on receiver is not necessary for Load/StoreGlobalIC @@ -791,14 +780,14 @@ Node* AccessorAssembler::HandleProtoHandler( { DCHECK_EQ(ICMode::kNonGlobalIC, ic_mode); CSA_ASSERT(this, Word32BinaryNot(HasInstanceType( - p->receiver, JS_GLOBAL_OBJECT_TYPE))); + p->receiver(), JS_GLOBAL_OBJECT_TYPE))); TNode<NameDictionary> properties = - CAST(LoadSlowProperties(p->receiver)); + CAST(LoadSlowProperties(p->receiver())); TVARIABLE(IntPtrT, var_name_index); Label found(this, &var_name_index); - NameDictionaryLookup<NameDictionary>(properties, CAST(p->name), &found, - &var_name_index, &done); + NameDictionaryLookup<NameDictionary>(properties, CAST(p->name()), + &found, &var_name_index, &done); BIND(&found); { if (on_found_on_receiver) { @@ -816,7 +805,7 @@ Node* AccessorAssembler::HandleProtoHandler( } void AccessorAssembler::HandleLoadICProtoHandler( - const LoadICParameters* p, Node* handler, Variable* var_holder, + const LazyLoadICParameters* p, Node* handler, Variable* var_holder, Variable* var_smi_handler, Label* if_smi_handler, Label* miss, ExitPoint* exit_point, ICMode ic_mode, LoadAccessMode access_mode) { DCHECK_EQ(MachineRepresentation::kTagged, var_holder->rep()); @@ -837,7 +826,7 @@ void AccessorAssembler::HandleLoadICProtoHandler( &var_value); Node* value = CallGetterIfAccessor(var_value.value(), var_details.value(), - p->context, p->receiver, miss); + p->context(), p->receiver(), miss); exit_point->Return(value); } }, @@ -910,8 +899,8 @@ void AccessorAssembler::HandleStoreICNativeDataProperty( Node* accessor_info = LoadDescriptorValue(LoadMap(holder), descriptor); CSA_CHECK(this, IsAccessorInfo(accessor_info)); - TailCallRuntime(Runtime::kStoreCallbackProperty, p->context, p->receiver, - holder, accessor_info, p->name, p->value); + TailCallRuntime(Runtime::kStoreCallbackProperty, p->context(), p->receiver(), + holder, accessor_info, p->name(), p->value()); } void AccessorAssembler::HandleStoreICHandlerCase( @@ -927,7 +916,7 @@ void AccessorAssembler::HandleStoreICHandlerCase( // for the encoding format. BIND(&if_smi_handler); { - Node* holder = p->receiver; + Node* holder = p->receiver(); Node* handler_word = SmiUntag(CAST(handler)); Label if_fast_smi(this), if_proxy(this); @@ -949,7 +938,7 @@ void AccessorAssembler::HandleStoreICHandlerCase( TVARIABLE(IntPtrT, var_name_index); Label dictionary_found(this, &var_name_index); NameDictionaryLookup<NameDictionary>( - properties, CAST(p->name), &dictionary_found, &var_name_index, miss); + properties, CAST(p->name()), &dictionary_found, &var_name_index, miss); BIND(&dictionary_found); { Node* details = LoadDetailsByKeyIndex<NameDictionary>( @@ -961,8 +950,8 @@ void AccessorAssembler::HandleStoreICHandlerCase( GotoIf(IsSetWord32(details, kTypeAndReadOnlyMask), miss); StoreValueByKeyIndex<NameDictionary>(properties, var_name_index.value(), - p->value); - Return(p->value); + p->value()); + Return(p->value()); } BIND(&if_fast_smi); @@ -984,7 +973,7 @@ void AccessorAssembler::HandleStoreICHandlerCase( BIND(&data); // Handle non-transitioning field stores. - HandleStoreICSmiHandlerCase(handler_word, holder, p->value, miss); + HandleStoreICSmiHandlerCase(handler_word, holder, p->value(), miss); } BIND(&if_proxy); @@ -1008,8 +997,8 @@ void AccessorAssembler::HandleStoreICHandlerCase( BIND(&call_handler); { TailCallStub(StoreWithVectorDescriptor{}, CAST(strong_handler), - CAST(p->context), p->receiver, p->name, p->value, p->slot, - p->vector); + p->context(), p->receiver(), p->name(), p->value(), + p->slot(), p->vector()); } } @@ -1027,7 +1016,7 @@ void AccessorAssembler::HandleStoreICHandlerCase( { TNode<PropertyCell> property_cell = CAST(map_or_property_cell); ExitPoint direct_exit(this); - StoreGlobalIC_PropertyCellCase(property_cell, p->value, &direct_exit, + StoreGlobalIC_PropertyCellCase(property_cell, p->value(), &direct_exit, miss); } BIND(&store_transition); @@ -1035,7 +1024,7 @@ void AccessorAssembler::HandleStoreICHandlerCase( TNode<Map> map = CAST(map_or_property_cell); HandleStoreICTransitionMapHandlerCase(p, map, miss, kCheckPrototypeValidity); - Return(p->value); + Return(p->value()); } } } @@ -1064,10 +1053,10 @@ void AccessorAssembler::HandleStoreICTransitionMapHandlerCase( 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(WordNotEqual(key, p->name()), miss); } else { CSA_ASSERT(this, WordEqual(LoadKeyByKeyIndex(descriptors, last_key_index), - p->name)); + p->name())); } Node* details = LoadDetailsByKeyIndex(descriptors, last_key_index); if (flags & kValidateTransitionHandler) { @@ -1088,14 +1077,14 @@ void AccessorAssembler::HandleStoreICTransitionMapHandlerCase( // DontEnum attribute is allowed only for private symbols and vice versa. Branch(Word32Equal( IsSetWord32(details, PropertyDetails::kAttributesDontEnumMask), - IsPrivateSymbol(p->name)), + IsPrivateSymbol(p->name())), &attributes_ok, miss); BIND(&attributes_ok); } - OverwriteExistingFastDataProperty(p->receiver, transition_map, descriptors, - last_key_index, details, p->value, miss, + OverwriteExistingFastDataProperty(p->receiver(), transition_map, descriptors, + last_key_index, details, p->value(), miss, true); } @@ -1207,7 +1196,7 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( &double_rep, &tagged_rep); BIND(&double_rep); { - TNode<Float64T> double_value = ChangeNumberToFloat64(value); + TNode<Float64T> double_value = ChangeNumberToFloat64(CAST(value)); if (FLAG_unbox_double_fields) { if (do_transitioning_store) { StoreMap(object, object_map); @@ -1275,7 +1264,7 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( Int32Constant(Representation::kDouble)), &cont); { - Node* double_value = ChangeNumberToFloat64(value); + Node* double_value = ChangeNumberToFloat64(CAST(value)); Node* mutable_heap_number = AllocateMutableHeapNumberWithValue(double_value); var_value.Bind(mutable_heap_number); @@ -1301,7 +1290,7 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( { Node* mutable_heap_number = LoadPropertyArrayElement(properties, backing_store_index); - TNode<Float64T> double_value = ChangeNumberToFloat64(value); + TNode<Float64T> double_value = ChangeNumberToFloat64(CAST(value)); Label if_mutable(this); GotoIfNot(IsPropertyDetailsConst(details), &if_mutable); @@ -1370,7 +1359,7 @@ void AccessorAssembler::HandleStoreAccessor(const StoreICParameters* p, CSA_ASSERT(this, Word32BinaryNot(IsTheHole(setter))); Callable callable = CodeFactory::Call(isolate()); - Return(CallJS(callable, p->context, setter, p->receiver, p->value)); + Return(CallJS(callable, p->context(), setter, p->receiver(), p->value())); } void AccessorAssembler::HandleStoreICProtoHandler( @@ -1388,8 +1377,9 @@ void AccessorAssembler::HandleStoreICProtoHandler( &if_transitioning_element_store); BIND(&if_element_store); { - TailCallStub(StoreWithVectorDescriptor{}, 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); @@ -1401,9 +1391,9 @@ void AccessorAssembler::HandleStoreICProtoHandler( GotoIf(IsDeprecatedMap(transition_map), miss); - TailCallStub(StoreTransitionDescriptor{}, 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()); } }; } @@ -1422,8 +1412,8 @@ void AccessorAssembler::HandleStoreICProtoHandler( GotoIf(IsSetWord32(details, kTypeAndReadOnlyMask), miss); StoreValueByKeyIndex<NameDictionary>( - CAST(properties), UncheckedCast<IntPtrT>(name_index), p->value); - Return(p->value); + CAST(properties), UncheckedCast<IntPtrT>(name_index), p->value()); + Return(p->value()); }, miss, ic_mode); @@ -1470,16 +1460,17 @@ void AccessorAssembler::HandleStoreICProtoHandler( // case is covered above by LookupOnReceiver bit handling of the smi // handler. Label slow(this); - TNode<Map> receiver_map = LoadMap(p->receiver); + TNode<Map> receiver_map = LoadMap(p->receiver()); InvalidateValidityCellIfPrototype(receiver_map); - TNode<NameDictionary> properties = CAST(LoadSlowProperties(p->receiver)); - Add<NameDictionary>(properties, CAST(p->name), p->value, &slow); - Return(p->value); + TNode<NameDictionary> properties = + CAST(LoadSlowProperties(p->receiver())); + Add<NameDictionary>(properties, CAST(p->name()), p->value(), &slow); + Return(p->value()); BIND(&slow); - TailCallRuntime(Runtime::kAddDictionaryProperty, p->context, p->receiver, - p->name, p->value); + TailCallRuntime(Runtime::kAddDictionaryProperty, p->context(), + p->receiver(), p->name(), p->value()); } BIND(&if_accessor); @@ -1513,7 +1504,7 @@ void AccessorAssembler::HandleStoreICProtoHandler( Node* data = LoadObjectField(call_handler_info, CallHandlerInfo::kDataOffset); - VARIABLE(api_holder, MachineRepresentation::kTagged, p->receiver); + VARIABLE(api_holder, MachineRepresentation::kTagged, p->receiver()); Label store(this); GotoIf(WordEqual(handler_kind, IntPtrConstant(StoreHandler::kApiSetter)), &store); @@ -1523,20 +1514,20 @@ void AccessorAssembler::HandleStoreICProtoHandler( WordEqual(handler_kind, IntPtrConstant(StoreHandler::kApiSetterHolderIsPrototype))); - api_holder.Bind(LoadMapPrototype(LoadMap(p->receiver))); + api_holder.Bind(LoadMapPrototype(LoadMap(p->receiver()))); Goto(&store); BIND(&store); Callable callable = CodeFactory::CallApiCallback(isolate()); TNode<IntPtrT> argc = IntPtrConstant(1); Return(CallStub(callable, context, callback, argc, data, - api_holder.value(), p->receiver, p->value)); + api_holder.value(), p->receiver(), p->value())); } BIND(&if_store_global_proxy); { ExitPoint direct_exit(this); - StoreGlobalIC_PropertyCellCase(holder, p->value, &direct_exit, miss); + StoreGlobalIC_PropertyCellCase(holder, p->value(), &direct_exit, miss); } } } @@ -1551,13 +1542,13 @@ void AccessorAssembler::HandleStoreToProxy(const StoreICParameters* p, to_name_failed(this, Label::kDeferred); if (support_elements == kSupportElements) { - TryToName(p->name, &if_index, &var_index, &if_unique_name, &var_unique, + TryToName(p->name(), &if_index, &var_index, &if_unique_name, &var_unique, &to_name_failed); BIND(&if_unique_name); - CallBuiltin(Builtins::kProxySetProperty, p->context, proxy, - var_unique.value(), p->value, p->receiver); - Return(p->value); + CallBuiltin(Builtins::kProxySetProperty, p->context(), proxy, + var_unique.value(), p->value(), p->receiver()); + Return(p->value()); // The index case is handled earlier by the runtime. BIND(&if_index); @@ -1566,12 +1557,12 @@ void AccessorAssembler::HandleStoreToProxy(const StoreICParameters* p, Goto(&to_name_failed); BIND(&to_name_failed); - TailCallRuntime(Runtime::kSetPropertyWithReceiver, p->context, proxy, - p->name, p->value, p->receiver); + TailCallRuntime(Runtime::kSetPropertyWithReceiver, p->context(), proxy, + p->name(), p->value(), p->receiver()); } else { - Node* name = CallBuiltin(Builtins::kToName, p->context, p->name); - TailCallBuiltin(Builtins::kProxySetProperty, p->context, proxy, name, - p->value, p->receiver); + Node* name = CallBuiltin(Builtins::kToName, p->context(), p->name()); + TailCallBuiltin(Builtins::kProxySetProperty, p->context(), proxy, name, + p->value(), p->receiver()); } } @@ -1979,7 +1970,7 @@ void AccessorAssembler::EmitElementLoad( { Comment("typed elements"); // Check if buffer has been detached. - Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset); + TNode<JSArrayBuffer> buffer = LoadJSArrayBufferViewBuffer(CAST(object)); GotoIf(IsDetachedBuffer(buffer), miss); // Bounds check. @@ -1988,7 +1979,8 @@ void AccessorAssembler::EmitElementLoad( if (access_mode == LoadAccessMode::kHas) { exit_point->Return(TrueConstant()); } else { - Node* backing_store = LoadJSTypedArrayBackingStore(CAST(object)); + TNode<RawPtrT> backing_store = + LoadJSTypedArrayBackingStore(CAST(object)); Label uint8_elements(this), int8_elements(this), uint16_elements(this), int16_elements(this), uint32_elements(this), int32_elements(this), @@ -2102,13 +2094,13 @@ void AccessorAssembler::NameDictionaryNegativeLookup(Node* object, } void AccessorAssembler::InvalidateValidityCellIfPrototype(Node* map, - Node* bitfield2) { + Node* bitfield3) { Label is_prototype(this), cont(this); - if (bitfield2 == nullptr) { - bitfield2 = LoadMapBitField2(map); + if (bitfield3 == nullptr) { + bitfield3 = LoadMapBitField3(map); } - Branch(IsSetWord32(bitfield2, Map::IsPrototypeMapBit::kMask), &is_prototype, + Branch(IsSetWord32(bitfield3, Map::IsPrototypeMapBit::kMask), &is_prototype, &cont); BIND(&is_prototype); @@ -2217,7 +2209,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(p->name(), descriptors, bitfield3, &if_descriptor_found, &var_name_index, notfound); BIND(&if_descriptor_found); @@ -2232,20 +2224,21 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, Label stub_cache(this); BIND(&try_stub_cache); // When there is no feedback vector don't use stub cache. - GotoIfNot(IsUndefined(p->vector), &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(p->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, p->name(), &found_handler, &var_handler, &stub_cache_miss); BIND(&found_handler); { - HandleLoadICHandlerCase(p, CAST(var_handler.value()), &stub_cache_miss, - &direct_exit); + LazyLoadICParameters lazy_p(p); + HandleLoadICHandlerCase(&lazy_p, CAST(var_handler.value()), + &stub_cache_miss, &direct_exit); } BIND(&stub_cache_miss); @@ -2253,8 +2246,8 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, // TODO(jkummerow): Check if the property exists on the prototype // 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); + TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context(), p->receiver(), + p->name(), p->slot(), p->vector()); } } @@ -2267,7 +2260,7 @@ 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), + NameDictionaryLookup<NameDictionary>(properties, CAST(p->name()), &dictionary_found, &var_name_index, &lookup_prototype_chain); BIND(&dictionary_found); @@ -2281,7 +2274,7 @@ 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); + p->context(), receiver, slow); IncrementCounter(isolate()->counters()->ic_keyed_load_generic_symbol(), 1); Return(value); } @@ -2290,14 +2283,14 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, { VARIABLE(var_holder_map, MachineRepresentation::kTagged); VARIABLE(var_holder_instance_type, MachineRepresentation::kWord32); - Label return_undefined(this); + Label return_undefined(this), is_private_symbol(this); Variable* merged_variables[] = {&var_holder_map, &var_holder_instance_type}; Label loop(this, arraysize(merged_variables), merged_variables); var_holder_map.Bind(receiver_map); var_holder_instance_type.Bind(instance_type); - // Private symbols must not be looked up on the prototype chain. - GotoIf(IsPrivateSymbol(p->name), &return_undefined); + GotoIf(IsPrivateSymbol(p->name()), &is_private_symbol); + Goto(&loop); BIND(&loop); { @@ -2312,9 +2305,9 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_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); + TryGetOwnProperty(p->context(), receiver, proto, proto_map, + proto_instance_type, p->name(), &return_value, + &var_value, &next_proto, &goto_slow); // This trampoline and the next are required to appease Turbofan's // variable merging. @@ -2328,6 +2321,16 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, Return(var_value.value()); } + BIND(&is_private_symbol); + { + CSA_ASSERT(this, IsPrivateSymbol(p->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); + } + BIND(&return_undefined); Return(UndefinedConstant()); } @@ -2338,11 +2341,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(p->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*/, p->name(), receiver, SmiConstant(OnNonExistent::kReturnUndefined)); } } @@ -2400,26 +2403,24 @@ void AccessorAssembler::TryProbeStubCacheTable( const int kMultiplier = sizeof(StubCache::Entry) >> Name::kHashShift; entry_offset = IntPtrMul(entry_offset, IntPtrConstant(kMultiplier)); - // Check that the key in the entry matches the name. Node* key_base = ExternalConstant( ExternalReference::Create(stub_cache->key_reference(table))); - Node* entry_key = Load(MachineType::Pointer(), key_base, entry_offset); - GotoIf(WordNotEqual(name, entry_key), if_miss); - - // Get the map entry from the cache. - DCHECK_EQ(kSystemPointerSize * 2, - stub_cache->map_reference(table).address() - - stub_cache->key_reference(table).address()); - Node* entry_map = - Load(MachineType::Pointer(), key_base, - IntPtrAdd(entry_offset, IntPtrConstant(kSystemPointerSize * 2))); - GotoIf(WordNotEqual(map, entry_map), if_miss); - - DCHECK_EQ(kSystemPointerSize, stub_cache->value_reference(table).address() - - stub_cache->key_reference(table).address()); + + // 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); + + // Check that the map in the entry matches. + Node* cached_map = Load( + MachineType::TaggedPointer(), key_base, + IntPtrAdd(entry_offset, IntPtrConstant(offsetof(StubCache::Entry, map)))); + GotoIf(WordNotEqual(map, cached_map), if_miss); + TNode<MaybeObject> handler = ReinterpretCast<MaybeObject>( Load(MachineType::AnyTagged(), key_base, - IntPtrAdd(entry_offset, IntPtrConstant(kSystemPointerSize)))); + IntPtrAdd(entry_offset, + IntPtrConstant(offsetof(StubCache::Entry, value))))); // We found the handler. *var_handler = handler; @@ -2462,7 +2463,7 @@ void AccessorAssembler::TryProbeStubCache(StubCache* stub_cache, Node* receiver, //////////////////// Entry points into private implementation (one per stub). -void AccessorAssembler::LoadIC_BytecodeHandler(const LoadICParameters* p, +void AccessorAssembler::LoadIC_BytecodeHandler(const LazyLoadICParameters* p, ExitPoint* exit_point) { // Must be kept in sync with LoadIC. @@ -2476,10 +2477,10 @@ void AccessorAssembler::LoadIC_BytecodeHandler(const LoadICParameters* p, Label stub_call(this, Label::kDeferred), miss(this, Label::kDeferred), no_feedback(this, Label::kDeferred); - Node* recv_map = LoadReceiverMap(p->receiver); + Node* recv_map = LoadReceiverMap(p->receiver()); GotoIf(IsDeprecatedMap(recv_map), &miss); - GotoIf(IsUndefined(p->vector), &no_feedback); + GotoIf(IsUndefined(p->vector()), &no_feedback); // Inlined fast path. { @@ -2489,7 +2490,7 @@ void AccessorAssembler::LoadIC_BytecodeHandler(const LoadICParameters* p, Label try_polymorphic(this), if_handler(this, &var_handler); TNode<MaybeObject> feedback = - TryMonomorphicCase(p->slot, p->vector, recv_map, &if_handler, + TryMonomorphicCase(p->slot(), p->vector(), recv_map, &if_handler, &var_handler, &try_polymorphic); BIND(&if_handler); @@ -2513,8 +2514,9 @@ void AccessorAssembler::LoadIC_BytecodeHandler(const LoadICParameters* p, Callable ic = Builtins::CallableFor(isolate(), Builtins::kLoadIC_Noninlined); Node* code_target = HeapConstant(ic.code()); - exit_point->ReturnCallStub(ic.descriptor(), code_target, p->context, - p->receiver, p->name, p->slot, p->vector); + exit_point->ReturnCallStub(ic.descriptor(), code_target, p->context(), + p->receiver(), p->name(), p->slot(), + p->vector()); } BIND(&no_feedback); @@ -2523,15 +2525,16 @@ void AccessorAssembler::LoadIC_BytecodeHandler(const LoadICParameters* p, // 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); + p->context(), p->receiver(), p->name(), p->slot(), p->vector()); } BIND(&miss); { Comment("LoadIC_BytecodeHandler_miss"); - exit_point->ReturnCallRuntime(Runtime::kLoadIC_Miss, p->context, - p->receiver, p->name, p->slot, p->vector); + exit_point->ReturnCallRuntime(Runtime::kLoadIC_Miss, p->context(), + p->receiver(), p->name(), p->slot(), + p->vector()); } } @@ -2544,15 +2547,19 @@ 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); + Node* receiver_map = LoadReceiverMap(p->receiver()); GotoIf(IsDeprecatedMap(receiver_map), &miss); // Check monomorphic case. TNode<MaybeObject> feedback = - TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, + TryMonomorphicCase(p->slot(), p->vector(), receiver_map, &if_handler, &var_handler, &try_polymorphic); BIND(&if_handler); - HandleLoadICHandlerCase(p, CAST(var_handler.value()), &miss, &direct_exit); + { + LazyLoadICParameters lazy_p(p); + HandleLoadICHandlerCase(&lazy_p, CAST(var_handler.value()), &miss, + &direct_exit); + } BIND(&try_polymorphic); TNode<HeapObject> strong_feedback = GetHeapObjectIfStrong(feedback, &miss); @@ -2571,8 +2578,9 @@ void AccessorAssembler::LoadIC(const LoadICParameters* p) { } BIND(&miss); - direct_exit.ReturnCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver, - p->name, p->slot, p->vector); + direct_exit.ReturnCallRuntime(Runtime::kLoadIC_Miss, p->context(), + p->receiver(), p->name(), p->slot(), + p->vector()); } void AccessorAssembler::LoadIC_Noninlined(const LoadICParameters* p, @@ -2595,7 +2603,7 @@ void AccessorAssembler::LoadIC_Noninlined(const LoadICParameters* p, GotoIfNot(WordEqual(feedback, LoadRoot(RootIndex::kmegamorphic_symbol)), &try_uninitialized); - TryProbeStubCache(isolate()->load_stub_cache(), p->receiver, p->name, + TryProbeStubCache(isolate()->load_stub_cache(), p->receiver(), p->name(), if_handler, var_handler, miss); } @@ -2606,24 +2614,24 @@ void AccessorAssembler::LoadIC_Noninlined(const LoadICParameters* p, miss); exit_point->ReturnCallStub( Builtins::CallableFor(isolate(), Builtins::kLoadIC_Uninitialized), - p->context, p->receiver, p->name, p->slot, p->vector); + 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); - Node* receiver = p->receiver; + 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); + GotoIf(IsUndefined(p->vector()), &check_function_prototype); // Optimistically write the state transition to the vector. - StoreFeedbackVectorSlot(p->vector, p->slot, + StoreFeedbackVectorSlot(p->vector(), p->slot(), LoadRoot(RootIndex::kpremonomorphic_symbol), SKIP_WRITE_BARRIER, 0, SMI_PARAMETERS); - StoreWeakReferenceInFeedbackVector(p->vector, p->slot, receiver_map, + StoreWeakReferenceInFeedbackVector(p->vector(), p->slot(), receiver_map, kTaggedSize, SMI_PARAMETERS); Goto(&check_function_prototype); @@ -2634,7 +2642,7 @@ void AccessorAssembler::LoadIC_Uninitialized(const LoadICParameters* p) { Label not_function_prototype(this, Label::kDeferred); GotoIfNot(InstanceTypeEqual(instance_type, JS_FUNCTION_TYPE), ¬_function_prototype); - GotoIfNot(IsPrototypeString(p->name), ¬_function_prototype); + GotoIfNot(IsPrototypeString(p->name()), ¬_function_prototype); GotoIfPrototypeRequiresRuntimeLookup(CAST(receiver), CAST(receiver_map), ¬_function_prototype); @@ -2648,16 +2656,16 @@ void AccessorAssembler::LoadIC_Uninitialized(const LoadICParameters* p) { BIND(&miss); { Label call_runtime(this, Label::kDeferred); - GotoIf(IsUndefined(p->vector), &call_runtime); + GotoIf(IsUndefined(p->vector()), &call_runtime); // Undo the optimistic state transition. - StoreFeedbackVectorSlot(p->vector, p->slot, + 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); + TailCallRuntime(Runtime::kLoadIC_Miss, p->context(), p->receiver(), + p->name(), p->slot(), p->vector()); } } @@ -2750,8 +2758,8 @@ void AccessorAssembler::LoadGlobalIC_TryHandlerCase( CAST(LoadContextElement(native_context, Context::GLOBAL_PROXY_INDEX)); Node* holder = LoadContextElement(native_context, Context::EXTENSION_INDEX); - LoadICParameters p(context, receiver, lazy_name(), - ParameterToTagged(slot, slot_mode), vector, holder); + LazyLoadICParameters p([=] { return context; }, receiver, lazy_name, + ParameterToTagged(slot, slot_mode), vector, holder); HandleLoadICHandlerCase(&p, handler, miss, exit_point, ICMode::kGlobalIC, on_nonexistent); @@ -2767,20 +2775,22 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p, try_polymorphic_name(this, Label::kDeferred), miss(this, Label::kDeferred), generic(this, Label::kDeferred); - Node* receiver_map = LoadReceiverMap(p->receiver); + Node* receiver_map = LoadReceiverMap(p->receiver()); GotoIf(IsDeprecatedMap(receiver_map), &miss); - GotoIf(IsUndefined(p->vector), &generic); + GotoIf(IsUndefined(p->vector()), &generic); // Check monomorphic case. TNode<MaybeObject> feedback = - TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, + TryMonomorphicCase(p->slot(), p->vector(), receiver_map, &if_handler, &var_handler, &try_polymorphic); BIND(&if_handler); { - HandleLoadICHandlerCase( - p, CAST(var_handler.value()), &miss, &direct_exit, ICMode::kNonGlobalIC, - OnNonExistent::kReturnUndefined, kSupportElements, access_mode); + LazyLoadICParameters lazy_p(p); + HandleLoadICHandlerCase(&lazy_p, CAST(var_handler.value()), &miss, + &direct_exit, ICMode::kNonGlobalIC, + OnNonExistent::kReturnUndefined, kSupportElements, + access_mode); } BIND(&try_polymorphic); @@ -2807,14 +2817,15 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p, TailCallBuiltin(access_mode == LoadAccessMode::kLoad ? Builtins::kKeyedLoadIC_Megamorphic : Builtins::kKeyedHasIC_Megamorphic, - p->context, p->receiver, p->name, p->slot, p->vector); + p->context(), p->receiver(), p->name(), p->slot(), + p->vector()); } BIND(&try_polymorphic_name); { // We might have a name in feedback, and a weak fixed array in the next // slot. - Node* name = p->name; + Node* name = p->name(); Comment("KeyedLoadIC_try_polymorphic_name"); VARIABLE(var_name, MachineRepresentation::kTagged, name); VARIABLE(var_index, MachineType::PointerRepresentation()); @@ -2857,36 +2868,37 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p, TailCallBuiltin(access_mode == LoadAccessMode::kLoad ? Builtins::kKeyedLoadIC_PolymorphicName : Builtins::kKeyedHasIC_PolymorphicName, - p->context, p->receiver, name, p->slot, p->vector); + p->context(), p->receiver(), name, p->slot(), + p->vector()); } } BIND(&miss); { Comment("KeyedLoadIC_miss"); - TailCallRuntime(access_mode == LoadAccessMode::kLoad - ? Runtime::kKeyedLoadIC_Miss - : Runtime::kKeyedHasIC_Miss, - p->context, p->receiver, p->name, p->slot, p->vector); + TailCallRuntime( + access_mode == LoadAccessMode::kLoad ? Runtime::kKeyedLoadIC_Miss + : Runtime::kKeyedHasIC_Miss, + p->context(), p->receiver(), p->name(), p->slot(), p->vector()); } } void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { VARIABLE(var_index, MachineType::PointerRepresentation()); - VARIABLE(var_unique, MachineRepresentation::kTagged, p->name); + VARIABLE(var_unique, MachineRepresentation::kTagged, p->name()); Label if_index(this), if_unique_name(this), if_notunique(this), if_other(this, Label::kDeferred), if_runtime(this, Label::kDeferred); - Node* receiver = p->receiver; + Node* receiver = p->receiver(); GotoIf(TaggedIsSmi(receiver), &if_runtime); GotoIf(IsNullOrUndefined(receiver), &if_runtime); - TryToName(p->name, &if_index, &var_index, &if_unique_name, &var_unique, + TryToName(p->name(), &if_index, &var_index, &if_unique_name, &var_unique, &if_other, &if_notunique); BIND(&if_other); { - Node* name = CallBuiltin(Builtins::kToName, p->context, p->name); + Node* name = CallBuiltin(Builtins::kToName, p->context(), p->name()); var_unique.Bind(name); TryToName(name, &if_index, &var_index, &if_unique_name, &var_unique, &if_runtime, &if_notunique); @@ -2902,8 +2914,7 @@ void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { BIND(&if_unique_name); { - LoadICParameters pp = *p; - pp.name = var_unique.value(); + LoadICParameters pp(p, var_unique.value()); Node* receiver_map = LoadMap(receiver); Node* instance_type = LoadMapInstanceType(receiver_map); GenericPropertyLoad(receiver, receiver_map, instance_type, &pp, @@ -2929,8 +2940,7 @@ void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { // successfully internalizing the incoming string. Past experiments // 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; - pp.name = var_unique.value(); + LoadICParameters pp(p, var_unique.value()); Node* receiver_map = LoadMap(receiver); Node* instance_type = LoadMapInstanceType(receiver_map); GenericPropertyLoad(receiver, receiver_map, instance_type, &pp, @@ -2946,7 +2956,7 @@ void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { Comment("KeyedLoadGeneric_slow"); IncrementCounter(isolate()->counters()->ic_keyed_load_generic_slow(), 1); // TODO(jkummerow): Should we use the GetProperty TF stub instead? - TailCallRuntime(Runtime::kGetProperty, p->context, p->receiver, + TailCallRuntime(Runtime::kGetProperty, p->context(), p->receiver(), var_unique.value()); } } @@ -2956,12 +2966,12 @@ void AccessorAssembler::KeyedLoadICPolymorphicName(const LoadICParameters* p, TVARIABLE(MaybeObject, var_handler); Label if_handler(this, &var_handler), miss(this, Label::kDeferred); - Node* receiver = p->receiver; + Node* receiver = p->receiver(); Node* receiver_map = LoadReceiverMap(receiver); - Node* name = p->name; - Node* vector = p->vector; - Node* slot = p->slot; - Node* context = p->context; + Node* name = p->name(); + Node* vector = p->vector(); + Node* slot = p->slot(); + TNode<Context> context = p->context(); // When we get here, we know that the {name} matches the recorded // feedback name in the {vector} and can safely be used for the @@ -2980,9 +2990,11 @@ void AccessorAssembler::KeyedLoadICPolymorphicName(const LoadICParameters* p, BIND(&if_handler); { ExitPoint direct_exit(this); - HandleLoadICHandlerCase( - p, CAST(var_handler.value()), &miss, &direct_exit, ICMode::kNonGlobalIC, - OnNonExistent::kReturnUndefined, kOnlyProperties, access_mode); + LazyLoadICParameters lazy_p(p); + HandleLoadICHandlerCase(&lazy_p, CAST(var_handler.value()), &miss, + &direct_exit, ICMode::kNonGlobalIC, + OnNonExistent::kReturnUndefined, kOnlyProperties, + access_mode); } BIND(&miss); @@ -3006,14 +3018,14 @@ void AccessorAssembler::StoreIC(const StoreICParameters* p) { try_uninitialized(this, Label::kDeferred), miss(this, Label::kDeferred), no_feedback(this, Label::kDeferred); - Node* receiver_map = LoadReceiverMap(p->receiver); + Node* receiver_map = LoadReceiverMap(p->receiver()); GotoIf(IsDeprecatedMap(receiver_map), &miss); - GotoIf(IsUndefined(p->vector), &no_feedback); + GotoIf(IsUndefined(p->vector()), &no_feedback); // Check monomorphic case. TNode<MaybeObject> feedback = - TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, + TryMonomorphicCase(p->slot(), p->vector(), receiver_map, &if_handler, &var_handler, &try_polymorphic); BIND(&if_handler); { @@ -3039,7 +3051,7 @@ void AccessorAssembler::StoreIC(const StoreICParameters* p) { WordEqual(strong_feedback, LoadRoot(RootIndex::kmegamorphic_symbol)), &try_uninitialized); - TryProbeStubCache(isolate()->store_stub_cache(), p->receiver, p->name, + TryProbeStubCache(isolate()->store_stub_cache(), p->receiver(), p->name(), &if_handler, &var_handler, &miss); } BIND(&try_uninitialized); @@ -3052,21 +3064,22 @@ void AccessorAssembler::StoreIC(const StoreICParameters* p) { BIND(&no_feedback); { - TailCallBuiltin(Builtins::kStoreIC_Uninitialized, p->context, p->receiver, - p->name, p->value, p->slot, p->vector); + TailCallBuiltin(Builtins::kStoreIC_Uninitialized, p->context(), + p->receiver(), p->name(), p->value(), p->slot(), + p->vector()); } BIND(&miss); { - TailCallRuntime(Runtime::kStoreIC_Miss, p->context, p->value, p->slot, - p->vector, p->receiver, p->name); + TailCallRuntime(Runtime::kStoreIC_Miss, p->context(), p->value(), p->slot(), + p->vector(), p->receiver(), p->name()); } } void AccessorAssembler::StoreGlobalIC(const StoreICParameters* pp) { Label if_lexical_var(this), if_heapobject(this); TNode<MaybeObject> maybe_weak_ref = - LoadFeedbackVectorSlot(pp->vector, pp->slot, 0, SMI_PARAMETERS); + LoadFeedbackVectorSlot(pp->vector(), pp->slot(), 0, SMI_PARAMETERS); Branch(TaggedIsSmi(maybe_weak_ref), &if_lexical_var, &if_heapobject); BIND(&if_heapobject); @@ -3081,31 +3094,32 @@ void AccessorAssembler::StoreGlobalIC(const StoreICParameters* pp) { CAST(GetHeapObjectAssumeWeak(maybe_weak_ref, &try_handler)); ExitPoint direct_exit(this); - StoreGlobalIC_PropertyCellCase(property_cell, pp->value, &direct_exit, + StoreGlobalIC_PropertyCellCase(property_cell, pp->value(), &direct_exit, &miss); BIND(&try_handler); { Comment("StoreGlobalIC_try_handler"); TNode<MaybeObject> handler = LoadFeedbackVectorSlot( - pp->vector, pp->slot, kTaggedSize, SMI_PARAMETERS); + pp->vector(), pp->slot(), kTaggedSize, SMI_PARAMETERS); GotoIf(WordEqual(handler, LoadRoot(RootIndex::kuninitialized_symbol)), &miss); - StoreICParameters p = *pp; - DCHECK_NULL(p.receiver); - Node* native_context = LoadNativeContext(p.context); - p.receiver = - LoadContextElement(native_context, Context::GLOBAL_PROXY_INDEX); + DCHECK_NULL(pp->receiver()); + Node* native_context = LoadNativeContext(pp->context()); + StoreICParameters p( + pp->context(), + LoadContextElement(native_context, Context::GLOBAL_PROXY_INDEX), + pp->name(), pp->value(), pp->slot(), pp->vector()); HandleStoreICHandlerCase(&p, handler, &miss, ICMode::kGlobalIC); } BIND(&miss); { - TailCallRuntime(Runtime::kStoreGlobalIC_Miss, pp->context, pp->value, - pp->slot, pp->vector, pp->name); + TailCallRuntime(Runtime::kStoreGlobalIC_Miss, pp->context(), pp->value(), + pp->slot(), pp->vector(), pp->name()); } } @@ -3118,9 +3132,9 @@ void AccessorAssembler::StoreGlobalIC(const StoreICParameters* pp) { TNode<IntPtrT> slot_index = Signed(DecodeWord<FeedbackNexus::SlotIndexBits>(lexical_handler)); TNode<Context> script_context = - LoadScriptContext(CAST(pp->context), context_index); - StoreContextElement(script_context, slot_index, pp->value); - Return(pp->value); + LoadScriptContext(pp->context(), context_index); + StoreContextElement(script_context, slot_index, pp->value()); + Return(pp->value()); } } @@ -3199,14 +3213,14 @@ void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p) { no_feedback(this, Label::kDeferred), try_polymorphic_name(this, Label::kDeferred); - Node* receiver_map = LoadReceiverMap(p->receiver); + Node* receiver_map = LoadReceiverMap(p->receiver()); GotoIf(IsDeprecatedMap(receiver_map), &miss); - GotoIf(IsUndefined(p->vector), &no_feedback); + GotoIf(IsUndefined(p->vector()), &no_feedback); // Check monomorphic case. TNode<MaybeObject> feedback = - TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, + TryMonomorphicCase(p->slot(), p->vector(), receiver_map, &if_handler, &var_handler, &try_polymorphic); BIND(&if_handler); { @@ -3237,19 +3251,19 @@ void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p) { BIND(&no_feedback); { - TailCallBuiltin(Builtins::kKeyedStoreIC_Megamorphic, p->context, - p->receiver, p->name, p->value, p->slot); + TailCallBuiltin(Builtins::kKeyedStoreIC_Megamorphic, p->context(), + p->receiver(), p->name(), p->value(), p->slot()); } BIND(&try_polymorphic_name); { // 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(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, kTaggedSize, SMI_PARAMETERS); + p->vector(), p->slot(), kTaggedSize, SMI_PARAMETERS); TNode<WeakFixedArray> array = CAST(feedback_element); HandlePolymorphicCase(receiver_map, array, &if_handler, &var_handler, &miss); @@ -3258,8 +3272,8 @@ void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p) { BIND(&miss); { Comment("KeyedStoreIC_miss"); - TailCallRuntime(Runtime::kKeyedStoreIC_Miss, p->context, p->value, p->slot, - p->vector, p->receiver, p->name); + TailCallRuntime(Runtime::kKeyedStoreIC_Miss, p->context(), p->value(), + p->slot(), p->vector(), p->receiver(), p->name()); } } @@ -3272,13 +3286,13 @@ void AccessorAssembler::StoreInArrayLiteralIC(const StoreICParameters* p) { try_polymorphic(this, Label::kDeferred), try_megamorphic(this, Label::kDeferred); - Node* array_map = LoadReceiverMap(p->receiver); + Node* array_map = LoadReceiverMap(p->receiver()); GotoIf(IsDeprecatedMap(array_map), &miss); - GotoIf(IsUndefined(p->vector), &miss); + GotoIf(IsUndefined(p->vector()), &miss); TNode<MaybeObject> feedback = - TryMonomorphicCase(p->slot, p->vector, array_map, &if_handler, + TryMonomorphicCase(p->slot(), p->vector(), array_map, &if_handler, &var_handler, &try_polymorphic); BIND(&if_handler); @@ -3289,8 +3303,9 @@ void AccessorAssembler::StoreInArrayLiteralIC(const StoreICParameters* p) { TNode<HeapObject> handler = CAST(var_handler.value()); Label if_transitioning_element_store(this); GotoIfNot(IsCode(handler), &if_transitioning_element_store); - TailCallStub(StoreWithVectorDescriptor{}, CAST(handler), CAST(p->context), - p->receiver, p->name, p->value, p->slot, p->vector); + TailCallStub(StoreWithVectorDescriptor{}, CAST(handler), p->context(), + p->receiver(), p->name(), p->value(), p->slot(), + p->vector()); BIND(&if_transitioning_element_store); { @@ -3301,8 +3316,9 @@ void AccessorAssembler::StoreInArrayLiteralIC(const StoreICParameters* p) { GotoIf(IsDeprecatedMap(transition_map), &miss); Node* code = LoadObjectField(handler, StoreHandler::kSmiHandlerOffset); CSA_ASSERT(this, IsCode(code)); - TailCallStub(StoreTransitionDescriptor{}, 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()); } } @@ -3327,16 +3343,17 @@ void AccessorAssembler::StoreInArrayLiteralIC(const StoreICParameters* p) { GotoIfNot( WordEqual(strong_feedback, LoadRoot(RootIndex::kmegamorphic_symbol)), &miss); - TailCallRuntime(Runtime::kStoreInArrayLiteralIC_Slow, p->context, - p->value, p->receiver, p->name); + TailCallRuntime(Runtime::kStoreInArrayLiteralIC_Slow, p->context(), + p->value(), p->receiver(), p->name()); } } BIND(&miss); { Comment("StoreInArrayLiteralIC_miss"); - TailCallRuntime(Runtime::kStoreInArrayLiteralIC_Miss, p->context, p->value, - p->slot, p->vector, p->receiver, p->name); + TailCallRuntime(Runtime::kStoreInArrayLiteralIC_Miss, p->context(), + p->value(), p->slot(), p->vector(), p->receiver(), + p->name()); } } @@ -3349,7 +3366,7 @@ void AccessorAssembler::GenerateLoadIC() { Node* name = Parameter(Descriptor::kName); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); LoadICParameters p(context, receiver, name, slot, vector); LoadIC(&p); @@ -3362,7 +3379,7 @@ void AccessorAssembler::GenerateLoadIC_Megamorphic() { Node* name = Parameter(Descriptor::kName); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); ExitPoint direct_exit(this); TVARIABLE(MaybeObject, var_handler); @@ -3372,7 +3389,8 @@ void AccessorAssembler::GenerateLoadIC_Megamorphic() { &var_handler, &miss); BIND(&if_handler); - LoadICParameters p(context, receiver, name, slot, vector); + LazyLoadICParameters p([=] { return context; }, receiver, + [=] { return CAST(name); }, slot, vector); HandleLoadICHandlerCase(&p, CAST(var_handler.value()), &miss, &direct_exit); BIND(&miss); @@ -3387,7 +3405,7 @@ void AccessorAssembler::GenerateLoadIC_Noninlined() { Node* name = Parameter(Descriptor::kName); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); ExitPoint direct_exit(this); TVARIABLE(MaybeObject, var_handler); @@ -3403,7 +3421,11 @@ void AccessorAssembler::GenerateLoadIC_Noninlined() { &miss, &direct_exit); BIND(&if_handler); - HandleLoadICHandlerCase(&p, CAST(var_handler.value()), &miss, &direct_exit); + { + LazyLoadICParameters lazy_p(&p); + HandleLoadICHandlerCase(&lazy_p, CAST(var_handler.value()), &miss, + &direct_exit); + } BIND(&miss); direct_exit.ReturnCallRuntime(Runtime::kLoadIC_Miss, context, receiver, name, @@ -3417,7 +3439,7 @@ void AccessorAssembler::GenerateLoadIC_Uninitialized() { Node* name = Parameter(Descriptor::kName); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); LoadICParameters p(context, receiver, name, slot, vector); LoadIC_Uninitialized(&p); @@ -3429,7 +3451,7 @@ void AccessorAssembler::GenerateLoadICTrampoline() { Node* receiver = Parameter(Descriptor::kReceiver); Node* name = Parameter(Descriptor::kName); Node* slot = Parameter(Descriptor::kSlot); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Node* vector = LoadFeedbackVectorForStub(); TailCallBuiltin(Builtins::kLoadIC, context, receiver, name, slot, vector); @@ -3441,7 +3463,7 @@ void AccessorAssembler::GenerateLoadICTrampoline_Megamorphic() { Node* receiver = Parameter(Descriptor::kReceiver); Node* name = Parameter(Descriptor::kName); Node* slot = Parameter(Descriptor::kSlot); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Node* vector = LoadFeedbackVectorForStub(); TailCallBuiltin(Builtins::kLoadIC_Megamorphic, context, receiver, name, slot, @@ -3454,13 +3476,13 @@ void AccessorAssembler::GenerateLoadGlobalIC(TypeofMode typeof_mode) { Node* name = Parameter(Descriptor::kName); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); ExitPoint direct_exit(this); LoadGlobalIC( vector, slot, // lazy_context - [=] { return CAST(context); }, + [=] { return context; }, // lazy_name [=] { return CAST(name); }, typeof_mode, &direct_exit); } @@ -3470,7 +3492,7 @@ void AccessorAssembler::GenerateLoadGlobalICTrampoline(TypeofMode typeof_mode) { Node* name = Parameter(Descriptor::kName); Node* slot = Parameter(Descriptor::kSlot); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Node* vector = LoadFeedbackVectorForStub(); Callable callable = @@ -3485,7 +3507,7 @@ void AccessorAssembler::GenerateKeyedLoadIC() { Node* name = Parameter(Descriptor::kName); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); LoadICParameters p(context, receiver, name, slot, vector); KeyedLoadIC(&p, LoadAccessMode::kLoad); @@ -3498,7 +3520,7 @@ void AccessorAssembler::GenerateKeyedLoadIC_Megamorphic() { Node* name = Parameter(Descriptor::kName); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); LoadICParameters p(context, receiver, name, slot, vector); KeyedLoadICGeneric(&p); @@ -3510,7 +3532,7 @@ void AccessorAssembler::GenerateKeyedLoadICTrampoline() { Node* receiver = Parameter(Descriptor::kReceiver); Node* name = Parameter(Descriptor::kName); Node* slot = Parameter(Descriptor::kSlot); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Node* vector = LoadFeedbackVectorForStub(); TailCallBuiltin(Builtins::kKeyedLoadIC, context, receiver, name, slot, @@ -3523,7 +3545,7 @@ void AccessorAssembler::GenerateKeyedLoadICTrampoline_Megamorphic() { Node* receiver = Parameter(Descriptor::kReceiver); Node* name = Parameter(Descriptor::kName); Node* slot = Parameter(Descriptor::kSlot); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Node* vector = LoadFeedbackVectorForStub(); TailCallBuiltin(Builtins::kKeyedLoadIC_Megamorphic, context, receiver, name, @@ -3537,7 +3559,7 @@ void AccessorAssembler::GenerateKeyedLoadIC_PolymorphicName() { Node* name = Parameter(Descriptor::kName); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); LoadICParameters p(context, receiver, name, slot, vector); KeyedLoadICPolymorphicName(&p, LoadAccessMode::kLoad); @@ -3550,7 +3572,7 @@ void AccessorAssembler::GenerateStoreGlobalIC() { Node* value = Parameter(Descriptor::kValue); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); StoreICParameters p(context, nullptr, name, value, slot, vector); StoreGlobalIC(&p); @@ -3562,7 +3584,7 @@ void AccessorAssembler::GenerateStoreGlobalICTrampoline() { Node* name = Parameter(Descriptor::kName); Node* value = Parameter(Descriptor::kValue); Node* slot = Parameter(Descriptor::kSlot); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Node* vector = LoadFeedbackVectorForStub(); TailCallBuiltin(Builtins::kStoreGlobalIC, context, name, value, slot, vector); @@ -3576,7 +3598,7 @@ void AccessorAssembler::GenerateStoreIC() { Node* value = Parameter(Descriptor::kValue); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); StoreICParameters p(context, receiver, name, value, slot, vector); StoreIC(&p); @@ -3589,7 +3611,7 @@ void AccessorAssembler::GenerateStoreICTrampoline() { Node* name = Parameter(Descriptor::kName); Node* value = Parameter(Descriptor::kValue); Node* slot = Parameter(Descriptor::kSlot); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Node* vector = LoadFeedbackVectorForStub(); TailCallBuiltin(Builtins::kStoreIC, context, receiver, name, value, slot, @@ -3604,7 +3626,7 @@ void AccessorAssembler::GenerateKeyedStoreIC() { Node* value = Parameter(Descriptor::kValue); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); StoreICParameters p(context, receiver, name, value, slot, vector); KeyedStoreIC(&p); @@ -3617,7 +3639,7 @@ void AccessorAssembler::GenerateKeyedStoreICTrampoline() { Node* name = Parameter(Descriptor::kName); Node* value = Parameter(Descriptor::kValue); Node* slot = Parameter(Descriptor::kSlot); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Node* vector = LoadFeedbackVectorForStub(); TailCallBuiltin(Builtins::kKeyedStoreIC, context, receiver, name, value, slot, @@ -3632,7 +3654,7 @@ void AccessorAssembler::GenerateStoreInArrayLiteralIC() { Node* value = Parameter(Descriptor::kValue); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); StoreICParameters p(context, array, index, value, slot, vector); StoreInArrayLiteralIC(&p); @@ -3640,7 +3662,7 @@ void AccessorAssembler::GenerateStoreInArrayLiteralIC() { void AccessorAssembler::GenerateCloneObjectIC_Slow() { using Descriptor = CloneObjectWithVectorDescriptor; - TNode<HeapObject> source = CAST(Parameter(Descriptor::kSource)); + TNode<Object> source = CAST(Parameter(Descriptor::kSource)); TNode<Smi> flags = CAST(Parameter(Descriptor::kFlags)); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -3655,7 +3677,7 @@ void AccessorAssembler::GenerateCloneObjectIC_Slow() { LoadObjectField(object_fn, JSFunction::kPrototypeOrInitialMapOffset)); CSA_ASSERT(this, IsMap(initial_map)); - TNode<JSObject> result = CAST(AllocateJSObjectFromMap(initial_map)); + TNode<JSObject> result = AllocateJSObjectFromMap(initial_map); { Label did_set_proto_if_needed(this); @@ -3672,28 +3694,16 @@ void AccessorAssembler::GenerateCloneObjectIC_Slow() { } ReturnIf(IsNullOrUndefined(source), result); + source = ToObject_Inline(context, source); - CSA_ASSERT(this, IsJSReceiver(source)); - - Label call_runtime(this, Label::kDeferred); - Label done(this); - - TNode<Map> map = LoadMap(source); - TNode<Int32T> type = LoadMapInstanceType(map); - { - Label cont(this); - GotoIf(IsJSObjectInstanceType(type), &cont); - GotoIf(InstanceTypeEqual(type, JS_PROXY_TYPE), &call_runtime); - GotoIfNot(IsStringInstanceType(type), &done); - Branch(SmiEqual(LoadStringLengthAsSmi(CAST(source)), SmiConstant(0)), &done, - &call_runtime); - BIND(&cont); - } + Label call_runtime(this, Label::kDeferred), done(this); + TNode<Map> source_map = LoadMap(CAST(source)); + GotoIfNot(IsJSObjectMap(source_map), &call_runtime); GotoIfNot(IsEmptyFixedArray(LoadElements(CAST(source))), &call_runtime); ForEachEnumerableOwnProperty( - context, map, CAST(source), kPropertyAdditionOrder, + context, source_map, CAST(source), kPropertyAdditionOrder, [=](TNode<Name> key, TNode<Object> value) { SetPropertyInLiteral(context, result, key, value); }, @@ -3710,17 +3720,17 @@ void AccessorAssembler::GenerateCloneObjectIC_Slow() { void AccessorAssembler::GenerateCloneObjectIC() { using Descriptor = CloneObjectWithVectorDescriptor; - TNode<HeapObject> source = CAST(Parameter(Descriptor::kSource)); - Node* flags = Parameter(Descriptor::kFlags); - Node* slot = Parameter(Descriptor::kSlot); - Node* vector = Parameter(Descriptor::kVector); - Node* context = Parameter(Descriptor::kContext); + TNode<Object> source = CAST(Parameter(Descriptor::kSource)); + TNode<Smi> flags = CAST(Parameter(Descriptor::kFlags)); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); + TNode<HeapObject> vector = CAST(Parameter(Descriptor::kVector)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); TVARIABLE(MaybeObject, var_handler); - Label if_handler(this, &var_handler); - Label miss(this, Label::kDeferred), try_polymorphic(this, Label::kDeferred), + Label if_handler(this, &var_handler), miss(this, Label::kDeferred), + try_polymorphic(this, Label::kDeferred), try_megamorphic(this, Label::kDeferred), slow(this, Label::kDeferred); - TNode<Map> source_map = LoadMap(UncheckedCast<HeapObject>(source)); + TNode<Map> source_map = LoadReceiverMap(source); GotoIf(IsDeprecatedMap(source_map), &miss); GotoIf(IsUndefined(vector), &slow); @@ -3735,11 +3745,12 @@ void AccessorAssembler::GenerateCloneObjectIC() { // Handlers for the CloneObjectIC stub are weak references to the Map of // a result object. TNode<Map> result_map = CAST(var_handler.value()); - TVARIABLE(Object, var_properties, EmptyFixedArrayConstant()); - TVARIABLE(FixedArrayBase, var_elements, EmptyFixedArrayConstant()); + TVARIABLE(HeapObject, var_properties, EmptyFixedArrayConstant()); + TVARIABLE(FixedArray, var_elements, EmptyFixedArrayConstant()); Label allocate_object(this); GotoIf(IsNullOrUndefined(source), &allocate_object); + CSA_SLOW_ASSERT(this, IsJSObjectMap(source_map)); CSA_SLOW_ASSERT(this, IsJSObjectMap(result_map)); // The IC fast case should only be taken if the result map a compatible @@ -3753,7 +3764,7 @@ void AccessorAssembler::GenerateCloneObjectIC() { // either an Smi, or a PropertyArray. // FIXME: Make a CSA macro for this TNode<Object> source_properties = - LoadObjectField(source, JSObject::kPropertiesOrHashOffset); + LoadObjectField(CAST(source), JSObject::kPropertiesOrHashOffset); { GotoIf(TaggedIsSmi(source_properties), &allocate_object); GotoIf(IsEmptyFixedArray(source_properties), &allocate_object); @@ -3779,8 +3790,6 @@ void AccessorAssembler::GenerateCloneObjectIC() { ReturnIf(IsNullOrUndefined(source), object); // Lastly, clone any in-object properties. - // Determine the inobject property capacity of both objects, and copy the - // smaller number into the resulting object. TNode<IntPtrT> source_start = LoadMapInobjectPropertiesStartInWords(source_map); TNode<IntPtrT> source_size = LoadMapInstanceSizeInWords(source_map); @@ -3789,35 +3798,49 @@ void AccessorAssembler::GenerateCloneObjectIC() { TNode<IntPtrT> field_offset_difference = TimesTaggedSize(IntPtrSub(result_start, source_start)); - // If MutableHeapNumbers may be present in-object, allocations may occur - // within this loop, thus the write barrier is required. - // - // TODO(caitp): skip the write barrier until the first MutableHeapNumber - // field is found - const bool may_use_mutable_heap_numbers = !FLAG_unbox_double_fields; - + // Just copy the fields as raw data (pretending that there are no + // MutableHeapNumbers). This doesn't need write barriers. BuildFastLoop( source_start, source_size, [=](Node* field_index) { TNode<IntPtrT> field_offset = TimesTaggedSize(UncheckedCast<IntPtrT>(field_index)); - - if (may_use_mutable_heap_numbers) { - TNode<Object> field = LoadObjectField(source, field_offset); - field = CloneIfMutablePrimitive(field); - TNode<IntPtrT> result_offset = - IntPtrAdd(field_offset, field_offset_difference); - StoreObjectField(object, result_offset, field); - } else { - // Copy fields as raw data. - TNode<IntPtrT> field = - LoadObjectField<IntPtrT>(source, field_offset); - TNode<IntPtrT> result_offset = - IntPtrAdd(field_offset, field_offset_difference); - StoreObjectFieldNoWriteBarrier(object, result_offset, field); - } + TNode<TaggedT> field = + LoadObjectField<TaggedT>(CAST(source), field_offset); + TNode<IntPtrT> result_offset = + IntPtrAdd(field_offset, field_offset_difference); + StoreObjectFieldNoWriteBarrier(object, result_offset, field); }, 1, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); + + // If MutableHeapNumbers 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. + if (!FLAG_unbox_double_fields) { + BuildFastLoop( + source_start, source_size, + [=](Node* field_index) { + TNode<IntPtrT> result_offset = + IntPtrAdd(TimesTaggedSize(UncheckedCast<IntPtrT>(field_index)), + field_offset_difference); + 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); + BIND(&if_mutableheapnumber); + { + TNode<Object> value = AllocateMutableHeapNumberWithValue( + LoadHeapNumberValue(UncheckedCast<HeapNumber>(field))); + StoreObjectField(object, result_offset, value); + Goto(&if_done); + } + BIND(&if_done); + }, + 1, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); + } + Return(object); } @@ -3869,7 +3892,7 @@ void AccessorAssembler::GenerateKeyedHasIC() { Node* name = Parameter(Descriptor::kName); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); LoadICParameters p(context, receiver, name, slot, vector); KeyedLoadIC(&p, LoadAccessMode::kHas); @@ -3880,7 +3903,7 @@ void AccessorAssembler::GenerateKeyedHasIC_Megamorphic() { Node* receiver = Parameter(Descriptor::kReceiver); Node* name = Parameter(Descriptor::kName); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); // TODO(magardn): implement HasProperty handling in KeyedLoadICGeneric Return(HasProperty(context, receiver, name, HasPropertyLookupMode::kHasProperty)); @@ -3893,7 +3916,7 @@ void AccessorAssembler::GenerateKeyedHasIC_PolymorphicName() { Node* name = Parameter(Descriptor::kName); Node* slot = Parameter(Descriptor::kSlot); Node* vector = Parameter(Descriptor::kVector); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); LoadICParameters p(context, receiver, name, slot, vector); KeyedLoadICPolymorphicName(&p, LoadAccessMode::kHas); |