Chromium Code Reviews| Index: src/type-feedback-vector.cc |
| diff --git a/src/type-feedback-vector.cc b/src/type-feedback-vector.cc |
| index a48fcec7f9317cfdcdef9c6737a66bfa7d50c5ed..134a22acf5bf35c8d4074b9a43372c4a2f8e9321 100644 |
| --- a/src/type-feedback-vector.cc |
| +++ b/src/type-feedback-vector.cc |
| @@ -4,6 +4,7 @@ |
| #include "src/v8.h" |
| +#include "src/ic/ic.h" |
| #include "src/ic/ic-state.h" |
| #include "src/objects.h" |
| #include "src/type-feedback-vector-inl.h" |
| @@ -145,9 +146,140 @@ void TypeFeedbackVector::ClearSlots(SharedFunctionInfo* shared) { |
| FeedbackVectorICSlot slot(i); |
| Object* obj = Get(slot); |
| if (obj != uninitialized_sentinel) { |
| - ICUtility::Clear(isolate, Code::CALL_IC, host, this, slot); |
| + // TODO(mvstanton): To make this code work with --vector-ics, |
| + // additional Nexus types must be created. |
| + DCHECK(!FLAG_vector_ics); |
| + DCHECK(GetKind(slot) == Code::CALL_IC); |
| + CallICNexus nexus(this, slot); |
| + ICUtility::Clear(isolate, Code::CALL_IC, host, &nexus); |
| } |
| } |
| } |
| + |
| + |
| +Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) { |
| + Isolate* isolate = GetIsolate(); |
| + Handle<Object> feedback = handle(GetFeedback(), isolate); |
| + if (!feedback->IsFixedArray() || |
| + FixedArray::cast(*feedback)->length() != length) { |
|
Igor Sheludko
2014/10/28 11:12:36
Do we need to allocate another array if existing o
mvstanton
2014/10/28 13:23:28
Hmm, the only case that would happen would be if t
|
| + Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); |
| + SetFeedback(*array); |
| + return array; |
| + } |
| + return Handle<FixedArray>::cast(feedback); |
| +} |
| + |
| + |
| +void FeedbackNexus::InstallHandlers(int start_index, TypeHandleList* types, |
| + CodeHandleList* handlers) { |
| + Isolate* isolate = GetIsolate(); |
| + FixedArray* array = FixedArray::cast(GetFeedback()); |
| + int receiver_count = types->length(); |
| + for (int current = 0; current < receiver_count; ++current) { |
| + Handle<HeapType> type = types->at(current); |
| + Handle<Map> map = IC::TypeToMap(*type, isolate); |
| + array->set(start_index + (current * 2), *map); |
| + array->set(start_index + (current * 2 + 1), *handlers->at(current)); |
| + } |
| +} |
| + |
| + |
| +InlineCacheState CallICNexus::StateFromFeedback() const { |
| + Isolate* isolate = GetIsolate(); |
| + InlineCacheState state = UNINITIALIZED; |
| + Object* feedback = GetFeedback(); |
| + |
| + if (feedback == *vector()->MegamorphicSentinel(isolate)) { |
| + state = GENERIC; |
| + } else if (feedback->IsAllocationSite() || feedback->IsJSFunction()) { |
| + state = MONOMORPHIC; |
| + } else { |
| + CHECK(feedback == *vector()->UninitializedSentinel(isolate)); |
| + } |
| + |
| + return state; |
| +} |
| + |
| + |
| +void CallICNexus::ConfigureGeneric() { |
| + SetFeedback(*vector()->MegamorphicSentinel(GetIsolate())); |
| +} |
| + |
| + |
| +void CallICNexus::ConfigureMonomorphicArray() { |
| + Object* feedback = GetFeedback(); |
| + if (!feedback->IsAllocationSite()) { |
| + Handle<AllocationSite> new_site = |
| + GetIsolate()->factory()->NewAllocationSite(); |
| + SetFeedback(*new_site); |
| + } |
| +} |
| + |
| + |
| +void CallICNexus::ConfigureUninitialized() { |
| + SetFeedback(*vector()->UninitializedSentinel(GetIsolate())); |
| +} |
| + |
| + |
| +void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) { |
| + SetFeedback(*function); |
| +} |
| + |
|
Igor Sheludko
2014/10/28 11:12:36
Empty line is missing.
mvstanton
2014/10/28 13:23:28
Done.
|
| +int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const { |
| + Isolate* isolate = GetIsolate(); |
| + Object* feedback = GetFeedback(); |
| + if (feedback->IsFixedArray()) { |
| + FixedArray* array = FixedArray::cast(feedback); |
| + // The array should be of the form [<optional name>], then |
| + // [map, handler, map, handler, ... ] |
| + DCHECK(array->length() >= (2 + start_index)); |
| + for (int i = start_index; i < array->length(); i += 2) { |
| + Map* map = Map::cast(array->get(i)); |
| + maps->Add(handle(map, isolate)); |
| + } |
| + return (array->length() - start_index) / 2; |
| + } |
| + |
| + return 0; |
| +} |
| + |
| + |
| +MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(int start_index, |
| + Handle<Map> map) const { |
| + Object* feedback = GetFeedback(); |
| + if (feedback->IsFixedArray()) { |
| + FixedArray* array = FixedArray::cast(feedback); |
| + for (int i = start_index; i < array->length(); i += 2) { |
| + Map* array_map = Map::cast(array->get(i)); |
| + if (array_map == *map) { |
| + Code* code = Code::cast(array->get(i + 1)); |
| + DCHECK(code->kind() == Code::HANDLER); |
| + return handle(code); |
| + } |
| + } |
| + } |
| + |
| + return MaybeHandle<Code>(); |
| +} |
| + |
| + |
| +bool FeedbackNexus::FindHandlers(int start_index, CodeHandleList* code_list, |
| + int length) const { |
| + Object* feedback = GetFeedback(); |
| + int count = 0; |
| + if (feedback->IsFixedArray()) { |
| + FixedArray* array = FixedArray::cast(feedback); |
| + // The array should be of the form [<optional name>], then |
| + // [map, handler, map, handler, ... ] |
| + DCHECK(array->length() >= (2 + start_index)); |
| + for (int i = start_index; i < array->length(); i += 2) { |
| + Code* code = Code::cast(array->get(i + 1)); |
| + DCHECK(code->kind() == Code::HANDLER); |
| + code_list->Add(handle(code)); |
| + count++; |
| + } |
| + } |
| + return count == length; |
| +} |
| } |
| } // namespace v8::internal |