| Index: src/code-stub-assembler.cc
|
| diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
|
| index e44e52f428419b0f46d7541ae56978ac10ff0aee..8210758883b217b18d852ef01122e311d2b0dace 100644
|
| --- a/src/code-stub-assembler.cc
|
| +++ b/src/code-stub-assembler.cc
|
| @@ -4728,6 +4728,48 @@ void CodeStubAssembler::HandlePolymorphicCase(
|
| }
|
| }
|
|
|
| +void CodeStubAssembler::HandleKeyedStorePolymorphicCase(
|
| + compiler::Node* receiver_map, compiler::Node* feedback, Label* if_handler,
|
| + Variable* var_handler, Label* if_transition_handler,
|
| + Variable* var_transition_map_cell, Label* if_miss) {
|
| + DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep());
|
| + DCHECK_EQ(MachineRepresentation::kTagged, var_transition_map_cell->rep());
|
| +
|
| + const int kEntrySize = 3;
|
| +
|
| + Variable var_index(this, MachineType::PointerRepresentation());
|
| + Label loop(this, &var_index);
|
| + var_index.Bind(IntPtrConstant(0));
|
| + Node* length = LoadAndUntagFixedArrayBaseLength(feedback);
|
| + Goto(&loop);
|
| + Bind(&loop);
|
| + {
|
| + Node* index = var_index.value();
|
| + GotoIf(UintPtrGreaterThanOrEqual(index, length), if_miss);
|
| +
|
| + Node* cached_map = LoadWeakCellValue(
|
| + LoadFixedArrayElement(feedback, index, 0, INTPTR_PARAMETERS));
|
| +
|
| + Label next_entry(this);
|
| + GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry);
|
| +
|
| + Node* maybe_transition_map_cell =
|
| + LoadFixedArrayElement(feedback, index, kPointerSize, INTPTR_PARAMETERS);
|
| +
|
| + var_handler->Bind(LoadFixedArrayElement(feedback, index, 2 * kPointerSize,
|
| + INTPTR_PARAMETERS));
|
| + GotoIf(WordEqual(maybe_transition_map_cell,
|
| + LoadRoot(Heap::kUndefinedValueRootIndex)),
|
| + if_handler);
|
| + var_transition_map_cell->Bind(maybe_transition_map_cell);
|
| + Goto(if_transition_handler);
|
| +
|
| + Bind(&next_entry);
|
| + var_index.Bind(IntPtrAdd(index, IntPtrConstant(kEntrySize)));
|
| + Goto(&loop);
|
| + }
|
| +}
|
| +
|
| compiler::Node* CodeStubAssembler::StubCachePrimaryOffset(compiler::Node* name,
|
| compiler::Node* map) {
|
| // See v8::internal::StubCache::PrimaryOffset().
|
| @@ -5569,6 +5611,85 @@ void CodeStubAssembler::StoreIC(const StoreICParameters* p) {
|
| }
|
| }
|
|
|
| +void CodeStubAssembler::KeyedStoreIC(const StoreICParameters* p,
|
| + LanguageMode language_mode) {
|
| + Variable var_handler(this, MachineRepresentation::kTagged);
|
| + // TODO(ishell): defer blocks when it works.
|
| + Label if_handler(this, &var_handler), try_polymorphic(this),
|
| + try_megamorphic(this /*, Label::kDeferred*/),
|
| + try_polymorphic_name(this /*, Label::kDeferred*/),
|
| + miss(this /*, Label::kDeferred*/);
|
| +
|
| + Node* receiver_map = LoadReceiverMap(p->receiver);
|
| +
|
| + // Check monomorphic case.
|
| + Node* feedback =
|
| + TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler,
|
| + &var_handler, &try_polymorphic);
|
| + 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);
|
| + }
|
| +
|
| + Bind(&try_polymorphic);
|
| + {
|
| + // CheckPolymorphic case.
|
| + Comment("KeyedStoreIC_try_polymorphic");
|
| + GotoUnless(
|
| + WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)),
|
| + &try_megamorphic);
|
| + Label if_transition_handler(this);
|
| + Variable var_transition_map_cell(this, MachineRepresentation::kTagged);
|
| + HandleKeyedStorePolymorphicCase(receiver_map, feedback, &if_handler,
|
| + &var_handler, &if_transition_handler,
|
| + &var_transition_map_cell, &miss);
|
| + Bind(&if_transition_handler);
|
| + Comment("KeyedStoreIC_polymorphic_transition");
|
| + Node* transition_map =
|
| + LoadWeakCellValue(var_transition_map_cell.value(), &miss);
|
| + StoreTransitionDescriptor descriptor(isolate());
|
| + TailCallStub(descriptor, var_handler.value(), p->context, p->receiver,
|
| + p->name, transition_map, p->value, p->slot, p->vector);
|
| + }
|
| +
|
| + Bind(&try_megamorphic);
|
| + {
|
| + // Check megamorphic case.
|
| + Comment("KeyedStoreIC_try_megamorphic");
|
| + GotoUnless(
|
| + WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)),
|
| + &try_polymorphic_name);
|
| + TailCallStub(
|
| + CodeFactory::KeyedStoreIC_Megamorphic(isolate(), language_mode),
|
| + p->context, p->receiver, p->name, p->value, p->slot, p->vector);
|
| + }
|
| +
|
| + Bind(&try_polymorphic_name);
|
| + {
|
| + // We might have a name in feedback, and a fixed array in the next slot.
|
| + Comment("KeyedStoreIC_try_polymorphic_name");
|
| + GotoUnless(WordEqual(feedback, p->name), &miss);
|
| + // If the name comparison succeeded, we know we have a FixedArray with
|
| + // at least one map/handler pair.
|
| + Node* offset = ElementOffsetFromIndex(
|
| + p->slot, FAST_HOLEY_ELEMENTS, SMI_PARAMETERS,
|
| + FixedArray::kHeaderSize + kPointerSize - kHeapObjectTag);
|
| + Node* array = Load(MachineType::AnyTagged(), p->vector, offset);
|
| + HandlePolymorphicCase(receiver_map, array, &if_handler, &var_handler, &miss,
|
| + 1);
|
| + }
|
| +
|
| + Bind(&miss);
|
| + {
|
| + Comment("KeyedStoreIC_miss");
|
| + TailCallRuntime(Runtime::kKeyedStoreIC_Miss, p->context, p->value, p->slot,
|
| + p->vector, p->receiver, p->name);
|
| + }
|
| +}
|
| +
|
| void CodeStubAssembler::LoadGlobalIC(const LoadICParameters* p) {
|
| Label try_handler(this), miss(this);
|
| Node* weak_cell =
|
|
|