Index: src/type-feedback-vector.cc |
diff --git a/src/type-feedback-vector.cc b/src/type-feedback-vector.cc |
index ac584ad8a79dcbc42200258f8887f72f502b183a..c5d4a7a2fcbf142fc63c3ffa7ce4faeabee94c2e 100644 |
--- a/src/type-feedback-vector.cc |
+++ b/src/type-feedback-vector.cc |
@@ -37,6 +37,11 @@ FeedbackVectorSlotKind TypeFeedbackMetadata::GetKind( |
return VectorICComputer::decode(data, slot.ToInt()); |
} |
+int TypeFeedbackMetadata::GetParameter(int parameter_index) const { |
+ FixedArray* parameters = FixedArray::cast(get(kParametersTableIndex)); |
+ return Smi::cast(parameters->get(parameter_index))->value(); |
+} |
+ |
void TypeFeedbackMetadata::SetKind(FeedbackVectorSlot slot, |
FeedbackVectorSlotKind kind) { |
int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); |
@@ -91,6 +96,18 @@ Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New(Isolate* isolate, |
metadata->SetKind(FeedbackVectorSlot(i), kind); |
} |
+ if (spec->parameters_count() > 0) { |
+ const int parameters_count = spec->parameters_count(); |
+ Handle<FixedArray> params_array = |
+ factory->NewFixedArray(parameters_count, TENURED); |
+ for (int i = 0; i < parameters_count; i++) { |
+ params_array->set(i, Smi::FromInt(spec->GetParameter(i))); |
+ } |
+ metadata->set(kParametersTableIndex, *params_array); |
+ } else { |
+ metadata->set(kParametersTableIndex, *factory->empty_fixed_array()); |
+ } |
+ |
// It's important that the TypeFeedbackMetadata have a COW map, since it's |
// pointed to by both a SharedFunctionInfo and indirectly by closures through |
// the TypeFeedbackVector. The serializer uses the COW map type to decide |
@@ -109,6 +126,7 @@ bool TypeFeedbackMetadata::SpecDiffersFrom( |
} |
int slots = slot_count(); |
+ int parameter_index = 0; |
for (int i = 0; i < slots;) { |
FeedbackVectorSlot slot(i); |
FeedbackVectorSlotKind kind = GetKind(slot); |
@@ -117,6 +135,14 @@ bool TypeFeedbackMetadata::SpecDiffersFrom( |
if (kind != other_spec->GetKind(i)) { |
return true; |
} |
+ if (SlotRequiresParameter(kind)) { |
+ int parameter = GetParameter(parameter_index); |
+ int other_parameter = other_spec->GetParameter(parameter_index); |
+ if (parameter != other_parameter) { |
+ return true; |
+ } |
+ parameter_index++; |
+ } |
i += entry_size; |
} |
return false; |
@@ -129,6 +155,7 @@ bool TypeFeedbackMetadata::DiffersFrom( |
} |
int slots = slot_count(); |
+ int parameter_index = 0; |
for (int i = 0; i < slots;) { |
FeedbackVectorSlot slot(i); |
FeedbackVectorSlotKind kind = GetKind(slot); |
@@ -136,6 +163,13 @@ bool TypeFeedbackMetadata::DiffersFrom( |
if (GetKind(slot) != other_metadata->GetKind(slot)) { |
return true; |
} |
+ if (SlotRequiresParameter(kind)) { |
+ if (GetParameter(parameter_index) != |
+ other_metadata->GetParameter(parameter_index)) { |
+ return true; |
+ } |
+ parameter_index++; |
+ } |
i += entry_size; |
} |
return false; |
@@ -161,6 +195,8 @@ const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) { |
return "INTERPRETER_BINARYOP_IC"; |
case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC: |
return "INTERPRETER_COMPARE_IC"; |
+ case FeedbackVectorSlotKind::CREATE_CLOSURE: |
+ return "CREATE_CLOSURE"; |
case FeedbackVectorSlotKind::GENERAL: |
return "STUB"; |
case FeedbackVectorSlotKind::KINDS_NUMBER: |
@@ -176,6 +212,13 @@ FeedbackVectorSlotKind TypeFeedbackVector::GetKind( |
return metadata()->GetKind(slot); |
} |
+int TypeFeedbackVector::GetParameter(FeedbackVectorSlot slot) const { |
+ DCHECK(!is_empty()); |
+ DCHECK( |
+ TypeFeedbackMetadata::SlotRequiresParameter(metadata()->GetKind(slot))); |
+ return FixedArray::cast(Get(slot))->length(); |
+} |
+ |
// static |
Handle<TypeFeedbackVector> TypeFeedbackVector::New( |
Isolate* isolate, Handle<TypeFeedbackMetadata> metadata) { |
@@ -191,6 +234,27 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::New( |
Handle<FixedArray> array = factory->NewFixedArray(length, TENURED); |
array->set(kMetadataIndex, *metadata); |
array->set(kInvocationCountIndex, Smi::kZero); |
+ int parameter_index = 0; |
+ for (int i = 0; i < slot_count;) { |
+ FeedbackVectorSlot slot(i); |
+ FeedbackVectorSlotKind kind = metadata->GetKind(slot); |
+ int index = TypeFeedbackVector::GetIndex(slot); |
+ int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); |
+ |
+ if (kind == FeedbackVectorSlotKind::CREATE_CLOSURE) { |
+ // This fixed array is filled with undefined. |
+ int length = metadata->GetParameter(parameter_index++); |
+ if (length == 0) { |
+ // This is a native function literal. We can always point to |
+ // the empty literals array here. |
+ array->set(index, *factory->empty_literals_array(), SKIP_WRITE_BARRIER); |
+ } else { |
+ Handle<FixedArray> value = factory->NewFixedArray(length); |
+ array->set(index, *value); |
+ } |
+ } |
+ i += entry_size; |
+ } |
DisallowHeapAllocation no_gc; |
@@ -212,12 +276,14 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::New( |
} else { |
value = *uninitialized_sentinel; |
} |
- array->set(index, value, SKIP_WRITE_BARRIER); |
- value = kind == FeedbackVectorSlotKind::CALL_IC ? Smi::kZero |
- : *uninitialized_sentinel; |
- for (int j = 1; j < entry_size; j++) { |
- array->set(index + j, value, SKIP_WRITE_BARRIER); |
+ if (kind != FeedbackVectorSlotKind::CREATE_CLOSURE) { |
+ array->set(index, value, SKIP_WRITE_BARRIER); |
+ value = kind == FeedbackVectorSlotKind::CALL_IC ? Smi::kZero |
+ : *uninitialized_sentinel; |
+ for (int j = 1; j < entry_size; j++) { |
+ array->set(index + j, value, SKIP_WRITE_BARRIER); |
+ } |
} |
i += entry_size; |
} |
@@ -252,9 +318,10 @@ static bool ClearLogic(Isolate* isolate) { |
void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared, |
bool force_clear) { |
Isolate* isolate = GetIsolate(); |
- |
if (!force_clear && !ClearLogic(isolate)) return; |
+ if (this == isolate->heap()->empty_type_feedback_vector()) return; |
+ |
Object* uninitialized_sentinel = |
TypeFeedbackVector::RawUninitializedSentinel(isolate); |
@@ -303,6 +370,14 @@ void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared, |
// Set(slot, Smi::kZero); |
break; |
} |
+ case FeedbackVectorSlotKind::CREATE_CLOSURE: { |
+ // Fill the array with undefined. |
+ FixedArray* array = FixedArray::cast(Get(slot)); |
+ for (int i = 0; i < array->length(); i++) { |
+ array->set_undefined(i); |
+ } |
+ break; |
+ } |
case FeedbackVectorSlotKind::GENERAL: { |
if (obj->IsHeapObject()) { |
InstanceType instance_type = |