| Index: src/code-stub-assembler.cc
|
| diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
|
| index 432613d929fae795fe962ae38ade473cb59d0593..be44c13819310b8fbc01ffc15f36f64e771c2789 100644
|
| --- a/src/code-stub-assembler.cc
|
| +++ b/src/code-stub-assembler.cc
|
| @@ -5704,6 +5704,125 @@ void CodeStubAssembler::KeyedLoadICGeneric(const LoadICParameters* p) {
|
| }
|
| }
|
|
|
| +void CodeStubAssembler::HandleStoreFieldAndReturn(
|
| + Node* handler_word, Node* holder, Representation representation,
|
| + Node* value, bool transition_to_field, Label* miss) {
|
| + Node* prepared_value = PrepareValueForWrite(value, representation, miss);
|
| +
|
| + Node* offset = DecodeWord<StoreHandler::FieldOffsetBits>(handler_word);
|
| + Label if_inobject(this), if_out_of_object(this);
|
| + Branch(IsSetWord<StoreHandler::IsInobjectBits>(handler_word), &if_inobject,
|
| + &if_out_of_object);
|
| +
|
| + Bind(&if_inobject);
|
| + {
|
| + StoreNamedField(holder, offset, true, representation, prepared_value,
|
| + transition_to_field);
|
| + Return(value);
|
| + }
|
| +
|
| + Bind(&if_out_of_object);
|
| + {
|
| + StoreNamedField(holder, offset, false, representation, prepared_value,
|
| + transition_to_field);
|
| + Return(value);
|
| + }
|
| +}
|
| +
|
| +void CodeStubAssembler::HandleStoreICSmiHandlerCase(Node* handler_word,
|
| + Node* holder, Node* value,
|
| + bool transition_to_field,
|
| + Label* miss) {
|
| + Comment(transition_to_field ? "transitioning field store" : "field store");
|
| +
|
| + Node* field_representation =
|
| + DecodeWord<StoreHandler::FieldRepresentationBits>(handler_word);
|
| +
|
| + Label if_smi_field(this), if_double_field(this), if_heap_object_field(this),
|
| + if_tagged_field(this);
|
| +
|
| + GotoIf(WordEqual(field_representation, IntPtrConstant(StoreHandler::kTagged)),
|
| + &if_tagged_field);
|
| + GotoIf(WordEqual(field_representation,
|
| + IntPtrConstant(StoreHandler::kHeapObject)),
|
| + &if_heap_object_field);
|
| + GotoIf(WordEqual(field_representation, IntPtrConstant(StoreHandler::kDouble)),
|
| + &if_double_field);
|
| + CSA_ASSERT(
|
| + WordEqual(field_representation, IntPtrConstant(StoreHandler::kSmi)));
|
| + Goto(&if_smi_field);
|
| +
|
| + Bind(&if_tagged_field);
|
| + {
|
| + Comment("store tagged field");
|
| + HandleStoreFieldAndReturn(handler_word, holder, Representation::Tagged(),
|
| + value, transition_to_field, miss);
|
| + }
|
| +
|
| + Bind(&if_double_field);
|
| + {
|
| + Comment("store double field");
|
| + HandleStoreFieldAndReturn(handler_word, holder, Representation::Double(),
|
| + value, transition_to_field, miss);
|
| + }
|
| +
|
| + Bind(&if_heap_object_field);
|
| + {
|
| + Comment("store heap object field");
|
| + // Generate full field type check here and then store value as Tagged.
|
| + Node* prepared_value =
|
| + PrepareValueForWrite(value, Representation::HeapObject(), miss);
|
| + Node* value_index_in_descriptor =
|
| + DecodeWord<StoreHandler::DescriptorValueIndexBits>(handler_word);
|
| + Node* descriptors = LoadMapDescriptors(LoadMap(holder));
|
| + Node* maybe_field_type = LoadFixedArrayElement(
|
| + descriptors, value_index_in_descriptor, 0, INTPTR_PARAMETERS);
|
| + Label do_store(this);
|
| + GotoIf(TaggedIsSmi(maybe_field_type), &do_store);
|
| + // Check that value type matches the field type.
|
| + {
|
| + Node* field_type = LoadWeakCellValue(maybe_field_type, miss);
|
| + Branch(WordEqual(LoadMap(prepared_value), field_type), &do_store, miss);
|
| + }
|
| + Bind(&do_store);
|
| + HandleStoreFieldAndReturn(handler_word, holder, Representation::Tagged(),
|
| + prepared_value, transition_to_field, miss);
|
| + }
|
| +
|
| + Bind(&if_smi_field);
|
| + {
|
| + Comment("store smi field");
|
| + HandleStoreFieldAndReturn(handler_word, holder, Representation::Smi(),
|
| + value, transition_to_field, miss);
|
| + }
|
| +}
|
| +
|
| +void CodeStubAssembler::HandleStoreICHandlerCase(const StoreICParameters* p,
|
| + Node* handler, Label* miss) {
|
| + Label if_smi_handler(this), call_handler(this);
|
| +
|
| + Branch(TaggedIsSmi(handler), &if_smi_handler, &call_handler);
|
| +
|
| + // |handler| is a Smi, encoding what to do. See SmiHandler methods
|
| + // for the encoding format.
|
| + Bind(&if_smi_handler);
|
| + {
|
| + Node* holder = p->receiver;
|
| + Node* handler_word = SmiUntag(handler);
|
| +
|
| + // Handle non-transitioning stores.
|
| + HandleStoreICSmiHandlerCase(handler_word, holder, p->value, false, miss);
|
| + }
|
| +
|
| + // |handler| is a heap object. Must be code, call it.
|
| + Bind(&call_handler);
|
| + {
|
| + StoreWithVectorDescriptor descriptor(isolate());
|
| + TailCallStub(descriptor, handler, p->context, p->receiver, p->name,
|
| + p->value, p->slot, p->vector);
|
| + }
|
| +}
|
| +
|
| void CodeStubAssembler::StoreIC(const StoreICParameters* p) {
|
| Variable var_handler(this, MachineRepresentation::kTagged);
|
| // TODO(ishell): defer blocks when it works.
|
| @@ -5720,9 +5839,7 @@ void CodeStubAssembler::StoreIC(const StoreICParameters* p) {
|
| Bind(&if_handler);
|
| {
|
| Comment("StoreIC_if_handler");
|
| - StoreWithVectorDescriptor descriptor(isolate());
|
| - TailCallStub(descriptor, var_handler.value(), p->context, p->receiver,
|
| - p->name, p->value, p->slot, p->vector);
|
| + HandleStoreICHandlerCase(p, var_handler.value(), &miss);
|
| }
|
|
|
| Bind(&try_polymorphic);
|
| @@ -5756,6 +5873,9 @@ void CodeStubAssembler::StoreIC(const StoreICParameters* p) {
|
| void CodeStubAssembler::KeyedStoreIC(const StoreICParameters* p,
|
| LanguageMode language_mode) {
|
| Variable var_handler(this, MachineRepresentation::kTagged);
|
| + // This is to make |miss| label see the var_handler bound on all paths.
|
| + var_handler.Bind(IntPtrConstant(0));
|
| +
|
| // TODO(ishell): defer blocks when it works.
|
| Label if_handler(this, &var_handler), try_polymorphic(this),
|
| try_megamorphic(this /*, Label::kDeferred*/),
|
| @@ -5771,9 +5891,7 @@ void CodeStubAssembler::KeyedStoreIC(const StoreICParameters* p,
|
| Bind(&if_handler);
|
| {
|
| Comment("KeyedStoreIC_if_handler");
|
| - StoreWithVectorDescriptor descriptor(isolate());
|
| - TailCallStub(descriptor, var_handler.value(), p->context, p->receiver,
|
| - p->name, p->value, p->slot, p->vector);
|
| + HandleStoreICHandlerCase(p, var_handler.value(), &miss);
|
| }
|
|
|
| Bind(&try_polymorphic);
|
|
|