Index: src/type-feedback-vector.cc |
diff --git a/src/type-feedback-vector.cc b/src/type-feedback-vector.cc |
index 9da3c655fbeb53658e1a86dc14e04b8f7dfcf4f5..ea6d7833164b1e1e86e6db89778c7a4c70f87e0b 100644 |
--- a/src/type-feedback-vector.cc |
+++ b/src/type-feedback-vector.cc |
@@ -19,14 +19,14 @@ std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind) { |
FeedbackVectorSlotKind TypeFeedbackVector::GetKind( |
- FeedbackVectorICSlot slot) const { |
+ FeedbackVectorSlot slot) const { |
int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); |
int data = Smi::cast(get(index))->value(); |
return VectorICComputer::decode(data, slot.ToInt()); |
} |
-void TypeFeedbackVector::SetKind(FeedbackVectorICSlot slot, |
+void TypeFeedbackVector::SetKind(FeedbackVectorSlot slot, |
FeedbackVectorSlotKind kind) { |
int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); |
int data = Smi::cast(get(index))->value(); |
@@ -35,33 +35,37 @@ void TypeFeedbackVector::SetKind(FeedbackVectorICSlot slot, |
} |
-template Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate( |
+template Handle<TypeFeedbackVector> TypeFeedbackVector::New( |
Isolate* isolate, const StaticFeedbackVectorSpec* spec); |
-template Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate( |
+template Handle<TypeFeedbackVector> TypeFeedbackVector::New( |
Isolate* isolate, const FeedbackVectorSpec* spec); |
// static |
template <typename Spec> |
-Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(Isolate* isolate, |
- const Spec* spec) { |
+Handle<TypeFeedbackVector> TypeFeedbackVector::New(Isolate* isolate, |
+ const Spec* spec) { |
const int slot_count = spec->slots(); |
- const int ic_slot_count = spec->ic_slots(); |
- const int index_count = VectorICComputer::word_count(ic_slot_count); |
- const int length = slot_count + (ic_slot_count * elements_per_ic_slot()) + |
- index_count + kReservedIndexCount; |
+ const int index_count = VectorICComputer::word_count(slot_count); |
+ const int length = slot_count + index_count + kReservedIndexCount; |
if (length == kReservedIndexCount) { |
return Handle<TypeFeedbackVector>::cast( |
isolate->factory()->empty_fixed_array()); |
} |
+#ifdef DEBUG |
+ for (int i = 0; i < slot_count;) { |
+ FeedbackVectorSlotKind kind = spec->GetKind(i); |
+ int entry_size = TypeFeedbackVector::GetSlotSize(kind); |
+ for (int j = 1; j < entry_size; j++) { |
+ FeedbackVectorSlotKind kind = spec->GetKind(i + j); |
+ DCHECK_EQ(FeedbackVectorSlotKind::INVALID, kind); |
+ } |
+ i += entry_size; |
+ } |
+#endif |
Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED); |
- if (ic_slot_count > 0) { |
- array->set(kFirstICSlotIndex, |
- Smi::FromInt(slot_count + index_count + kReservedIndexCount)); |
- } else { |
- array->set(kFirstICSlotIndex, Smi::FromInt(length)); |
- } |
+ array->set(kSlotsCountIndex, Smi::FromInt(slot_count)); |
array->set(kWithTypesIndex, Smi::FromInt(0)); |
array->set(kGenericCountIndex, Smi::FromInt(0)); |
// Fill the indexes with zeros. |
@@ -77,38 +81,19 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(Isolate* isolate, |
} |
Handle<TypeFeedbackVector> vector = Handle<TypeFeedbackVector>::cast(array); |
- for (int i = 0; i < ic_slot_count; i++) { |
- vector->SetKind(FeedbackVectorICSlot(i), spec->GetKind(i)); |
+ for (int i = 0; i < slot_count; i++) { |
+ vector->SetKind(FeedbackVectorSlot(i), spec->GetKind(i)); |
} |
return vector; |
} |
-template int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec*, |
- FeedbackVectorICSlot); |
-template int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec*, |
- FeedbackVectorSlot); |
- |
- |
// static |
-template <typename Spec> |
-int TypeFeedbackVector::GetIndexFromSpec(const Spec* spec, |
+int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec* spec, |
FeedbackVectorSlot slot) { |
- const int ic_slot_count = spec->ic_slots(); |
- const int index_count = VectorICComputer::word_count(ic_slot_count); |
- return kReservedIndexCount + index_count + slot.ToInt(); |
-} |
- |
- |
-// static |
-template <typename Spec> |
-int TypeFeedbackVector::GetIndexFromSpec(const Spec* spec, |
- FeedbackVectorICSlot slot) { |
const int slot_count = spec->slots(); |
- const int ic_slot_count = spec->ic_slots(); |
- const int index_count = VectorICComputer::word_count(ic_slot_count); |
- return kReservedIndexCount + index_count + slot_count + |
- slot.ToInt() * elements_per_ic_slot(); |
+ const int index_count = VectorICComputer::word_count(slot_count); |
+ return kReservedIndexCount + index_count + slot.ToInt(); |
} |
@@ -122,12 +107,12 @@ int TypeFeedbackVector::PushAppliedArgumentsIndex() { |
// static |
Handle<TypeFeedbackVector> TypeFeedbackVector::CreatePushAppliedArgumentsVector( |
Isolate* isolate) { |
- FeedbackVectorSlotKind kinds[] = {FeedbackVectorSlotKind::KEYED_LOAD_IC}; |
- StaticFeedbackVectorSpec spec(0, 1, kinds); |
+ StaticFeedbackVectorSpec spec; |
+ FeedbackVectorSlot slot = spec.AddKeyedLoadICSlot(); |
Handle<TypeFeedbackVector> feedback_vector = |
- isolate->factory()->NewTypeFeedbackVector(&spec); |
- DCHECK(PushAppliedArgumentsIndex() == |
- feedback_vector->GetIndex(FeedbackVectorICSlot(0))); |
+ TypeFeedbackVector::New(isolate, &spec); |
+ DCHECK_EQ(PushAppliedArgumentsIndex(), feedback_vector->GetIndex(slot)); |
+ USE(slot); |
return feedback_vector; |
} |
@@ -144,13 +129,13 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::Copy( |
bool TypeFeedbackVector::SpecDiffersFrom( |
const FeedbackVectorSpec* other_spec) const { |
- if (other_spec->slots() != Slots() || other_spec->ic_slots() != ICSlots()) { |
+ if (other_spec->slots() != Slots()) { |
return true; |
} |
- int ic_slots = ICSlots(); |
- for (int i = 0; i < ic_slots; i++) { |
- if (GetKind(FeedbackVectorICSlot(i)) != other_spec->GetKind(i)) { |
+ int slots = Slots(); |
+ for (int i = 0; i < slots; i++) { |
+ if (GetKind(FeedbackVectorSlot(i)) != other_spec->GetKind(i)) { |
return true; |
} |
} |
@@ -160,82 +145,69 @@ bool TypeFeedbackVector::SpecDiffersFrom( |
// This logic is copied from |
// StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget. |
-static bool ClearLogic(Heap* heap) { |
- return FLAG_cleanup_code_caches_at_gc && |
- heap->isolate()->serializer_enabled(); |
+static bool ClearLogic(Isolate* isolate) { |
+ return FLAG_cleanup_code_caches_at_gc && isolate->serializer_enabled(); |
} |
void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared, |
bool force_clear) { |
- int slots = Slots(); |
- Heap* heap = GetIsolate()->heap(); |
+ Isolate* isolate = GetIsolate(); |
- if (!force_clear && !ClearLogic(heap)) return; |
+ if (!force_clear && !ClearLogic(isolate)) return; |
Object* uninitialized_sentinel = |
- TypeFeedbackVector::RawUninitializedSentinel(heap); |
- for (int i = 0; i < slots; i++) { |
- FeedbackVectorSlot slot(i); |
- Object* obj = Get(slot); |
- if (obj->IsHeapObject()) { |
- InstanceType instance_type = |
- HeapObject::cast(obj)->map()->instance_type(); |
- // AllocationSites are exempt from clearing. They don't store Maps |
- // or Code pointers which can cause memory leaks if not cleared |
- // regularly. |
- if (instance_type != ALLOCATION_SITE_TYPE) { |
- Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER); |
- } |
- } |
- } |
-} |
- |
+ TypeFeedbackVector::RawUninitializedSentinel(isolate); |
-void TypeFeedbackVector::ClearICSlotsImpl(SharedFunctionInfo* shared, |
- bool force_clear) { |
- Heap* heap = GetIsolate()->heap(); |
+ TypeFeedbackMetadataIterator iter(this); |
+ while (iter.HasNext()) { |
+ FeedbackVectorSlot slot = iter.Next(); |
+ FeedbackVectorSlotKind kind = iter.kind(); |
- if (!force_clear && !ClearLogic(heap)) return; |
- |
- int slots = ICSlots(); |
- Code* host = shared->code(); |
- Object* uninitialized_sentinel = |
- TypeFeedbackVector::RawUninitializedSentinel(heap); |
- for (int i = 0; i < slots; i++) { |
- FeedbackVectorICSlot slot(i); |
Object* obj = Get(slot); |
if (obj != uninitialized_sentinel) { |
- FeedbackVectorSlotKind kind = GetKind(slot); |
switch (kind) { |
case FeedbackVectorSlotKind::CALL_IC: { |
CallICNexus nexus(this, slot); |
- nexus.Clear(host); |
+ nexus.Clear(shared->code()); |
break; |
} |
case FeedbackVectorSlotKind::LOAD_IC: { |
LoadICNexus nexus(this, slot); |
- nexus.Clear(host); |
+ nexus.Clear(shared->code()); |
break; |
} |
case FeedbackVectorSlotKind::KEYED_LOAD_IC: { |
KeyedLoadICNexus nexus(this, slot); |
- nexus.Clear(host); |
+ nexus.Clear(shared->code()); |
break; |
} |
case FeedbackVectorSlotKind::STORE_IC: { |
DCHECK(FLAG_vector_stores); |
StoreICNexus nexus(this, slot); |
- nexus.Clear(host); |
+ nexus.Clear(shared->code()); |
break; |
} |
case FeedbackVectorSlotKind::KEYED_STORE_IC: { |
DCHECK(FLAG_vector_stores); |
KeyedStoreICNexus nexus(this, slot); |
- nexus.Clear(host); |
+ nexus.Clear(shared->code()); |
+ break; |
+ } |
+ case FeedbackVectorSlotKind::GENERAL: { |
+ if (obj->IsHeapObject()) { |
+ InstanceType instance_type = |
+ HeapObject::cast(obj)->map()->instance_type(); |
+ // AllocationSites are exempt from clearing. They don't store Maps |
+ // or Code pointers which can cause memory leaks if not cleared |
+ // regularly. |
+ if (instance_type != ALLOCATION_SITE_TYPE) { |
+ Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER); |
+ } |
+ } |
break; |
} |
- case FeedbackVectorSlotKind::UNUSED: |
+ case FeedbackVectorSlotKind::INVALID: |
case FeedbackVectorSlotKind::KINDS_NUMBER: |
UNREACHABLE(); |
break; |
@@ -258,22 +230,22 @@ void TypeFeedbackVector::ClearAllKeyedStoreICs(Isolate* isolate) { |
void TypeFeedbackVector::ClearKeyedStoreICs(SharedFunctionInfo* shared) { |
- Heap* heap = GetIsolate()->heap(); |
+ Isolate* isolate = GetIsolate(); |
- int slots = ICSlots(); |
Code* host = shared->code(); |
Object* uninitialized_sentinel = |
- TypeFeedbackVector::RawUninitializedSentinel(heap); |
- for (int i = 0; i < slots; i++) { |
- FeedbackVectorICSlot slot(i); |
+ TypeFeedbackVector::RawUninitializedSentinel(isolate); |
+ |
+ TypeFeedbackMetadataIterator iter(this); |
+ while (iter.HasNext()) { |
+ FeedbackVectorSlot slot = iter.Next(); |
+ FeedbackVectorSlotKind kind = iter.kind(); |
+ if (kind != FeedbackVectorSlotKind::KEYED_STORE_IC) continue; |
Object* obj = Get(slot); |
if (obj != uninitialized_sentinel) { |
- FeedbackVectorSlotKind kind = GetKind(slot); |
- if (kind == FeedbackVectorSlotKind::KEYED_STORE_IC) { |
- DCHECK(FLAG_vector_stores); |
- KeyedStoreICNexus nexus(this, slot); |
- nexus.Clear(host); |
- } |
+ DCHECK(FLAG_vector_stores); |
+ KeyedStoreICNexus nexus(this, slot); |
+ nexus.Clear(host); |
} |
} |
} |
@@ -281,14 +253,14 @@ void TypeFeedbackVector::ClearKeyedStoreICs(SharedFunctionInfo* shared) { |
// static |
Handle<TypeFeedbackVector> TypeFeedbackVector::DummyVector(Isolate* isolate) { |
- return Handle<TypeFeedbackVector>::cast(isolate->factory()->dummy_vector()); |
+ return isolate->factory()->dummy_vector(); |
} |
const char* TypeFeedbackVector::Kind2String(FeedbackVectorSlotKind kind) { |
switch (kind) { |
- case FeedbackVectorSlotKind::UNUSED: |
- return "UNUSED"; |
+ case FeedbackVectorSlotKind::INVALID: |
+ return "INVALID"; |
case FeedbackVectorSlotKind::CALL_IC: |
return "CALL_IC"; |
case FeedbackVectorSlotKind::LOAD_IC: |
@@ -299,6 +271,8 @@ const char* TypeFeedbackVector::Kind2String(FeedbackVectorSlotKind kind) { |
return "STORE_IC"; |
case FeedbackVectorSlotKind::KEYED_STORE_IC: |
return "KEYED_STORE_IC"; |
+ case FeedbackVectorSlotKind::GENERAL: |
+ return "STUB"; |
case FeedbackVectorSlotKind::KINDS_NUMBER: |
break; |
} |