Index: src/type-feedback-vector.cc |
diff --git a/src/type-feedback-vector.cc b/src/type-feedback-vector.cc |
index ea6d7833164b1e1e86e6db89778c7a4c70f87e0b..b860d12e84f42a741783b8ef1c0c7b9b5f22e3e3 100644 |
--- a/src/type-feedback-vector.cc |
+++ b/src/type-feedback-vector.cc |
@@ -14,11 +14,11 @@ namespace v8 { |
namespace internal { |
std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind) { |
- return os << TypeFeedbackVector::Kind2String(kind); |
+ return os << TypeFeedbackMetadata::Kind2String(kind); |
} |
-FeedbackVectorSlotKind TypeFeedbackVector::GetKind( |
+FeedbackVectorSlotKind TypeFeedbackMetadata::GetKind( |
FeedbackVectorSlot slot) const { |
int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); |
int data = Smi::cast(get(index))->value(); |
@@ -26,8 +26,8 @@ FeedbackVectorSlotKind TypeFeedbackVector::GetKind( |
} |
-void TypeFeedbackVector::SetKind(FeedbackVectorSlot slot, |
- FeedbackVectorSlotKind kind) { |
+void TypeFeedbackMetadata::SetKind(FeedbackVectorSlot slot, |
+ FeedbackVectorSlotKind kind) { |
int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); |
int data = Smi::cast(get(index))->value(); |
int new_data = VectorICComputer::encode(data, slot.ToInt(), kind); |
@@ -35,27 +35,27 @@ void TypeFeedbackVector::SetKind(FeedbackVectorSlot slot, |
} |
-template Handle<TypeFeedbackVector> TypeFeedbackVector::New( |
+template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New( |
Isolate* isolate, const StaticFeedbackVectorSpec* spec); |
-template Handle<TypeFeedbackVector> TypeFeedbackVector::New( |
+template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New( |
Isolate* isolate, const FeedbackVectorSpec* spec); |
// static |
template <typename Spec> |
-Handle<TypeFeedbackVector> TypeFeedbackVector::New(Isolate* isolate, |
- const Spec* spec) { |
+Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New(Isolate* isolate, |
+ const Spec* spec) { |
const int slot_count = spec->slots(); |
- const int index_count = VectorICComputer::word_count(slot_count); |
- const int length = slot_count + index_count + kReservedIndexCount; |
+ const int slot_kinds_length = VectorICComputer::word_count(slot_count); |
+ const int length = slot_kinds_length + kReservedIndexCount; |
if (length == kReservedIndexCount) { |
- return Handle<TypeFeedbackVector>::cast( |
+ return Handle<TypeFeedbackMetadata>::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); |
+ int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); |
for (int j = 1; j < entry_size; j++) { |
FeedbackVectorSlotKind kind = spec->GetKind(i + j); |
DCHECK_EQ(FeedbackVectorSlotKind::INVALID, kind); |
@@ -66,41 +66,97 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::New(Isolate* isolate, |
Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED); |
array->set(kSlotsCountIndex, Smi::FromInt(slot_count)); |
- array->set(kWithTypesIndex, Smi::FromInt(0)); |
- array->set(kGenericCountIndex, Smi::FromInt(0)); |
- // Fill the indexes with zeros. |
- for (int i = 0; i < index_count; i++) { |
+ // Fill the bit-vector part with zeros. |
+ for (int i = 0; i < slot_kinds_length; i++) { |
array->set(kReservedIndexCount + i, Smi::FromInt(0)); |
} |
+ Handle<TypeFeedbackMetadata> metadata = |
+ Handle<TypeFeedbackMetadata>::cast(array); |
+ for (int i = 0; i < slot_count; i++) { |
+ metadata->SetKind(FeedbackVectorSlot(i), spec->GetKind(i)); |
+ } |
+ return metadata; |
+} |
+ |
+ |
+bool TypeFeedbackMetadata::SpecDiffersFrom( |
+ const FeedbackVectorSpec* other_spec) const { |
+ if (other_spec->slots() != slot_count()) { |
+ return true; |
+ } |
+ |
+ int slots = slot_count(); |
+ for (int i = 0; i < slots; i++) { |
+ if (GetKind(FeedbackVectorSlot(i)) != other_spec->GetKind(i)) { |
+ return true; |
+ } |
+ } |
+ return false; |
+} |
+ |
+ |
+const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) { |
+ switch (kind) { |
+ case FeedbackVectorSlotKind::INVALID: |
+ return "INVALID"; |
+ case FeedbackVectorSlotKind::CALL_IC: |
+ return "CALL_IC"; |
+ case FeedbackVectorSlotKind::LOAD_IC: |
+ return "LOAD_IC"; |
+ case FeedbackVectorSlotKind::KEYED_LOAD_IC: |
+ return "KEYED_LOAD_IC"; |
+ case FeedbackVectorSlotKind::STORE_IC: |
+ return "STORE_IC"; |
+ case FeedbackVectorSlotKind::KEYED_STORE_IC: |
+ return "KEYED_STORE_IC"; |
+ case FeedbackVectorSlotKind::GENERAL: |
+ return "STUB"; |
+ case FeedbackVectorSlotKind::KINDS_NUMBER: |
+ break; |
+ } |
+ UNREACHABLE(); |
+ return "?"; |
+} |
+ |
+ |
+// static |
+Handle<TypeFeedbackVector> TypeFeedbackVector::New( |
+ Isolate* isolate, Handle<TypeFeedbackMetadata> metadata) { |
+ Factory* factory = isolate->factory(); |
+ |
+ const int slot_count = metadata->slot_count(); |
+ const int length = slot_count + kReservedIndexCount; |
+ if (length == kReservedIndexCount) { |
+ return Handle<TypeFeedbackVector>::cast(factory->empty_fixed_array()); |
+ } |
+ |
+ Handle<FixedArray> array = factory->NewFixedArray(length, TENURED); |
+ array->set(kMetadataIndex, *metadata); |
+ array->set(kWithTypesIndex, Smi::FromInt(0)); |
+ array->set(kGenericCountIndex, Smi::FromInt(0)); |
+ |
// Ensure we can skip the write barrier |
Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); |
- DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel); |
- for (int i = kReservedIndexCount + index_count; i < length; i++) { |
+ DCHECK_EQ(*factory->uninitialized_symbol(), *uninitialized_sentinel); |
+ for (int i = kReservedIndexCount; i < length; i++) { |
array->set(i, *uninitialized_sentinel, SKIP_WRITE_BARRIER); |
} |
- Handle<TypeFeedbackVector> vector = Handle<TypeFeedbackVector>::cast(array); |
- for (int i = 0; i < slot_count; i++) { |
- vector->SetKind(FeedbackVectorSlot(i), spec->GetKind(i)); |
- } |
- return vector; |
+ return Handle<TypeFeedbackVector>::cast(array); |
} |
// static |
int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec* spec, |
FeedbackVectorSlot slot) { |
- const int slot_count = spec->slots(); |
- const int index_count = VectorICComputer::word_count(slot_count); |
- return kReservedIndexCount + index_count + slot.ToInt(); |
+ return kReservedIndexCount + slot.ToInt(); |
} |
// static |
int TypeFeedbackVector::PushAppliedArgumentsIndex() { |
- const int index_count = VectorICComputer::word_count(1); |
- return kReservedIndexCount + index_count; |
+ return kReservedIndexCount; |
} |
@@ -109,8 +165,11 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::CreatePushAppliedArgumentsVector( |
Isolate* isolate) { |
StaticFeedbackVectorSpec spec; |
FeedbackVectorSlot slot = spec.AddKeyedLoadICSlot(); |
+ // TODO(ishell): allocate this metadata only once. |
+ Handle<TypeFeedbackMetadata> feedback_metadata = |
+ TypeFeedbackMetadata::New(isolate, &spec); |
Handle<TypeFeedbackVector> feedback_vector = |
- TypeFeedbackVector::New(isolate, &spec); |
+ TypeFeedbackVector::New(isolate, feedback_metadata); |
DCHECK_EQ(PushAppliedArgumentsIndex(), feedback_vector->GetIndex(slot)); |
USE(slot); |
return feedback_vector; |
@@ -127,22 +186,6 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::Copy( |
} |
-bool TypeFeedbackVector::SpecDiffersFrom( |
- const FeedbackVectorSpec* other_spec) const { |
- if (other_spec->slots() != Slots()) { |
- return true; |
- } |
- |
- int slots = Slots(); |
- for (int i = 0; i < slots; i++) { |
- if (GetKind(FeedbackVectorSlot(i)) != other_spec->GetKind(i)) { |
- return true; |
- } |
- } |
- return false; |
-} |
- |
- |
// This logic is copied from |
// StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget. |
static bool ClearLogic(Isolate* isolate) { |
@@ -159,7 +202,7 @@ void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared, |
Object* uninitialized_sentinel = |
TypeFeedbackVector::RawUninitializedSentinel(isolate); |
- TypeFeedbackMetadataIterator iter(this); |
+ TypeFeedbackMetadataIterator iter(metadata()); |
while (iter.HasNext()) { |
FeedbackVectorSlot slot = iter.Next(); |
FeedbackVectorSlotKind kind = iter.kind(); |
@@ -236,7 +279,7 @@ void TypeFeedbackVector::ClearKeyedStoreICs(SharedFunctionInfo* shared) { |
Object* uninitialized_sentinel = |
TypeFeedbackVector::RawUninitializedSentinel(isolate); |
- TypeFeedbackMetadataIterator iter(this); |
+ TypeFeedbackMetadataIterator iter(metadata()); |
while (iter.HasNext()) { |
FeedbackVectorSlot slot = iter.Next(); |
FeedbackVectorSlotKind kind = iter.kind(); |
@@ -257,30 +300,6 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::DummyVector(Isolate* isolate) { |
} |
-const char* TypeFeedbackVector::Kind2String(FeedbackVectorSlotKind kind) { |
- switch (kind) { |
- case FeedbackVectorSlotKind::INVALID: |
- return "INVALID"; |
- case FeedbackVectorSlotKind::CALL_IC: |
- return "CALL_IC"; |
- case FeedbackVectorSlotKind::LOAD_IC: |
- return "LOAD_IC"; |
- case FeedbackVectorSlotKind::KEYED_LOAD_IC: |
- return "KEYED_LOAD_IC"; |
- case FeedbackVectorSlotKind::STORE_IC: |
- return "STORE_IC"; |
- case FeedbackVectorSlotKind::KEYED_STORE_IC: |
- return "KEYED_STORE_IC"; |
- case FeedbackVectorSlotKind::GENERAL: |
- return "STUB"; |
- case FeedbackVectorSlotKind::KINDS_NUMBER: |
- break; |
- } |
- UNREACHABLE(); |
- return "?"; |
-} |
- |
- |
Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) { |
Isolate* isolate = GetIsolate(); |
Handle<Object> feedback = handle(GetFeedback(), isolate); |