Index: src/transitions.cc |
diff --git a/src/transitions.cc b/src/transitions.cc |
index ec1b7f4fc991f4d91ac2ce1c9fc04af7d24cd6e1..df463a305b2405ecaf890992b903eef60f74e3f0 100644 |
--- a/src/transitions.cc |
+++ b/src/transitions.cc |
@@ -48,7 +48,7 @@ Handle<TransitionArray> TransitionArray::NewWith(Handle<Map> map, |
Handle<TransitionArray> result; |
Isolate* isolate = name->GetIsolate(); |
- if (flag == SIMPLE_TRANSITION) { |
+ if (flag == SIMPLE_PROPERTY_TRANSITION) { |
result = AllocateSimple(isolate, target); |
} else { |
result = Allocate(isolate, 1); |
@@ -94,9 +94,19 @@ Handle<TransitionArray> TransitionArray::Insert(Handle<Map> map, |
int number_of_transitions = map->transitions()->number_of_transitions(); |
int new_nof = number_of_transitions; |
- int insertion_index = kNotFound; |
- int index = map->transitions()->Search(*name, &insertion_index); |
+ bool is_special_transition = flag == SPECIAL_TRANSITION; |
+ DCHECK_EQ(is_special_transition, IsSpecialTransition(*name)); |
+ PropertyDetails details = is_special_transition |
+ ? PropertyDetails(NONE, FIELD, 0) |
+ : GetTargetDetails(*name, *target); |
+ int insertion_index = kNotFound; |
+ int index = |
+ is_special_transition |
+ ? map->transitions()->SearchSpecial(Symbol::cast(*name), |
+ &insertion_index) |
+ : map->transitions()->Search(details.type(), *name, |
+ details.attributes(), &insertion_index); |
if (index == kNotFound) { |
++new_nof; |
} else { |
@@ -118,12 +128,12 @@ Handle<TransitionArray> TransitionArray::Insert(Handle<Map> map, |
array->SetNumberOfTransitions(new_nof); |
for (index = number_of_transitions; index > insertion_index; --index) { |
Name* key = array->GetKey(index - 1); |
- DCHECK(key->Hash() > name->Hash()); |
array->SetKey(index, key); |
array->SetTarget(index, array->GetTarget(index - 1)); |
} |
array->SetKey(index, *name); |
array->SetTarget(index, *target); |
+ SLOW_DCHECK(array->IsSortedNoDuplicates()); |
return handle(array); |
} |
@@ -144,7 +154,11 @@ Handle<TransitionArray> TransitionArray::Insert(Handle<Map> map, |
new_nof = number_of_transitions; |
insertion_index = kNotFound; |
- index = array->Search(*name, &insertion_index); |
+ index = is_special_transition ? map->transitions()->SearchSpecial( |
+ Symbol::cast(*name), &insertion_index) |
+ : map->transitions()->Search( |
+ details.type(), *name, |
+ details.attributes(), &insertion_index); |
if (index == kNotFound) { |
++new_nof; |
} else { |
@@ -170,8 +184,46 @@ Handle<TransitionArray> TransitionArray::Insert(Handle<Map> map, |
} |
result->set_back_pointer_storage(array->back_pointer_storage()); |
+ SLOW_DCHECK(result->IsSortedNoDuplicates()); |
return result; |
} |
+int TransitionArray::SearchDetails(int transition, PropertyType type, |
+ PropertyAttributes attributes, |
+ int* out_insertion_index) { |
+ int nof_transitions = number_of_transitions(); |
+ DCHECK(transition < nof_transitions); |
+ Name* key = GetKey(transition); |
+ bool is_data = type == FIELD || type == CONSTANT; |
+ for (; transition < nof_transitions && GetKey(transition) == key; |
+ transition++) { |
+ Map* target = GetTarget(transition); |
+ PropertyDetails target_details = GetTargetDetails(key, target); |
+ |
+ bool target_is_data = |
+ target_details.type() == FIELD || target_details.type() == CONSTANT; |
+ |
+ int cmp = CompareDetails(is_data, attributes, target_is_data, |
+ target_details.attributes()); |
+ if (cmp == 0) { |
+ return transition; |
+ } else if (cmp < 0) { |
+ break; |
+ } |
+ } |
+ if (out_insertion_index != NULL) *out_insertion_index = transition; |
+ return kNotFound; |
+} |
+ |
+ |
+int TransitionArray::Search(PropertyType type, Name* name, |
+ PropertyAttributes attributes, |
+ int* out_insertion_index) { |
+ int transition = SearchName(name, out_insertion_index); |
+ if (transition == kNotFound) { |
+ return kNotFound; |
+ } |
+ return SearchDetails(transition, type, attributes, out_insertion_index); |
+} |
} } // namespace v8::internal |