diff options
Diffstat (limited to 'deps/v8/src/type-feedback-vector.cc')
-rw-r--r-- | deps/v8/src/type-feedback-vector.cc | 224 |
1 files changed, 134 insertions, 90 deletions
diff --git a/deps/v8/src/type-feedback-vector.cc b/deps/v8/src/type-feedback-vector.cc index b0be315b2b..6653bea0ee 100644 --- a/deps/v8/src/type-feedback-vector.cc +++ b/deps/v8/src/type-feedback-vector.cc @@ -75,15 +75,22 @@ void TypeFeedbackVector::SetKind(FeedbackVectorICSlot slot, Code::Kind kind) { } +template Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate( + Isolate* isolate, const FeedbackVectorSpec* spec); +template Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate( + Isolate* isolate, const ZoneFeedbackVectorSpec* spec); + + // static -Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate( - Isolate* isolate, const FeedbackVectorSpec& spec) { - const int slot_count = spec.slots(); - const int ic_slot_count = spec.ic_slots(); +template <typename Spec> +Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(Isolate* isolate, + const Spec* spec) { + const int slot_count = spec->slots(); + const int ic_slot_count = spec->ic_slots(); const int index_count = FLAG_vector_ics ? VectorICComputer::word_count(ic_slot_count) : 0; - const int length = - slot_count + ic_slot_count + index_count + kReservedIndexCount; + const int length = slot_count + (ic_slot_count * elements_per_ic_slot()) + + index_count + kReservedIndexCount; if (length == kReservedIndexCount) { return Handle<TypeFeedbackVector>::cast( isolate->factory()->empty_fixed_array()); @@ -113,7 +120,7 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate( Handle<TypeFeedbackVector> vector = Handle<TypeFeedbackVector>::cast(array); if (FLAG_vector_ics) { for (int i = 0; i < ic_slot_count; i++) { - vector->SetKind(FeedbackVectorICSlot(i), spec.GetKind(i)); + vector->SetKind(FeedbackVectorICSlot(i), spec->GetKind(i)); } } return vector; @@ -207,16 +214,28 @@ Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) { } -void FeedbackNexus::InstallHandlers(int start_index, MapHandleList* maps, - CodeHandleList* handlers) { +Handle<FixedArray> FeedbackNexus::EnsureExtraArrayOfSize(int length) { Isolate* isolate = GetIsolate(); - Handle<FixedArray> array = handle(FixedArray::cast(GetFeedback()), isolate); + Handle<Object> feedback_extra = handle(GetFeedbackExtra(), isolate); + if (!feedback_extra->IsFixedArray() || + FixedArray::cast(*feedback_extra)->length() != length) { + Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); + SetFeedbackExtra(*array); + return array; + } + return Handle<FixedArray>::cast(feedback_extra); +} + + +void FeedbackNexus::InstallHandlers(Handle<FixedArray> array, + MapHandleList* maps, + CodeHandleList* handlers) { int receiver_count = maps->length(); for (int current = 0; current < receiver_count; ++current) { Handle<Map> map = maps->at(current); Handle<WeakCell> cell = Map::WeakCellForMap(map); - array->set(start_index + (current * 2), *cell); - array->set(start_index + (current * 2 + 1), *handlers->at(current)); + array->set(current * 2, *cell); + array->set(current * 2 + 1, *handlers->at(current)); } } @@ -224,6 +243,7 @@ void FeedbackNexus::InstallHandlers(int start_index, MapHandleList* maps, InlineCacheState LoadICNexus::StateFromFeedback() const { Isolate* isolate = GetIsolate(); Object* feedback = GetFeedback(); + if (feedback == *vector()->UninitializedSentinel(isolate)) { return UNINITIALIZED; } else if (feedback == *vector()->MegamorphicSentinel(isolate)) { @@ -233,10 +253,10 @@ InlineCacheState LoadICNexus::StateFromFeedback() const { } else if (feedback->IsFixedArray()) { // Determine state purely by our structure, don't check if the maps are // cleared. - FixedArray* array = FixedArray::cast(feedback); - int length = array->length(); - DCHECK(length >= 2); - return length == 2 ? MONOMORPHIC : POLYMORPHIC; + return POLYMORPHIC; + } else if (feedback->IsWeakCell()) { + // Don't check if the map is cleared. + return MONOMORPHIC; } return UNINITIALIZED; @@ -246,6 +266,7 @@ InlineCacheState LoadICNexus::StateFromFeedback() const { InlineCacheState KeyedLoadICNexus::StateFromFeedback() const { Isolate* isolate = GetIsolate(); Object* feedback = GetFeedback(); + if (feedback == *vector()->UninitializedSentinel(isolate)) { return UNINITIALIZED; } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) { @@ -255,10 +276,14 @@ InlineCacheState KeyedLoadICNexus::StateFromFeedback() const { } else if (feedback->IsFixedArray()) { // Determine state purely by our structure, don't check if the maps are // cleared. - FixedArray* array = FixedArray::cast(feedback); - int length = array->length(); - DCHECK(length >= 3); - return length == 3 ? MONOMORPHIC : POLYMORPHIC; + return POLYMORPHIC; + } else if (feedback->IsWeakCell()) { + // Don't check if the map is cleared. + return MONOMORPHIC; + } else if (feedback->IsName()) { + Object* extra = GetFeedbackExtra(); + FixedArray* extra_array = FixedArray::cast(extra); + return extra_array->length() > 2 ? POLYMORPHIC : MONOMORPHIC; } return UNINITIALIZED; @@ -268,6 +293,8 @@ InlineCacheState KeyedLoadICNexus::StateFromFeedback() const { InlineCacheState CallICNexus::StateFromFeedback() const { Isolate* isolate = GetIsolate(); Object* feedback = GetFeedback(); + DCHECK(!FLAG_vector_ics || + GetFeedbackExtra() == *vector()->UninitializedSentinel(isolate)); if (feedback == *vector()->MegamorphicSentinel(isolate)) { return GENERIC; @@ -311,56 +338,68 @@ void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) { void KeyedLoadICNexus::ConfigureMegamorphic() { - SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER); + Isolate* isolate = GetIsolate(); + SetFeedback(*vector()->MegamorphicSentinel(isolate), SKIP_WRITE_BARRIER); + SetFeedbackExtra(*vector()->UninitializedSentinel(isolate), + SKIP_WRITE_BARRIER); } void LoadICNexus::ConfigureMegamorphic() { SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER); + SetFeedbackExtra(*vector()->UninitializedSentinel(GetIsolate()), + SKIP_WRITE_BARRIER); } void LoadICNexus::ConfigurePremonomorphic() { SetFeedback(*vector()->PremonomorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER); + SetFeedbackExtra(*vector()->UninitializedSentinel(GetIsolate()), + SKIP_WRITE_BARRIER); } void KeyedLoadICNexus::ConfigurePremonomorphic() { - SetFeedback(*vector()->PremonomorphicSentinel(GetIsolate()), - SKIP_WRITE_BARRIER); + Isolate* isolate = GetIsolate(); + SetFeedback(*vector()->PremonomorphicSentinel(isolate), SKIP_WRITE_BARRIER); + SetFeedbackExtra(*vector()->UninitializedSentinel(isolate), + SKIP_WRITE_BARRIER); } void LoadICNexus::ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Code> handler) { - Handle<FixedArray> array = EnsureArrayOfSize(2); Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); - array->set(0, *cell); - array->set(1, *handler); + SetFeedback(*cell); + SetFeedbackExtra(*handler); } void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map, Handle<Code> handler) { - Handle<FixedArray> array = EnsureArrayOfSize(3); + Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); if (name.is_null()) { - array->set(0, Smi::FromInt(0)); + SetFeedback(*cell); + SetFeedbackExtra(*handler); } else { - array->set(0, *name); + SetFeedback(*name); + Handle<FixedArray> array = EnsureExtraArrayOfSize(2); + array->set(0, *cell); + array->set(1, *handler); } - Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); - array->set(1, *cell); - array->set(2, *handler); } void LoadICNexus::ConfigurePolymorphic(MapHandleList* maps, CodeHandleList* handlers) { + Isolate* isolate = GetIsolate(); int receiver_count = maps->length(); - EnsureArrayOfSize(receiver_count * 2); - InstallHandlers(0, maps, handlers); + Handle<FixedArray> array = EnsureArrayOfSize(receiver_count * 2); + InstallHandlers(array, maps, handlers); + SetFeedbackExtra(*vector()->UninitializedSentinel(isolate), + SKIP_WRITE_BARRIER); } @@ -368,26 +407,35 @@ void KeyedLoadICNexus::ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps, CodeHandleList* handlers) { int receiver_count = maps->length(); - Handle<FixedArray> array = EnsureArrayOfSize(1 + receiver_count * 2); + DCHECK(receiver_count > 1); + Handle<FixedArray> array; if (name.is_null()) { - array->set(0, Smi::FromInt(0)); + array = EnsureArrayOfSize(receiver_count * 2); + SetFeedbackExtra(*vector()->UninitializedSentinel(GetIsolate()), + SKIP_WRITE_BARRIER); } else { - array->set(0, *name); + SetFeedback(*name); + array = EnsureExtraArrayOfSize(receiver_count * 2); } - InstallHandlers(1, maps, handlers); + + InstallHandlers(array, maps, handlers); } -int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const { +int FeedbackNexus::ExtractMaps(MapHandleList* maps) const { Isolate* isolate = GetIsolate(); Object* feedback = GetFeedback(); - if (feedback->IsFixedArray()) { + if (feedback->IsFixedArray() || feedback->IsString()) { int found = 0; + if (feedback->IsString()) { + feedback = GetFeedbackExtra(); + } 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) { + DCHECK(array->length() >= 2); + for (int i = 0; i < array->length(); i += 2) { + DCHECK(array->get(i)->IsWeakCell()); WeakCell* cell = WeakCell::cast(array->get(i)); if (!cell->cleared()) { Map* map = Map::cast(cell->value()); @@ -396,18 +444,28 @@ int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const { } } return found; + } else if (feedback->IsWeakCell()) { + WeakCell* cell = WeakCell::cast(feedback); + if (!cell->cleared()) { + Map* map = Map::cast(cell->value()); + maps->Add(handle(map, isolate)); + return 1; + } } return 0; } -MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(int start_index, - Handle<Map> map) const { +MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const { Object* feedback = GetFeedback(); - if (feedback->IsFixedArray()) { + if (feedback->IsFixedArray() || feedback->IsString()) { + if (feedback->IsString()) { + feedback = GetFeedbackExtra(); + } FixedArray* array = FixedArray::cast(feedback); - for (int i = start_index; i < array->length(); i += 2) { + for (int i = 0; i < array->length(); i += 2) { + DCHECK(array->get(i)->IsWeakCell()); WeakCell* cell = WeakCell::cast(array->get(i)); if (!cell->cleared()) { Map* array_map = Map::cast(cell->value()); @@ -418,23 +476,35 @@ MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(int start_index, } } } + } else if (feedback->IsWeakCell()) { + WeakCell* cell = WeakCell::cast(feedback); + if (!cell->cleared()) { + Map* cell_map = Map::cast(cell->value()); + if (cell_map == *map) { + Code* code = Code::cast(GetFeedbackExtra()); + DCHECK(code->kind() == Code::HANDLER); + return handle(code); + } + } } return MaybeHandle<Code>(); } -bool FeedbackNexus::FindHandlers(int start_index, CodeHandleList* code_list, - int length) const { +bool FeedbackNexus::FindHandlers(CodeHandleList* code_list, int length) const { Object* feedback = GetFeedback(); int count = 0; - if (feedback->IsFixedArray()) { + if (feedback->IsFixedArray() || feedback->IsString()) { + if (feedback->IsString()) { + feedback = GetFeedbackExtra(); + } FixedArray* array = FixedArray::cast(feedback); - // The array should be of the form [<optional name>], then - // [map, handler, map, handler, ... ]. Be sure to skip handlers whose maps - // have been cleared. - DCHECK(array->length() >= (2 + start_index)); - for (int i = start_index; i < array->length(); i += 2) { + // The array should be of the form [map, handler, map, handler, ... ]. + // Be sure to skip handlers whose maps have been cleared. + DCHECK(array->length() >= 2); + for (int i = 0; i < array->length(); i += 2) { + DCHECK(array->get(i)->IsWeakCell()); WeakCell* cell = WeakCell::cast(array->get(i)); if (!cell->cleared()) { Code* code = Code::cast(array->get(i + 1)); @@ -443,16 +513,19 @@ bool FeedbackNexus::FindHandlers(int start_index, CodeHandleList* code_list, count++; } } + } else if (feedback->IsWeakCell()) { + WeakCell* cell = WeakCell::cast(feedback); + if (!cell->cleared()) { + Code* code = Code::cast(GetFeedbackExtra()); + DCHECK(code->kind() == Code::HANDLER); + code_list->Add(handle(code)); + count++; + } } return count == length; } -int LoadICNexus::ExtractMaps(MapHandleList* maps) const { - return FeedbackNexus::ExtractMaps(0, maps); -} - - void LoadICNexus::Clear(Code* host) { LoadIC::Clear(GetIsolate(), host, this); } @@ -461,39 +534,10 @@ void KeyedLoadICNexus::Clear(Code* host) { } -int KeyedLoadICNexus::ExtractMaps(MapHandleList* maps) const { - return FeedbackNexus::ExtractMaps(1, maps); -} - - -MaybeHandle<Code> LoadICNexus::FindHandlerForMap(Handle<Map> map) const { - return FeedbackNexus::FindHandlerForMap(0, map); -} - - -MaybeHandle<Code> KeyedLoadICNexus::FindHandlerForMap(Handle<Map> map) const { - return FeedbackNexus::FindHandlerForMap(1, map); -} - - -bool LoadICNexus::FindHandlers(CodeHandleList* code_list, int length) const { - return FeedbackNexus::FindHandlers(0, code_list, length); -} - - -bool KeyedLoadICNexus::FindHandlers(CodeHandleList* code_list, - int length) const { - return FeedbackNexus::FindHandlers(1, code_list, length); -} - - Name* KeyedLoadICNexus::FindFirstName() const { Object* feedback = GetFeedback(); - if (feedback->IsFixedArray()) { - FixedArray* array = FixedArray::cast(feedback); - DCHECK(array->length() >= 3); - Object* name = array->get(0); - if (name->IsName()) return Name::cast(name); + if (feedback->IsString()) { + return Name::cast(feedback); } return NULL; } |