| Index: src/type-feedback-vector.cc
|
| diff --git a/src/type-feedback-vector.cc b/src/type-feedback-vector.cc
|
| index b0be315b2b612bfd3733da6f6f0efbb236d68363..371a309ea7b0115cba18163774e5e7d5ca4b8050 100644
|
| --- a/src/type-feedback-vector.cc
|
| +++ b/src/type-feedback-vector.cc
|
| @@ -82,8 +82,8 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(
|
| 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());
|
| @@ -207,16 +207,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 +236,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 +246,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 +259,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 +269,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 +286,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 +331,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 +400,34 @@ 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) {
|
| WeakCell* cell = WeakCell::cast(array->get(i));
|
| if (!cell->cleared()) {
|
| Map* map = Map::cast(cell->value());
|
| @@ -396,18 +436,27 @@ 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) {
|
| WeakCell* cell = WeakCell::cast(array->get(i));
|
| if (!cell->cleared()) {
|
| Map* array_map = Map::cast(cell->value());
|
| @@ -418,23 +467,34 @@ 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) {
|
| WeakCell* cell = WeakCell::cast(array->get(i));
|
| if (!cell->cleared()) {
|
| Code* code = Code::cast(array->get(i + 1));
|
| @@ -443,16 +503,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 +524,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;
|
| }
|
|
|