Index: src/transitions.cc |
diff --git a/src/transitions.cc b/src/transitions.cc |
index 96ed870e07b43465bccef7b29abe24b7305f246e..56d9bf760d95acd0bd22e64cb1858ee1ffd4da20 100644 |
--- a/src/transitions.cc |
+++ b/src/transitions.cc |
@@ -96,7 +96,16 @@ Handle<TransitionArray> TransitionArray::CopyInsert(Handle<Map> map, |
int number_of_transitions = map->transitions()->number_of_transitions(); |
int new_size = number_of_transitions; |
- int insertion_index = map->transitions()->Search(*name); |
+ bool is_special_transition = IsSpecialTransition(*name); |
+ PropertyDetails details = is_special_transition |
+ ? PropertyDetails(NONE, NORMAL, 0) |
+ : GetTargetDetails(*name, *target); |
+ |
+ int insertion_index = |
+ is_special_transition |
+ ? map->transitions()->SearchSpecial(Symbol::cast(*name)) |
+ : map->transitions()->Search(details.type(), *name, |
+ details.attributes()); |
if (insertion_index == kNotFound) ++new_size; |
Handle<TransitionArray> result = Allocate(map->GetIsolate(), new_size); |
@@ -113,7 +122,11 @@ Handle<TransitionArray> TransitionArray::CopyInsert(Handle<Map> map, |
number_of_transitions = array->number_of_transitions(); |
new_size = number_of_transitions; |
- insertion_index = array->Search(*name); |
+ insertion_index = |
+ is_special_transition |
+ ? map->transitions()->SearchSpecial(Symbol::cast(*name)) |
+ : map->transitions()->Search(details.type(), *name, |
+ details.attributes()); |
if (insertion_index == kNotFound) ++new_size; |
result->Shrink(ToKeyIndex(new_size)); |
@@ -129,6 +142,9 @@ Handle<TransitionArray> TransitionArray::CopyInsert(Handle<Map> map, |
result->NoIncrementalWriteBarrierCopyFrom(array, i, i); |
} |
} |
+ |
+ DCHECK_NE(map->instance_descriptors(), |
+ array->GetTarget(insertion_index)->instance_descriptors()); |
result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target); |
result->set_back_pointer_storage(array->back_pointer_storage()); |
return result; |
@@ -153,4 +169,35 @@ Handle<TransitionArray> TransitionArray::CopyInsert(Handle<Map> map, |
} |
+int TransitionArray::SearchNext(int transition, PropertyType type, Name* name, |
+ PropertyAttributes attributes) { |
+ int nof_transitions = number_of_transitions(); |
+ bool is_data = type == FIELD || type == CONSTANT; |
+ for (;;) { |
+ Map* target = GetTarget(transition); |
+ PropertyDetails target_details = GetTargetDetails(name, target); |
+ bool target_is_data = |
+ target_details.type() == FIELD || target_details.type() == CONSTANT; |
+ |
+ if (target_is_data == is_data && |
+ target_details.attributes() == attributes) { |
+ return transition; |
+ } |
+ transition++; |
+ if ((transition >= nof_transitions) || !GetKey(transition)->Equals(name)) { |
+ break; |
+ } |
+ } |
+ return kNotFound; |
+} |
+ |
+ |
+int TransitionArray::Search(PropertyType type, Name* name, |
+ PropertyAttributes attributes) { |
+ int transition = SearchFirst(name); |
+ if (transition == kNotFound) { |
+ return kNotFound; |
+ } |
+ return SearchNext(transition, type, name, attributes); |
+} |
} } // namespace v8::internal |