From: ishell@chromium.org Date: Thu, 13 Nov 2014 15:30:53 +0000 (+0100) Subject: Revert "TransitionArray now uses tuple as a... X-Git-Tag: upstream/4.7.83~5708 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2e38f3391116d87ec3745982b24a0279dcefe2d7;p=platform%2Fupstream%2Fv8.git Revert "TransitionArray now uses tuple as a key, which allows to have several entries for the same property name." Revert "Fix for an assertion failure in Map::FindTransitionToField(...). Appeared after r25136." This revert is made in order to revert r25099 which potentially causes renderer hangs. R=verwaest@chromium.org Review URL: https://codereview.chromium.org/722873004 Cr-Commit-Position: refs/heads/master@{#25332} --- diff --git a/src/globals.h b/src/globals.h index 414ff9b62..1de3f0f1b 100644 --- a/src/globals.h +++ b/src/globals.h @@ -361,7 +361,6 @@ template class String; class Name; class Struct; -class Symbol; class Variable; class RelocInfo; class Deserializer; diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 388f63fe2..a79219c5b 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -6154,7 +6154,7 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() { if (IsAccessor()) return true; Handle map = this->map(); - map->LookupTransition(NULL, *name_, NONE, &lookup_); + map->LookupTransition(NULL, *name_, &lookup_); if (lookup_.IsTransitionToField() && map->unused_property_fields() > 0) { // Construct the object field access. int descriptor = transition()->LastAdded(); diff --git a/src/objects-debug.cc b/src/objects-debug.cc index 949572065..0e670993e 100644 --- a/src/objects-debug.cc +++ b/src/objects-debug.cc @@ -1169,13 +1169,15 @@ bool DescriptorArray::IsSortedNoDuplicates(int valid_entries) { for (int i = 0; i < number_of_descriptors(); i++) { Name* key = GetSortedKey(i); if (key == current_key) { - Print(); + OFStream os(stdout); + PrintDescriptors(os); return false; } current_key = key; uint32_t hash = GetSortedKey(i)->Hash(); if (hash < current) { - Print(); + OFStream os(stdout); + PrintDescriptors(os); return false; } current = hash; @@ -1207,36 +1209,23 @@ bool LayoutDescriptor::IsConsistentWithMap(Map* map) { bool TransitionArray::IsSortedNoDuplicates(int valid_entries) { DCHECK(valid_entries == -1); - Name* prev_key = NULL; - bool prev_is_data_property = false; - PropertyAttributes prev_attributes = NONE; - uint32_t prev_hash = 0; + Name* current_key = NULL; + uint32_t current = 0; for (int i = 0; i < number_of_transitions(); i++) { Name* key = GetSortedKey(i); - uint32_t hash = key->Hash(); - bool is_data_property = false; - PropertyAttributes attributes = NONE; - if (!IsSpecialTransition(key)) { - Map* target = GetTarget(i); - PropertyDetails details = GetTargetDetails(key, target); - is_data_property = details.type() == FIELD || details.type() == CONSTANT; - attributes = details.attributes(); - } else { - // Duplicate entries are not allowed for non-property transitions. - CHECK_NE(prev_key, key); + if (key == current_key) { + OFStream os(stdout); + PrintTransitions(os); + return false; } - - int cmp = - CompareKeys(prev_key, prev_hash, prev_is_data_property, prev_attributes, - key, hash, is_data_property, attributes); - if (cmp >= 0) { - Print(); + current_key = key; + uint32_t hash = GetSortedKey(i)->Hash(); + if (hash < current) { + OFStream os(stdout); + PrintTransitions(os); return false; } - prev_key = key; - prev_hash = hash; - prev_attributes = attributes; - prev_is_data_property = is_data_property; + current = hash; } return true; } diff --git a/src/objects-inl.h b/src/objects-inl.h index 3300df077..c741ce34e 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -1901,11 +1901,11 @@ Handle Map::FindTransitionToField(Handle map, Handle key) { DisallowHeapAllocation no_allocation; if (!map->HasTransitionArray()) return Handle::null(); TransitionArray* transitions = map->transitions(); - int transition = transitions->Search(FIELD, *key, NONE); + int transition = transitions->Search(*key); if (transition == TransitionArray::kNotFound) return Handle::null(); - PropertyDetails details = transitions->GetTargetDetails(transition); - if (details.type() != FIELD) return Handle::null(); - DCHECK_EQ(NONE, details.attributes()); + PropertyDetails target_details = transitions->GetTargetDetails(transition); + if (target_details.type() != FIELD) return Handle::null(); + if (target_details.attributes() != NONE) return Handle::null(); return Handle(transitions->GetTarget(transition)); } @@ -2995,10 +2995,8 @@ void Map::LookupDescriptor(JSObject* holder, } -void Map::LookupTransition(JSObject* holder, Name* name, - PropertyAttributes attributes, - LookupResult* result) { - int transition_index = this->SearchTransition(FIELD, name, attributes); +void Map::LookupTransition(JSObject* holder, Name* name, LookupResult* result) { + int transition_index = this->SearchTransition(name); if (transition_index == TransitionArray::kNotFound) return result->NotFound(); result->TransitionResult(holder, this->GetTransition(transition_index)); } @@ -5320,8 +5318,7 @@ bool Map::HasTransitionArray() const { Map* Map::elements_transition_map() { - int index = - transitions()->SearchSpecial(GetHeap()->elements_transition_symbol()); + int index = transitions()->Search(GetHeap()->elements_transition_symbol()); return transitions()->GetTarget(index); } @@ -5338,19 +5335,8 @@ Map* Map::GetTransition(int transition_index) { } -int Map::SearchSpecialTransition(Symbol* name) { - if (HasTransitionArray()) { - return transitions()->SearchSpecial(name); - } - return TransitionArray::kNotFound; -} - - -int Map::SearchTransition(PropertyType type, Name* name, - PropertyAttributes attributes) { - if (HasTransitionArray()) { - return transitions()->Search(type, name, attributes); - } +int Map::SearchTransition(Name* name) { + if (HasTransitionArray()) return transitions()->Search(name); return TransitionArray::kNotFound; } @@ -5401,17 +5387,9 @@ void Map::set_transitions(TransitionArray* transition_array, Map* target = transitions()->GetTarget(i); if (target->instance_descriptors() == instance_descriptors()) { Name* key = transitions()->GetKey(i); - int new_target_index; - if (TransitionArray::IsSpecialTransition(key)) { - new_target_index = transition_array->SearchSpecial(Symbol::cast(key)); - } else { - PropertyDetails details = - TransitionArray::GetTargetDetails(key, target); - new_target_index = transition_array->Search(details.type(), key, - details.attributes()); - } - DCHECK_NE(TransitionArray::kNotFound, new_target_index); - DCHECK_EQ(target, transition_array->GetTarget(new_target_index)); + int new_target_index = transition_array->Search(key); + DCHECK(new_target_index != TransitionArray::kNotFound); + DCHECK(transition_array->GetTarget(new_target_index) == target); } } #endif diff --git a/src/objects-printer.cc b/src/objects-printer.cc index bc5ffca78..dff4dd232 100644 --- a/src/objects-printer.cc +++ b/src/objects-printer.cc @@ -1134,19 +1134,18 @@ void TransitionArray::PrintTransitions(std::ostream& os, } for (int i = 0; i < number_of_transitions(); i++) { Name* key = GetKey(i); - Map* target = GetTarget(i); os << " "; key->NamePrint(os); os << ": "; if (key == GetHeap()->frozen_symbol()) { os << " (transition to frozen)"; } else if (key == GetHeap()->elements_transition_symbol()) { - os << " (transition to " << ElementsKindToString(target->elements_kind()) - << ")"; + os << " (transition to " + << ElementsKindToString(GetTarget(i)->elements_kind()) << ")"; } else if (key == GetHeap()->observed_symbol()) { os << " (transition to Object.observe)"; } else { - PropertyDetails details = GetTargetDetails(key, target); + PropertyDetails details = GetTargetDetails(i); switch (details.type()) { case FIELD: { os << " (transition to field)"; @@ -1165,7 +1164,7 @@ void TransitionArray::PrintTransitions(std::ostream& os, } os << ", attrs: " << details.attributes(); } - os << " -> " << Brief(target) << "\n"; + os << " -> " << Brief(GetTarget(i)) << "\n"; } } diff --git a/src/objects.cc b/src/objects.cc index 047adc5af..d48a30d8a 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -1939,7 +1939,7 @@ bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields, void Map::ConnectElementsTransition(Handle parent, Handle child) { Isolate* isolate = parent->GetIsolate(); Handle name = isolate->factory()->elements_transition_symbol(); - ConnectTransition(parent, child, name, SPECIAL_TRANSITION); + ConnectTransition(parent, child, name, FULL_TRANSITION); } @@ -2259,13 +2259,11 @@ void Map::DeprecateTransitionTree() { // Invalidates a transition target at |key|, and installs |new_descriptors| over // the current instance_descriptors to ensure proper sharing of descriptor // arrays. -void Map::DeprecateTarget(PropertyType type, Name* key, - PropertyAttributes attributes, - DescriptorArray* new_descriptors, +void Map::DeprecateTarget(Name* key, DescriptorArray* new_descriptors, LayoutDescriptor* new_layout_descriptor) { if (HasTransitionArray()) { TransitionArray* transitions = this->transitions(); - int transition = transitions->Search(type, key, attributes); + int transition = transitions->Search(key); if (transition != TransitionArray::kNotFound) { transitions->GetTarget(transition)->DeprecateTransitionTree(); } @@ -2312,15 +2310,14 @@ Map* Map::FindLastMatchMap(int verbatim, for (int i = verbatim; i < length; i++) { if (!current->HasTransitionArray()) break; Name* name = descriptors->GetKey(i); - PropertyDetails details = descriptors->GetDetails(i); TransitionArray* transitions = current->transitions(); - int transition = - transitions->Search(details.type(), name, details.attributes()); + int transition = transitions->Search(name); if (transition == TransitionArray::kNotFound) break; Map* next = transitions->GetTarget(transition); DescriptorArray* next_descriptors = next->instance_descriptors(); + PropertyDetails details = descriptors->GetDetails(i); PropertyDetails next_details = next_descriptors->GetDetails(i); if (details.type() != next_details.type()) break; if (details.attributes() != next_details.attributes()) break; @@ -2524,23 +2521,21 @@ Handle Map::GeneralizeRepresentation(Handle old_map, Handle target_map = root_map; for (int i = root_nof; i < old_nof; ++i) { - PropertyDetails old_details = old_descriptors->GetDetails(i); - int j = target_map->SearchTransition(old_details.type(), - old_descriptors->GetKey(i), - old_details.attributes()); + int j = target_map->SearchTransition(old_descriptors->GetKey(i)); if (j == TransitionArray::kNotFound) break; Handle tmp_map(target_map->GetTransition(j), isolate); Handle tmp_descriptors = handle( tmp_map->instance_descriptors(), isolate); // Check if target map is incompatible. + PropertyDetails old_details = old_descriptors->GetDetails(i); PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); PropertyType old_type = old_details.type(); PropertyType tmp_type = tmp_details.type(); - DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); - if ((tmp_type == CALLBACKS || old_type == CALLBACKS) && - (tmp_type != old_type || - tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { + if (tmp_details.attributes() != old_details.attributes() || + ((tmp_type == CALLBACKS || old_type == CALLBACKS) && + (tmp_type != old_type || + tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) { return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, "GenAll_Incompatible"); } @@ -2592,21 +2587,19 @@ Handle Map::GeneralizeRepresentation(Handle old_map, // Find the last compatible target map in the transition tree. for (int i = target_nof; i < old_nof; ++i) { - PropertyDetails old_details = old_descriptors->GetDetails(i); - int j = target_map->SearchTransition(old_details.type(), - old_descriptors->GetKey(i), - old_details.attributes()); + int j = target_map->SearchTransition(old_descriptors->GetKey(i)); if (j == TransitionArray::kNotFound) break; Handle tmp_map(target_map->GetTransition(j), isolate); Handle tmp_descriptors( tmp_map->instance_descriptors(), isolate); // Check if target map is compatible. + PropertyDetails old_details = old_descriptors->GetDetails(i); PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); - DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); - if ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) && - (tmp_details.type() != old_details.type() || - tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { + if (tmp_details.attributes() != old_details.attributes() || + ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) && + (tmp_details.type() != old_details.type() || + tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) { return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, "GenAll_Incompatible"); } @@ -2738,11 +2731,8 @@ Handle Map::GeneralizeRepresentation(Handle old_map, Handle new_layout_descriptor = LayoutDescriptor::New(split_map, new_descriptors, old_nof); - PropertyDetails split_prop_details = old_descriptors->GetDetails(split_nof); - split_map->DeprecateTarget(split_prop_details.type(), - old_descriptors->GetKey(split_nof), - split_prop_details.attributes(), *new_descriptors, - *new_layout_descriptor); + split_map->DeprecateTarget(old_descriptors->GetKey(split_nof), + *new_descriptors, *new_layout_descriptor); if (FLAG_trace_generalization) { PropertyDetails old_details = old_descriptors->GetDetails(modify_index); @@ -2832,15 +2822,13 @@ MaybeHandle Map::TryUpdateInternal(Handle old_map) { Map* new_map = root_map; for (int i = root_nof; i < old_nof; ++i) { - PropertyDetails old_details = old_descriptors->GetDetails(i); - int j = new_map->SearchTransition(old_details.type(), - old_descriptors->GetKey(i), - old_details.attributes()); + int j = new_map->SearchTransition(old_descriptors->GetKey(i)); if (j == TransitionArray::kNotFound) return MaybeHandle(); new_map = new_map->GetTransition(j); DescriptorArray* new_descriptors = new_map->instance_descriptors(); PropertyDetails new_details = new_descriptors->GetDetails(i); + PropertyDetails old_details = old_descriptors->GetDetails(i); if (old_details.attributes() != new_details.attributes() || !old_details.representation().fits_into(new_details.representation())) { return MaybeHandle(); @@ -5467,7 +5455,7 @@ MaybeHandle JSObject::Freeze(Handle object) { Handle old_map(object->map(), isolate); int transition_index = - old_map->SearchSpecialTransition(isolate->heap()->frozen_symbol()); + old_map->SearchTransition(isolate->heap()->frozen_symbol()); if (transition_index != TransitionArray::kNotFound) { Handle transition_map(old_map->GetTransition(transition_index)); DCHECK(transition_map->has_dictionary_elements()); @@ -5520,7 +5508,7 @@ void JSObject::SetObserved(Handle object) { Handle old_map(object->map(), isolate); DCHECK(!old_map->is_observed()); int transition_index = - old_map->SearchSpecialTransition(isolate->heap()->observed_symbol()); + old_map->SearchTransition(isolate->heap()->observed_symbol()); if (transition_index != TransitionArray::kNotFound) { new_map = handle(old_map->GetTransition(transition_index), isolate); DCHECK(new_map->is_observed()); @@ -6731,7 +6719,7 @@ Handle Map::ShareDescriptor(Handle map, } DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); - ConnectTransition(map, result, name, SIMPLE_PROPERTY_TRANSITION); + ConnectTransition(map, result, name, SIMPLE_TRANSITION); return result; } @@ -6864,7 +6852,7 @@ Handle Map::CopyInstallDescriptors( } Handle name = handle(descriptors->GetKey(new_descriptor)); - ConnectTransition(map, result, name, SIMPLE_PROPERTY_TRANSITION); + ConnectTransition(map, result, name, SIMPLE_TRANSITION); return result; } @@ -6942,7 +6930,7 @@ Handle Map::CopyForObserved(Handle map) { if (map->CanHaveMoreTransitions()) { Handle name = isolate->factory()->observed_symbol(); - ConnectTransition(map, new_map, name, SPECIAL_TRANSITION); + ConnectTransition(map, new_map, name, FULL_TRANSITION); } return new_map; } @@ -6956,8 +6944,7 @@ Handle Map::Copy(Handle map, const char* reason) { Handle new_layout_descriptor(map->GetLayoutDescriptor(), map->GetIsolate()); return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor, - OMIT_TRANSITION, MaybeHandle(), reason, - SPECIAL_TRANSITION); + OMIT_TRANSITION, MaybeHandle(), reason); } @@ -6996,7 +6983,7 @@ Handle Map::CopyForFreeze(Handle map) { isolate); Handle new_map = CopyReplaceDescriptors( map, new_desc, new_layout_descriptor, INSERT_TRANSITION, - isolate->factory()->frozen_symbol(), "CopyForFreeze", SPECIAL_TRANSITION); + isolate->factory()->frozen_symbol(), "CopyForFreeze"); new_map->freeze(); new_map->set_is_extensible(false); new_map->set_elements_kind(DICTIONARY_ELEMENTS); @@ -7060,14 +7047,17 @@ Handle Map::TransitionToDataProperty(Handle map, Handle name, // Migrate to the newest map before storing the property. map = Update(map); - int index = map->SearchTransition(FIELD, *name, attributes); + int index = map->SearchTransition(*name); if (index != TransitionArray::kNotFound) { Handle transition(map->GetTransition(index)); int descriptor = transition->LastAdded(); - DCHECK_EQ(attributes, transition->instance_descriptors() - ->GetDetails(descriptor) - .attributes()); + // TODO(verwaest): Handle attributes better. + DescriptorArray* descriptors = transition->instance_descriptors(); + if (descriptors->GetDetails(descriptor).attributes() != attributes) { + return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, + "IncompatibleAttributes"); + } return Map::PrepareForDataProperty(transition, descriptor, value); } @@ -7137,15 +7127,26 @@ Handle Map::TransitionToAccessorProperty(Handle map, ? KEEP_INOBJECT_PROPERTIES : CLEAR_INOBJECT_PROPERTIES; - int index = map->SearchTransition(CALLBACKS, *name, attributes); + int index = map->SearchTransition(*name); if (index != TransitionArray::kNotFound) { Handle transition(map->GetTransition(index)); DescriptorArray* descriptors = transition->instance_descriptors(); + // Fast path, assume that we're modifying the last added descriptor. int descriptor = transition->LastAdded(); - DCHECK(descriptors->GetKey(descriptor)->Equals(*name)); + if (descriptors->GetKey(descriptor) != *name) { + // If not, search for the descriptor. + descriptor = descriptors->SearchWithCache(*name, *transition); + } + + if (descriptors->GetDetails(descriptor).type() != CALLBACKS) { + return Map::Normalize(map, mode, "TransitionToAccessorFromNonPair"); + } - DCHECK_EQ(CALLBACKS, descriptors->GetDetails(descriptor).type()); - DCHECK_EQ(attributes, descriptors->GetDetails(descriptor).attributes()); + // TODO(verwaest): Handle attributes better. + if (descriptors->GetDetails(descriptor).attributes() != attributes) { + return Map::Normalize(map, mode, + "TransitionToAccessorDifferentAttributes"); + } Handle maybe_pair(descriptors->GetValue(descriptor), isolate); if (!maybe_pair->IsAccessorPair()) { @@ -7164,9 +7165,6 @@ Handle Map::TransitionToAccessorProperty(Handle map, DescriptorArray* old_descriptors = map->instance_descriptors(); int descriptor = old_descriptors->SearchWithCache(*name, *map); if (descriptor != DescriptorArray::kNotFound) { - if (descriptor != map->LastAdded()) { - return Map::Normalize(map, mode, "AccessorsOverwritingNonLast"); - } PropertyDetails old_details = old_descriptors->GetDetails(descriptor); if (old_details.type() != CALLBACKS) { return Map::Normalize(map, mode, "AccessorsOverwritingNonAccessors"); @@ -7228,7 +7226,7 @@ Handle Map::CopyAddDescriptor(Handle map, return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor, flag, descriptor->GetKey(), "CopyAddDescriptor", - SIMPLE_PROPERTY_TRANSITION); + SIMPLE_TRANSITION); } @@ -7324,8 +7322,8 @@ Handle Map::CopyReplaceDescriptor(Handle map, SimpleTransitionFlag simple_flag = (insertion_index == descriptors->number_of_descriptors() - 1) - ? SIMPLE_PROPERTY_TRANSITION - : PROPERTY_TRANSITION; + ? SIMPLE_TRANSITION + : FULL_TRANSITION; return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor, flag, key, "CopyReplaceDescriptor", simple_flag); diff --git a/src/objects.h b/src/objects.h index 5a42c7356..8dd3fc35d 100644 --- a/src/objects.h +++ b/src/objects.h @@ -280,11 +280,7 @@ enum DebugExtraICState { // Indicates whether the transition is simple: the target map of the transition // either extends the current map with a new property, or it modifies the // property that was added last to the current map. -enum SimpleTransitionFlag { - SIMPLE_PROPERTY_TRANSITION, - PROPERTY_TRANSITION, - SPECIAL_TRANSITION -}; +enum SimpleTransitionFlag { SIMPLE_TRANSITION, FULL_TRANSITION }; // Indicates whether we are only interested in the descriptors of a particular @@ -5793,9 +5789,7 @@ class Map: public HeapObject { inline Map* elements_transition_map(); inline Map* GetTransition(int transition_index); - inline int SearchSpecialTransition(Symbol* name); - inline int SearchTransition(PropertyType type, Name* name, - PropertyAttributes attributes); + inline int SearchTransition(Name* name); inline FixedArrayBase* GetInitialElements(); DECL_ACCESSORS(transitions, TransitionArray) @@ -5949,7 +5943,6 @@ class Map: public HeapObject { LookupResult* result); inline void LookupTransition(JSObject* holder, Name* name, - PropertyAttributes attributes, LookupResult* result); inline PropertyDetails GetLastDescriptorDetails(); @@ -6340,8 +6333,7 @@ class Map: public HeapObject { Handle map, Handle descriptors, Handle layout_descriptor, TransitionFlag flag, MaybeHandle maybe_name, const char* reason, - SimpleTransitionFlag simple_flag); - + SimpleTransitionFlag simple_flag = FULL_TRANSITION); static Handle CopyReplaceDescriptor(Handle map, Handle descriptors, Descriptor* descriptor, @@ -6369,9 +6361,7 @@ class Map: public HeapObject { void ZapTransitions(); void DeprecateTransitionTree(); - void DeprecateTarget(PropertyType type, Name* key, - PropertyAttributes attributes, - DescriptorArray* new_descriptors, + void DeprecateTarget(Name* key, DescriptorArray* new_descriptors, LayoutDescriptor* new_layout_descriptor); Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors); diff --git a/src/transitions-inl.h b/src/transitions-inl.h index 8a6d1bba1..087755d1b 100644 --- a/src/transitions-inl.h +++ b/src/transitions-inl.h @@ -34,7 +34,7 @@ TransitionArray* TransitionArray::cast(Object* object) { bool TransitionArray::HasElementsTransition() { - return SearchSpecial(GetHeap()->elements_transition_symbol()) != kNotFound; + return Search(GetHeap()->elements_transition_symbol()) != kNotFound; } @@ -140,7 +140,7 @@ Object* TransitionArray::GetTargetValue(int transition_number) { } -int TransitionArray::SearchName(Name* name, int* out_insertion_index) { +int TransitionArray::Search(Name* name, int* out_insertion_index) { if (IsSimpleTransition()) { Name* key = GetKey(kSimpleTransitionIndex); if (key->Equals(name)) return kSimpleTransitionIndex; @@ -153,71 +153,6 @@ int TransitionArray::SearchName(Name* name, int* out_insertion_index) { } -#ifdef DEBUG -bool TransitionArray::IsSpecialTransition(Name* name) { - if (!name->IsSymbol()) return false; - Heap* heap = name->GetHeap(); - return name == heap->frozen_symbol() || - name == heap->elements_transition_symbol() || - name == heap->observed_symbol(); -} -#endif - - -int TransitionArray::CompareKeys(Name* key1, uint32_t hash1, - bool is_data_property1, - PropertyAttributes attributes1, Name* key2, - uint32_t hash2, bool is_data_property2, - PropertyAttributes attributes2) { - int cmp = CompareNames(key1, hash1, key2, hash2); - if (cmp != 0) return cmp; - - return CompareDetails(is_data_property1, attributes1, is_data_property2, - attributes2); -} - - -int TransitionArray::CompareNames(Name* key1, uint32_t hash1, Name* key2, - uint32_t hash2) { - if (key1 != key2) { - // In case of hash collisions key1 is always "less" than key2. - return hash1 <= hash2 ? -1 : 1; - } - - return 0; -} - - -int TransitionArray::CompareDetails(bool is_data_property1, - PropertyAttributes attributes1, - bool is_data_property2, - PropertyAttributes attributes2) { - if (is_data_property1 != is_data_property2) { - return static_cast(is_data_property1) < - static_cast(is_data_property2) - ? -1 - : 1; - } - - if (attributes1 != attributes2) { - return static_cast(attributes1) < static_cast(attributes2) ? -1 - : 1; - } - - return 0; -} - - -PropertyDetails TransitionArray::GetTargetDetails(Name* name, Map* target) { - DCHECK(!IsSpecialTransition(name)); - int descriptor = target->LastAdded(); - DescriptorArray* descriptors = target->instance_descriptors(); - // Transitions are allowed only for the last added property. - DCHECK(descriptors->GetKey(descriptor)->Equals(name)); - return descriptors->GetDetails(descriptor); -} - - void TransitionArray::NoIncrementalWriteBarrierSet(int transition_number, Name* key, Map* target) { diff --git a/src/transitions.cc b/src/transitions.cc index 51eee6f98..ec1b7f4fc 100644 --- a/src/transitions.cc +++ b/src/transitions.cc @@ -48,7 +48,7 @@ Handle TransitionArray::NewWith(Handle map, Handle result; Isolate* isolate = name->GetIsolate(); - if (flag == SIMPLE_PROPERTY_TRANSITION) { + if (flag == SIMPLE_TRANSITION) { result = AllocateSimple(isolate, target); } else { result = Allocate(isolate, 1); @@ -94,19 +94,9 @@ Handle TransitionArray::Insert(Handle map, int number_of_transitions = map->transitions()->number_of_transitions(); int new_nof = number_of_transitions; - bool is_special_transition = flag == SPECIAL_TRANSITION; - DCHECK_EQ(is_special_transition, IsSpecialTransition(*name)); - PropertyDetails details = is_special_transition - ? PropertyDetails(NONE, NORMAL, 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); + int index = map->transitions()->Search(*name, &insertion_index); + if (index == kNotFound) { ++new_nof; } else { @@ -128,12 +118,12 @@ Handle TransitionArray::Insert(Handle 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); } @@ -154,11 +144,7 @@ Handle TransitionArray::Insert(Handle map, new_nof = number_of_transitions; insertion_index = kNotFound; - index = is_special_transition ? map->transitions()->SearchSpecial( - Symbol::cast(*name), &insertion_index) - : map->transitions()->Search( - details.type(), *name, - details.attributes(), &insertion_index); + index = array->Search(*name, &insertion_index); if (index == kNotFound) { ++new_nof; } else { @@ -184,46 +170,8 @@ Handle TransitionArray::Insert(Handle 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 diff --git a/src/transitions.h b/src/transitions.h index ef74b4df8..c5f9a3001 100644 --- a/src/transitions.h +++ b/src/transitions.h @@ -98,17 +98,9 @@ class TransitionArray: public FixedArray { static Handle Insert(Handle map, Handle name, Handle target, SimpleTransitionFlag flag); - // Search a transition for a given type, property name and attributes. - int Search(PropertyType type, Name* name, PropertyAttributes attributes, - int* out_insertion_index = NULL); - - // Search a non-property transition (like elements kind, observe or frozen - // transitions). - inline int SearchSpecial(Symbol* symbol, int* out_insertion_index = NULL) { - return SearchName(symbol, out_insertion_index); - } - static inline PropertyDetails GetTargetDetails(Name* name, Map* target); + // Search a transition for a given property name. + inline int Search(Name* name, int* out_insertion_index = NULL); // Allocates a TransitionArray. static Handle Allocate(Isolate* isolate, @@ -175,10 +167,6 @@ class TransitionArray: public FixedArray { bool IsSortedNoDuplicates(int valid_entries = -1); bool IsConsistentWithBackPointers(Map* current_map); bool IsEqualTo(TransitionArray* other); - - // Returns true for a non-property transitions like elements kind, observed - // or frozen transitions. - static inline bool IsSpecialTransition(Name* name); #endif // The maximum number of transitions we want in a transition array (should @@ -214,31 +202,6 @@ class TransitionArray: public FixedArray { Handle target, SimpleTransitionFlag flag); - // Search a first transition for a given property name. - inline int SearchName(Name* name, int* out_insertion_index = NULL); - int SearchDetails(int transition, PropertyType type, - PropertyAttributes attributes, int* out_insertion_index); - - // Compares two tuples , returns -1 if - // tuple1 is "less" than tuple2, 0 if tuple1 equal to tuple2 and 1 otherwise. - static inline int CompareKeys(Name* key1, uint32_t hash1, - bool is_data_property1, - PropertyAttributes attributes1, Name* key2, - uint32_t hash2, bool is_data_property2, - PropertyAttributes attributes2); - - // Compares keys, returns -1 if key1 is "less" than key2, - // 0 if key1 equal to key2 and 1 otherwise. - static inline int CompareNames(Name* key1, uint32_t hash1, Name* key2, - uint32_t hash2); - - // Compares two details, returns -1 if details1 is "less" than details2, - // 0 if details1 equal to details2 and 1 otherwise. - static inline int CompareDetails(bool is_data_property1, - PropertyAttributes attributes1, - bool is_data_property2, - PropertyAttributes attributes2); - inline void NoIncrementalWriteBarrierSet(int transition_number, Name* key, Map* target); diff --git a/test/cctest/cctest.gyp b/test/cctest/cctest.gyp index 07a838dbf..3b821a3d1 100644 --- a/test/cctest/cctest.gyp +++ b/test/cctest/cctest.gyp @@ -155,7 +155,6 @@ 'test-strtod.cc', 'test-thread-termination.cc', 'test-threads.cc', - 'test-transitions.cc', 'test-types.cc', 'test-unbound-queue.cc', 'test-unboxed-doubles.cc', diff --git a/test/cctest/test-transitions.cc b/test/cctest/test-transitions.cc deleted file mode 100644 index 94e230c04..000000000 --- a/test/cctest/test-transitions.cc +++ /dev/null @@ -1,283 +0,0 @@ -// Copyright 2014 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include -#include - -#include "src/v8.h" - -#include "src/compilation-cache.h" -#include "src/execution.h" -#include "src/factory.h" -#include "src/global-handles.h" -#include "test/cctest/cctest.h" - -using namespace v8::internal; - - -// -// Helper functions. -// - -static void ConnectTransition(Handle parent, - Handle transitions, - Handle child) { - if (!parent->HasTransitionArray() || *transitions != parent->transitions()) { - parent->set_transitions(*transitions); - } - child->SetBackPointer(*parent); -} - - -TEST(TransitionArray_SimpleFieldTransitions) { - CcTest::InitializeVM(); - v8::HandleScope scope(CcTest::isolate()); - Isolate* isolate = CcTest::i_isolate(); - Factory* factory = isolate->factory(); - - Handle name1 = factory->InternalizeUtf8String("foo"); - Handle name2 = factory->InternalizeUtf8String("bar"); - PropertyAttributes attributes = NONE; - - Handle map0 = Map::Create(isolate, 0); - Handle map1 = - Map::CopyWithField(map0, name1, handle(HeapType::Any(), isolate), - attributes, Representation::Tagged(), - OMIT_TRANSITION).ToHandleChecked(); - Handle map2 = - Map::CopyWithField(map0, name2, handle(HeapType::Any(), isolate), - attributes, Representation::Tagged(), - OMIT_TRANSITION).ToHandleChecked(); - - CHECK(!map0->HasTransitionArray()); - Handle transitions = TransitionArray::Allocate(isolate, 0); - CHECK(transitions->IsFullTransitionArray()); - - int transition; - transitions = - transitions->Insert(map0, name1, map1, SIMPLE_PROPERTY_TRANSITION); - ConnectTransition(map0, transitions, map1); - CHECK(transitions->IsSimpleTransition()); - transition = transitions->Search(FIELD, *name1, attributes); - CHECK_EQ(TransitionArray::kSimpleTransitionIndex, transition); - CHECK_EQ(*name1, transitions->GetKey(transition)); - CHECK_EQ(*map1, transitions->GetTarget(transition)); - - transitions = - transitions->Insert(map0, name2, map2, SIMPLE_PROPERTY_TRANSITION); - ConnectTransition(map0, transitions, map2); - CHECK(transitions->IsFullTransitionArray()); - - transition = transitions->Search(FIELD, *name1, attributes); - CHECK_EQ(*name1, transitions->GetKey(transition)); - CHECK_EQ(*map1, transitions->GetTarget(transition)); - - transition = transitions->Search(FIELD, *name2, attributes); - CHECK_EQ(*name2, transitions->GetKey(transition)); - CHECK_EQ(*map2, transitions->GetTarget(transition)); - - DCHECK(transitions->IsSortedNoDuplicates()); -} - - -TEST(TransitionArray_FullFieldTransitions) { - CcTest::InitializeVM(); - v8::HandleScope scope(CcTest::isolate()); - Isolate* isolate = CcTest::i_isolate(); - Factory* factory = isolate->factory(); - - Handle name1 = factory->InternalizeUtf8String("foo"); - Handle name2 = factory->InternalizeUtf8String("bar"); - PropertyAttributes attributes = NONE; - - Handle map0 = Map::Create(isolate, 0); - Handle map1 = - Map::CopyWithField(map0, name1, handle(HeapType::Any(), isolate), - attributes, Representation::Tagged(), - OMIT_TRANSITION).ToHandleChecked(); - Handle map2 = - Map::CopyWithField(map0, name2, handle(HeapType::Any(), isolate), - attributes, Representation::Tagged(), - OMIT_TRANSITION).ToHandleChecked(); - - CHECK(!map0->HasTransitionArray()); - Handle transitions = TransitionArray::Allocate(isolate, 0); - CHECK(transitions->IsFullTransitionArray()); - - int transition; - transitions = transitions->Insert(map0, name1, map1, PROPERTY_TRANSITION); - ConnectTransition(map0, transitions, map1); - CHECK(transitions->IsFullTransitionArray()); - transition = transitions->Search(FIELD, *name1, attributes); - CHECK_EQ(*name1, transitions->GetKey(transition)); - CHECK_EQ(*map1, transitions->GetTarget(transition)); - - transitions = transitions->Insert(map0, name2, map2, PROPERTY_TRANSITION); - ConnectTransition(map0, transitions, map2); - CHECK(transitions->IsFullTransitionArray()); - - transition = transitions->Search(FIELD, *name1, attributes); - CHECK_EQ(*name1, transitions->GetKey(transition)); - CHECK_EQ(*map1, transitions->GetTarget(transition)); - - transition = transitions->Search(FIELD, *name2, attributes); - CHECK_EQ(*name2, transitions->GetKey(transition)); - CHECK_EQ(*map2, transitions->GetTarget(transition)); - - DCHECK(transitions->IsSortedNoDuplicates()); -} - - -TEST(TransitionArray_DifferentFieldNames) { - CcTest::InitializeVM(); - v8::HandleScope scope(CcTest::isolate()); - Isolate* isolate = CcTest::i_isolate(); - Factory* factory = isolate->factory(); - - const int PROPS_COUNT = 10; - Handle names[PROPS_COUNT]; - Handle maps[PROPS_COUNT]; - PropertyAttributes attributes = NONE; - - Handle map0 = Map::Create(isolate, 0); - CHECK(!map0->HasTransitionArray()); - Handle transitions = TransitionArray::Allocate(isolate, 0); - CHECK(transitions->IsFullTransitionArray()); - - for (int i = 0; i < PROPS_COUNT; i++) { - EmbeddedVector buffer; - SNPrintF(buffer, "prop%d", i); - Handle name = factory->InternalizeUtf8String(buffer.start()); - Handle map = - Map::CopyWithField(map0, name, handle(HeapType::Any(), isolate), - attributes, Representation::Tagged(), - OMIT_TRANSITION).ToHandleChecked(); - names[i] = name; - maps[i] = map; - - transitions = transitions->Insert(map0, name, map, PROPERTY_TRANSITION); - ConnectTransition(map0, transitions, map); - } - - for (int i = 0; i < PROPS_COUNT; i++) { - int transition = transitions->Search(FIELD, *names[i], attributes); - CHECK_EQ(*names[i], transitions->GetKey(transition)); - CHECK_EQ(*maps[i], transitions->GetTarget(transition)); - } - - DCHECK(transitions->IsSortedNoDuplicates()); -} - - -TEST(TransitionArray_SameFieldNamesDifferentAttributesSimple) { - CcTest::InitializeVM(); - v8::HandleScope scope(CcTest::isolate()); - Isolate* isolate = CcTest::i_isolate(); - Factory* factory = isolate->factory(); - - Handle map0 = Map::Create(isolate, 0); - CHECK(!map0->HasTransitionArray()); - Handle transitions = TransitionArray::Allocate(isolate, 0); - CHECK(transitions->IsFullTransitionArray()); - - const int ATTRS_COUNT = (READ_ONLY | DONT_ENUM | DONT_DELETE) + 1; - STATIC_ASSERT(ATTRS_COUNT == 8); - Handle attr_maps[ATTRS_COUNT]; - Handle name = factory->InternalizeUtf8String("foo"); - - // Add transitions for same field name but different attributes. - for (int i = 0; i < ATTRS_COUNT; i++) { - PropertyAttributes attributes = static_cast(i); - - Handle map = - Map::CopyWithField(map0, name, handle(HeapType::Any(), isolate), - attributes, Representation::Tagged(), - OMIT_TRANSITION).ToHandleChecked(); - attr_maps[i] = map; - - transitions = transitions->Insert(map0, name, map, PROPERTY_TRANSITION); - ConnectTransition(map0, transitions, map); - } - - // Ensure that transitions for |name| field are valid. - for (int i = 0; i < ATTRS_COUNT; i++) { - PropertyAttributes attributes = static_cast(i); - - int transition = transitions->Search(FIELD, *name, attributes); - CHECK_EQ(*name, transitions->GetKey(transition)); - CHECK_EQ(*attr_maps[i], transitions->GetTarget(transition)); - } - - DCHECK(transitions->IsSortedNoDuplicates()); -} - - -TEST(TransitionArray_SameFieldNamesDifferentAttributes) { - CcTest::InitializeVM(); - v8::HandleScope scope(CcTest::isolate()); - Isolate* isolate = CcTest::i_isolate(); - Factory* factory = isolate->factory(); - - const int PROPS_COUNT = 10; - Handle names[PROPS_COUNT]; - Handle maps[PROPS_COUNT]; - - Handle map0 = Map::Create(isolate, 0); - CHECK(!map0->HasTransitionArray()); - Handle transitions = TransitionArray::Allocate(isolate, 0); - CHECK(transitions->IsFullTransitionArray()); - - // Some number of fields. - for (int i = 0; i < PROPS_COUNT; i++) { - EmbeddedVector buffer; - SNPrintF(buffer, "prop%d", i); - Handle name = factory->InternalizeUtf8String(buffer.start()); - Handle map = - Map::CopyWithField(map0, name, handle(HeapType::Any(), isolate), NONE, - Representation::Tagged(), - OMIT_TRANSITION).ToHandleChecked(); - names[i] = name; - maps[i] = map; - - transitions = transitions->Insert(map0, name, map, PROPERTY_TRANSITION); - ConnectTransition(map0, transitions, map); - } - - const int ATTRS_COUNT = (READ_ONLY | DONT_ENUM | DONT_DELETE) + 1; - STATIC_ASSERT(ATTRS_COUNT == 8); - Handle attr_maps[ATTRS_COUNT]; - Handle name = factory->InternalizeUtf8String("foo"); - - // Add transitions for same field name but different attributes. - for (int i = 0; i < ATTRS_COUNT; i++) { - PropertyAttributes attributes = static_cast(i); - - Handle map = - Map::CopyWithField(map0, name, handle(HeapType::Any(), isolate), - attributes, Representation::Tagged(), - OMIT_TRANSITION).ToHandleChecked(); - attr_maps[i] = map; - - transitions = transitions->Insert(map0, name, map, PROPERTY_TRANSITION); - ConnectTransition(map0, transitions, map); - } - - // Ensure that transitions for |name| field are valid. - for (int i = 0; i < ATTRS_COUNT; i++) { - PropertyAttributes attributes = static_cast(i); - - int transition = transitions->Search(FIELD, *name, attributes); - CHECK_EQ(*name, transitions->GetKey(transition)); - CHECK_EQ(*attr_maps[i], transitions->GetTarget(transition)); - } - - // Ensure that info about the other fields still valid. - for (int i = 0; i < PROPS_COUNT; i++) { - int transition = transitions->Search(FIELD, *names[i], NONE); - CHECK_EQ(*names[i], transitions->GetKey(transition)); - CHECK_EQ(*maps[i], transitions->GetTarget(transition)); - } - - DCHECK(transitions->IsSortedNoDuplicates()); -} diff --git a/test/mjsunit/regress/regress-crbug-430846.js b/test/mjsunit/regress/regress-crbug-430846.js deleted file mode 100644 index 3047c7fc3..000000000 --- a/test/mjsunit/regress/regress-crbug-430846.js +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2014 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Flags: --allow-natives-syntax - -function foo() { return 1; }; -var o1 = {}; -o1.foo = foo; - -var json = '{"foo": {"x": 1}}'; -var o2 = JSON.parse(json); -var o3 = JSON.parse(json); -assertTrue(%HaveSameMap(o2, o3));