__ ldr(receiver, MemOperand(fp, argumentsOffset));
// Use inline caching to speed up access to arguments.
- FeedbackVectorSpec spec(0, Code::KEYED_LOAD_IC);
+ Code::Kind kinds[] = {Code::KEYED_LOAD_IC};
+ FeedbackVectorSpec spec(0, 1, kinds);
Handle<TypeFeedbackVector> feedback_vector =
masm->isolate()->factory()->NewTypeFeedbackVector(&spec);
int index = feedback_vector->GetIndex(FeedbackVectorICSlot(0));
__ Ldr(receiver, MemOperand(fp, argumentsOffset));
// Use inline caching to speed up access to arguments.
- FeedbackVectorSpec spec(0, Code::KEYED_LOAD_IC);
+ Code::Kind kinds[] = {Code::KEYED_LOAD_IC};
+ FeedbackVectorSpec spec(0, 1, kinds);
Handle<TypeFeedbackVector> feedback_vector =
masm->isolate()->factory()->NewTypeFeedbackVector(&spec);
int index = feedback_vector->GetIndex(FeedbackVectorICSlot(0));
set_microtask_queue(empty_fixed_array());
{
- FeedbackVectorSpec spec(0, Code::KEYED_LOAD_IC);
+ Code::Kind kinds[] = {Code::LOAD_IC, Code::KEYED_LOAD_IC, Code::STORE_IC,
+ Code::KEYED_STORE_IC};
+ FeedbackVectorSpec spec(0, 4, kinds);
Handle<TypeFeedbackVector> dummy_vector =
factory->NewTypeFeedbackVector(&spec);
- dummy_vector->Set(FeedbackVectorICSlot(0),
- *TypeFeedbackVector::MegamorphicSentinel(isolate()),
- SKIP_WRITE_BARRIER);
- set_keyed_load_dummy_vector(*dummy_vector);
- }
-
- if (FLAG_vector_stores) {
- FeedbackVectorSpec spec(0, Code::KEYED_STORE_IC);
- Handle<TypeFeedbackVector> dummy_vector =
- factory->NewTypeFeedbackVector(&spec);
- dummy_vector->Set(FeedbackVectorICSlot(0),
- *TypeFeedbackVector::MegamorphicSentinel(isolate()),
- SKIP_WRITE_BARRIER);
- set_keyed_store_dummy_vector(*dummy_vector);
- } else {
- set_keyed_store_dummy_vector(empty_fixed_array());
+ for (int i = 0; i < 4; i++) {
+ dummy_vector->Set(FeedbackVectorICSlot(0),
+ *TypeFeedbackVector::MegamorphicSentinel(isolate()),
+ SKIP_WRITE_BARRIER);
+ }
+ set_dummy_vector(*dummy_vector);
}
set_detached_contexts(empty_fixed_array());
V(FixedArray, materialized_objects, MaterializedObjects) \
V(FixedArray, allocation_sites_scratchpad, AllocationSitesScratchpad) \
V(FixedArray, microtask_queue, MicrotaskQueue) \
- V(FixedArray, keyed_load_dummy_vector, KeyedLoadDummyVector) \
- V(FixedArray, keyed_store_dummy_vector, KeyedStoreDummyVector) \
+ V(FixedArray, dummy_vector, DummyVector) \
V(FixedArray, detached_contexts, DetachedContexts) \
V(ArrayList, retained_maps, RetainedMaps) \
V(WeakHashTable, weak_object_to_code_table, WeakObjectToCodeTable) \
__ mov(receiver, Operand(ebp, argumentsOffset)); // load arguments
// Use inline caching to speed up access to arguments.
- FeedbackVectorSpec spec(0, Code::KEYED_LOAD_IC);
+ Code::Kind kinds[] = {Code::KEYED_LOAD_IC};
+ FeedbackVectorSpec spec(0, 1, kinds);
Handle<TypeFeedbackVector> feedback_vector =
masm->isolate()->factory()->NewTypeFeedbackVector(&spec);
int index = feedback_vector->GetIndex(FeedbackVectorICSlot(0));
Register vector = LoadWithVectorDescriptor::VectorRegister();
Register slot = LoadWithVectorDescriptor::SlotRegister();
DCHECK(!AreAliased(vector, slot, r4, r5, r6, r9));
- Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast(
- masm->isolate()->factory()->keyed_load_dummy_vector());
- int slot_index = dummy_vector->GetIndex(FeedbackVectorICSlot(0));
- __ LoadRoot(vector, Heap::kKeyedLoadDummyVectorRootIndex);
+ Handle<TypeFeedbackVector> dummy_vector =
+ TypeFeedbackVector::DummyVector(masm->isolate());
+ int slot_index = dummy_vector->GetIndex(
+ FeedbackVectorICSlot(TypeFeedbackVector::kDummyKeyedLoadICSlot));
+ __ LoadRoot(vector, Heap::kDummyVectorRootIndex);
__ mov(slot, Operand(Smi::FromInt(slot_index)));
Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
Register vector = VectorStoreICDescriptor::VectorRegister();
Register slot = VectorStoreICDescriptor::SlotRegister();
DCHECK(!AreAliased(vector, slot, r3, r4, r5, r6));
- Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast(
- masm->isolate()->factory()->keyed_store_dummy_vector());
- int slot_index = dummy_vector->GetIndex(FeedbackVectorICSlot(0));
- __ LoadRoot(vector, Heap::kKeyedStoreDummyVectorRootIndex);
+ Handle<TypeFeedbackVector> dummy_vector =
+ TypeFeedbackVector::DummyVector(masm->isolate());
+ int slot_index = dummy_vector->GetIndex(
+ FeedbackVectorICSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot));
+ __ LoadRoot(vector, Heap::kDummyVectorRootIndex);
__ mov(slot, Operand(Smi::FromInt(slot_index)));
}
Register vector = LoadWithVectorDescriptor::VectorRegister();
Register slot = LoadWithVectorDescriptor::SlotRegister();
DCHECK(!AreAliased(vector, slot, scratch1, scratch2, scratch3, scratch4));
- Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast(
- masm->isolate()->factory()->keyed_load_dummy_vector());
- int slot_index = dummy_vector->GetIndex(FeedbackVectorICSlot(0));
- __ LoadRoot(vector, Heap::kKeyedLoadDummyVectorRootIndex);
+ Handle<TypeFeedbackVector> dummy_vector =
+ TypeFeedbackVector::DummyVector(masm->isolate());
+ int slot_index = dummy_vector->GetIndex(
+ FeedbackVectorICSlot(TypeFeedbackVector::kDummyKeyedLoadICSlot));
+ __ LoadRoot(vector, Heap::kDummyVectorRootIndex);
__ Mov(slot, Operand(Smi::FromInt(slot_index)));
Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
Register vector = VectorStoreICDescriptor::VectorRegister();
Register slot = VectorStoreICDescriptor::SlotRegister();
DCHECK(!AreAliased(vector, slot, x3, x4, x5, x6));
- Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast(
- masm->isolate()->factory()->keyed_store_dummy_vector());
- int slot_index = dummy_vector->GetIndex(FeedbackVectorICSlot(0));
- __ LoadRoot(vector, Heap::kKeyedStoreDummyVectorRootIndex);
+ Handle<TypeFeedbackVector> dummy_vector =
+ TypeFeedbackVector::DummyVector(masm->isolate());
+ int slot_index = dummy_vector->GetIndex(
+ FeedbackVectorICSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot));
+ __ LoadRoot(vector, Heap::kDummyVectorRootIndex);
__ Mov(slot, Operand(Smi::FromInt(slot_index)));
}
// The handlers in the stub cache expect a vector and slot. Since we won't
// change the IC from any downstream misses, a dummy vector can be used.
- Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast(
- isolate->factory()->keyed_load_dummy_vector());
- int slot = dummy_vector->GetIndex(FeedbackVectorICSlot(0));
+ Handle<TypeFeedbackVector> dummy_vector =
+ TypeFeedbackVector::DummyVector(isolate);
+ int slot = dummy_vector->GetIndex(
+ FeedbackVectorICSlot(TypeFeedbackVector::kDummyKeyedLoadICSlot));
__ push(Immediate(Smi::FromInt(slot)));
__ push(Immediate(dummy_vector));
if (FLAG_vector_stores) {
// The handlers in the stub cache expect a vector and slot. Since we won't
// change the IC from any downstream misses, a dummy vector can be used.
- Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast(
- masm->isolate()->factory()->keyed_store_dummy_vector());
- int slot = dummy_vector->GetIndex(FeedbackVectorICSlot(0));
+ Handle<TypeFeedbackVector> dummy_vector =
+ TypeFeedbackVector::DummyVector(masm->isolate());
+ int slot = dummy_vector->GetIndex(
+ FeedbackVectorICSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot));
__ push(Immediate(Smi::FromInt(slot)));
__ push(Immediate(dummy_vector));
}
#define TRACE_IC(type, name) TraceIC(type, name)
-IC::IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus,
- bool for_queries_only)
+IC::IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus)
: isolate_(isolate),
target_set_(false),
vector_set_(false),
pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address);
target_ = handle(raw_target(), isolate);
kind_ = target_->kind();
- state_ = (!for_queries_only && UseVector()) ? nexus->StateFromFeedback()
- : target_->ic_state();
+ state_ = UseVector() ? nexus->StateFromFeedback() : target_->ic_state();
old_state_ = state_;
extra_ic_state_ = target_->extra_ic_state();
}
// Return the undefined result if the reference error should not be thrown.
// Note that both keyed and non-keyed loads may end up here.
- LoadIC ic(IC::NO_EXTRA_FRAME, isolate, true);
+ LoadICNexus nexus(isolate);
+ LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
if (!ic.ShouldThrowReferenceError(it.GetReceiver())) {
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_StorePropertyWithInterceptor) {
HandleScope scope(isolate);
DCHECK(args.length() == 3);
- StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
+ StoreICNexus nexus(isolate);
+ StoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
Handle<JSObject> receiver = args.at<JSObject>(0);
Handle<Name> name = args.at<Name>(1);
Handle<Object> value = args.at<Object>(2);
// Construct the IC structure with the given number of extra
// JavaScript frames on the stack.
- IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL,
- bool for_queries_only = false);
+ IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL);
virtual ~IC() {}
State state() const { return state_; }
DCHECK(IsLoadStub());
}
- // TODO(mvstanton): The for_queries_only is because we have a case where we
- // construct an IC only to gather the contextual mode, and we don't have
- // vector/slot information. for_queries_only is a temporary hack to enable the
- // strong DCHECK protection around vector/slot.
- LoadIC(FrameDepth depth, Isolate* isolate, bool for_queries_only)
- : IC(depth, isolate, NULL, for_queries_only) {
- DCHECK(IsLoadStub());
- }
-
bool ShouldThrowReferenceError(Handle<Object> receiver) {
return receiver->IsGlobalObject() && typeof_mode() == NOT_INSIDE_TYPEOF;
}
Register vector = LoadWithVectorDescriptor::VectorRegister();
Register slot = LoadWithVectorDescriptor::SlotRegister();
DCHECK(!AreAliased(vector, slot, t0, t1, t2, t5));
- Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast(
- masm->isolate()->factory()->keyed_load_dummy_vector());
- int slot_index = dummy_vector->GetIndex(FeedbackVectorICSlot(0));
- __ LoadRoot(vector, Heap::kKeyedLoadDummyVectorRootIndex);
+ Handle<TypeFeedbackVector> dummy_vector =
+ TypeFeedbackVector::DummyVector(masm->isolate());
+ int slot_index = dummy_vector->GetIndex(
+ FeedbackVectorICSlot(TypeFeedbackVector::kDummyKeyedLoadICSlot));
+ __ LoadRoot(vector, Heap::kDummyVectorRootIndex);
__ li(slot, Operand(Smi::FromInt(slot_index)));
Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
Register vector = VectorStoreICDescriptor::VectorRegister();
Register slot = VectorStoreICDescriptor::SlotRegister();
DCHECK(!AreAliased(vector, slot, a3, t0, t1, t2));
- Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast(
- masm->isolate()->factory()->keyed_store_dummy_vector());
- int slot_index = dummy_vector->GetIndex(FeedbackVectorICSlot(0));
- __ LoadRoot(vector, Heap::kKeyedStoreDummyVectorRootIndex);
+ Handle<TypeFeedbackVector> dummy_vector =
+ TypeFeedbackVector::DummyVector(masm->isolate());
+ int slot_index = dummy_vector->GetIndex(
+ FeedbackVectorICSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot));
+ __ LoadRoot(vector, Heap::kDummyVectorRootIndex);
__ li(slot, Operand(Smi::FromInt(slot_index)));
}
Register vector = LoadWithVectorDescriptor::VectorRegister();
Register slot = LoadWithVectorDescriptor::SlotRegister();
DCHECK(!AreAliased(vector, slot, a4, a5, a6, t1));
- Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast(
- masm->isolate()->factory()->keyed_load_dummy_vector());
- int slot_index = dummy_vector->GetIndex(FeedbackVectorICSlot(0));
- __ LoadRoot(vector, Heap::kKeyedLoadDummyVectorRootIndex);
+ Handle<TypeFeedbackVector> dummy_vector =
+ TypeFeedbackVector::DummyVector(masm->isolate());
+ int slot_index = dummy_vector->GetIndex(
+ FeedbackVectorICSlot(TypeFeedbackVector::kDummyKeyedLoadICSlot));
+ __ LoadRoot(vector, Heap::kDummyVectorRootIndex);
__ li(slot, Operand(Smi::FromInt(slot_index)));
Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
Register vector = LoadWithVectorDescriptor::VectorRegister();
Register slot = LoadWithVectorDescriptor::SlotRegister();
DCHECK(!AreAliased(vector, slot, a3, a4, a5, a6));
- Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast(
- masm->isolate()->factory()->keyed_store_dummy_vector());
- int slot_index = dummy_vector->GetIndex(FeedbackVectorICSlot(0));
- __ LoadRoot(vector, Heap::kKeyedStoreDummyVectorRootIndex);
+ Handle<TypeFeedbackVector> dummy_vector =
+ TypeFeedbackVector::DummyVector(masm->isolate());
+ int slot_index = dummy_vector->GetIndex(
+ FeedbackVectorICSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot));
+ __ LoadRoot(vector, Heap::kDummyVectorRootIndex);
__ li(slot, Operand(Smi::FromInt(slot_index)));
}
Register vector = LoadWithVectorDescriptor::VectorRegister();
Register slot = LoadDescriptor::SlotRegister();
DCHECK(!AreAliased(megamorphic_scratch, vector, slot));
- Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast(
- masm->isolate()->factory()->keyed_load_dummy_vector());
- int slot_index = dummy_vector->GetIndex(FeedbackVectorICSlot(0));
+ Handle<TypeFeedbackVector> dummy_vector =
+ TypeFeedbackVector::DummyVector(masm->isolate());
+ int slot_index = dummy_vector->GetIndex(
+ FeedbackVectorICSlot(TypeFeedbackVector::kDummyKeyedLoadICSlot));
__ Move(vector, dummy_vector);
__ Move(slot, Smi::FromInt(slot_index));
Register slot = VectorStoreICDescriptor::SlotRegister();
// The handlers in the stub cache expect a vector and slot. Since we won't
// change the IC from any downstream misses, a dummy vector can be used.
- Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast(
- masm->isolate()->factory()->keyed_store_dummy_vector());
- int slot_index = dummy_vector->GetIndex(FeedbackVectorICSlot(0));
+ Handle<TypeFeedbackVector> dummy_vector =
+ TypeFeedbackVector::DummyVector(masm->isolate());
+ int slot_index = dummy_vector->GetIndex(
+ FeedbackVectorICSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot));
__ Move(vector, dummy_vector);
__ Move(slot, Smi::FromInt(slot_index));
}
__ lw(receiver, MemOperand(fp, argumentsOffset));
// Use inline caching to speed up access to arguments.
- FeedbackVectorSpec spec(0, Code::KEYED_LOAD_IC);
+ Code::Kind kinds[] = {Code::KEYED_LOAD_IC};
+ FeedbackVectorSpec spec(0, 1, kinds);
Handle<TypeFeedbackVector> feedback_vector =
masm->isolate()->factory()->NewTypeFeedbackVector(&spec);
int index = feedback_vector->GetIndex(FeedbackVectorICSlot(0));
__ ld(receiver, MemOperand(fp, argumentsOffset));
// Use inline caching to speed up access to arguments.
- FeedbackVectorSpec spec(0, Code::KEYED_LOAD_IC);
+ Code::Kind kinds[] = {Code::KEYED_LOAD_IC};
+ FeedbackVectorSpec spec(0, 1, kinds);
Handle<TypeFeedbackVector> feedback_vector =
masm->isolate()->factory()->NewTypeFeedbackVector(&spec);
int index = feedback_vector->GetIndex(FeedbackVectorICSlot(0));
case Code::KEYED_LOAD_IC:
return KindKeyedLoadIC;
case Code::STORE_IC:
- DCHECK(FLAG_vector_stores);
return KindStoreIC;
case Code::KEYED_STORE_IC:
- DCHECK(FLAG_vector_stores);
return KindKeyedStoreIC;
default:
// Shouldn't get here.
}
+// static
+Handle<TypeFeedbackVector> TypeFeedbackVector::DummyVector(Isolate* isolate) {
+ return Handle<TypeFeedbackVector>::cast(isolate->factory()->dummy_vector());
+}
+
+
Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) {
Isolate* isolate = GetIsolate();
Handle<Object> feedback = handle(GetFeedback(), isolate);
class FeedbackVectorSpec {
public:
- FeedbackVectorSpec() : slots_(0), has_ic_slot_(false) {}
- explicit FeedbackVectorSpec(int slots) : slots_(slots), has_ic_slot_(false) {}
- FeedbackVectorSpec(int slots, Code::Kind ic_slot_kind)
- : slots_(slots), has_ic_slot_(true), ic_kind_(ic_slot_kind) {}
+ FeedbackVectorSpec() : slots_(0), ic_slots_(0), ic_kinds_(NULL) {}
+ explicit FeedbackVectorSpec(int slots)
+ : slots_(slots), ic_slots_(0), ic_kinds_(NULL) {}
+ FeedbackVectorSpec(int slots, int ic_slots, Code::Kind* ic_slot_kinds)
+ : slots_(slots), ic_slots_(ic_slots), ic_kinds_(ic_slot_kinds) {}
int slots() const { return slots_; }
- int ic_slots() const { return has_ic_slot_ ? 1 : 0; }
+ int ic_slots() const { return ic_slots_; }
Code::Kind GetKind(int ic_slot) const {
- DCHECK(has_ic_slot_ && ic_slot == 0);
- return ic_kind_;
+ DCHECK(ic_slots_ > 0 && ic_slot < ic_slots_);
+ return ic_kinds_[ic_slot];
}
private:
int slots_;
- bool has_ic_slot_;
- Code::Kind ic_kind_;
+ int ic_slots_;
+ Code::Kind* ic_kinds_;
};
// garbage collection (e.g., for patching the cache).
static inline Object* RawUninitializedSentinel(Heap* heap);
+ static const int kDummyLoadICSlot = 0;
+ static const int kDummyKeyedLoadICSlot = 1;
+ static const int kDummyStoreICSlot = 2;
+ static const int kDummyKeyedStoreICSlot = 3;
+
+ static Handle<TypeFeedbackVector> DummyVector(Isolate* isolate);
+ static FeedbackVectorICSlot DummySlot(int dummyIndex) {
+ DCHECK(dummyIndex >= 0 && dummyIndex <= kDummyKeyedStoreICSlot);
+ return FeedbackVectorICSlot(dummyIndex);
+ }
+
private:
enum VectorICKind {
KindUnused = 0x0,
: FeedbackNexus(vector, slot) {
DCHECK(vector->GetKind(slot) == Code::LOAD_IC);
}
+ explicit LoadICNexus(Isolate* isolate)
+ : FeedbackNexus(TypeFeedbackVector::DummyVector(isolate),
+ TypeFeedbackVector::DummySlot(
+ TypeFeedbackVector::kDummyLoadICSlot)) {}
LoadICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot)
: FeedbackNexus(vector, slot) {
DCHECK(vector->GetKind(slot) == Code::LOAD_IC);
: FeedbackNexus(vector, slot) {
DCHECK(vector->GetKind(slot) == Code::STORE_IC);
}
+ explicit StoreICNexus(Isolate* isolate)
+ : FeedbackNexus(TypeFeedbackVector::DummyVector(isolate),
+ TypeFeedbackVector::DummySlot(
+ TypeFeedbackVector::kDummyStoreICSlot)) {}
StoreICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot)
: FeedbackNexus(vector, slot) {
DCHECK(vector->GetKind(slot) == Code::STORE_IC);
__ movp(receiver, Operand(rbp, argumentsOffset)); // load arguments
// Use inline caching to speed up access to arguments.
- FeedbackVectorSpec spec(0, Code::KEYED_LOAD_IC);
+ Code::Kind kinds[] = {Code::KEYED_LOAD_IC};
+ FeedbackVectorSpec spec(0, 1, kinds);
Handle<TypeFeedbackVector> feedback_vector =
masm->isolate()->factory()->NewTypeFeedbackVector(&spec);
int index = feedback_vector->GetIndex(FeedbackVectorICSlot(0));
CHECK_EQ(1, vector->Slots());
CHECK_EQ(0, vector->ICSlots());
- FeedbackVectorSpec one_icslot(0, Code::CALL_IC);
+ ZoneFeedbackVectorSpec one_icslot(zone, 0, 1);
+ one_icslot.SetKind(0, Code::CALL_IC);
vector = factory->NewTypeFeedbackVector(&one_icslot);
CHECK_EQ(0, vector->Slots());
CHECK_EQ(1, vector->ICSlots());