Revert "TransitionArray::Search() now returns insertion index if the entry was not found."
This reverts the commit because it possibly causes renderer hangs. BUG=chromium:431807 LOG=N R=verwaest@chromium.org Review URL: https://codereview.chromium.org/725633002 Cr-Commit-Position: refs/heads/master@{#25338}
This commit is contained in:
parent
04719195a2
commit
994094cc62
@ -2853,10 +2853,8 @@ void DescriptorArray::SetNumberOfDescriptors(int number_of_descriptors) {
|
||||
// Perform a binary search in a fixed array. Low and high are entry indices. If
|
||||
// there are three entries in this array it should be called with low=0 and
|
||||
// high=2.
|
||||
template <SearchMode search_mode, typename T>
|
||||
int BinarySearch(T* array, Name* name, int low, int high, int valid_entries,
|
||||
int* out_insertion_index) {
|
||||
DCHECK(search_mode == ALL_ENTRIES || out_insertion_index == NULL);
|
||||
template<SearchMode search_mode, typename T>
|
||||
int BinarySearch(T* array, Name* name, int low, int high, int valid_entries) {
|
||||
uint32_t hash = name->Hash();
|
||||
int limit = high;
|
||||
|
||||
@ -2877,13 +2875,7 @@ int BinarySearch(T* array, Name* name, int low, int high, int valid_entries,
|
||||
for (; low <= limit; ++low) {
|
||||
int sort_index = array->GetSortedKeyIndex(low);
|
||||
Name* entry = array->GetKey(sort_index);
|
||||
uint32_t current_hash = entry->Hash();
|
||||
if (current_hash != hash) {
|
||||
if (out_insertion_index != NULL) {
|
||||
*out_insertion_index = sort_index + (current_hash > hash ? 0 : 1);
|
||||
}
|
||||
return T::kNotFound;
|
||||
}
|
||||
if (entry->Hash() != hash) break;
|
||||
if (entry->Equals(name)) {
|
||||
if (search_mode == ALL_ENTRIES || sort_index < valid_entries) {
|
||||
return sort_index;
|
||||
@ -2892,45 +2884,37 @@ int BinarySearch(T* array, Name* name, int low, int high, int valid_entries,
|
||||
}
|
||||
}
|
||||
|
||||
if (out_insertion_index != NULL) *out_insertion_index = limit + 1;
|
||||
return T::kNotFound;
|
||||
}
|
||||
|
||||
|
||||
// Perform a linear search in this fixed array. len is the number of entry
|
||||
// indices that are valid.
|
||||
template <SearchMode search_mode, typename T>
|
||||
int LinearSearch(T* array, Name* name, int len, int valid_entries,
|
||||
int* out_insertion_index) {
|
||||
template<SearchMode search_mode, typename T>
|
||||
int LinearSearch(T* array, Name* name, int len, int valid_entries) {
|
||||
uint32_t hash = name->Hash();
|
||||
if (search_mode == ALL_ENTRIES) {
|
||||
for (int number = 0; number < len; number++) {
|
||||
int sorted_index = array->GetSortedKeyIndex(number);
|
||||
Name* entry = array->GetKey(sorted_index);
|
||||
uint32_t current_hash = entry->Hash();
|
||||
if (current_hash > hash) {
|
||||
if (out_insertion_index != NULL) *out_insertion_index = sorted_index;
|
||||
return T::kNotFound;
|
||||
}
|
||||
if (current_hash > hash) break;
|
||||
if (current_hash == hash && entry->Equals(name)) return sorted_index;
|
||||
}
|
||||
if (out_insertion_index != NULL) *out_insertion_index = len;
|
||||
return T::kNotFound;
|
||||
} else {
|
||||
DCHECK(len >= valid_entries);
|
||||
DCHECK_EQ(NULL, out_insertion_index); // Not supported here.
|
||||
for (int number = 0; number < valid_entries; number++) {
|
||||
Name* entry = array->GetKey(number);
|
||||
uint32_t current_hash = entry->Hash();
|
||||
if (current_hash == hash && entry->Equals(name)) return number;
|
||||
}
|
||||
return T::kNotFound;
|
||||
}
|
||||
return T::kNotFound;
|
||||
}
|
||||
|
||||
|
||||
template <SearchMode search_mode, typename T>
|
||||
int Search(T* array, Name* name, int valid_entries, int* out_insertion_index) {
|
||||
template<SearchMode search_mode, typename T>
|
||||
int Search(T* array, Name* name, int valid_entries) {
|
||||
if (search_mode == VALID_ENTRIES) {
|
||||
SLOW_DCHECK(array->IsSortedNoDuplicates(valid_entries));
|
||||
} else {
|
||||
@ -2938,10 +2922,7 @@ int Search(T* array, Name* name, int valid_entries, int* out_insertion_index) {
|
||||
}
|
||||
|
||||
int nof = array->number_of_entries();
|
||||
if (nof == 0) {
|
||||
if (out_insertion_index != NULL) *out_insertion_index = 0;
|
||||
return T::kNotFound;
|
||||
}
|
||||
if (nof == 0) return T::kNotFound;
|
||||
|
||||
// Fast case: do linear search for small arrays.
|
||||
const int kMaxElementsForLinearSearch = 8;
|
||||
@ -2949,18 +2930,16 @@ int Search(T* array, Name* name, int valid_entries, int* out_insertion_index) {
|
||||
nof <= kMaxElementsForLinearSearch) ||
|
||||
(search_mode == VALID_ENTRIES &&
|
||||
valid_entries <= (kMaxElementsForLinearSearch * 3))) {
|
||||
return LinearSearch<search_mode>(array, name, nof, valid_entries,
|
||||
out_insertion_index);
|
||||
return LinearSearch<search_mode>(array, name, nof, valid_entries);
|
||||
}
|
||||
|
||||
// Slow case: perform binary search.
|
||||
return BinarySearch<search_mode>(array, name, 0, nof - 1, valid_entries,
|
||||
out_insertion_index);
|
||||
return BinarySearch<search_mode>(array, name, 0, nof - 1, valid_entries);
|
||||
}
|
||||
|
||||
|
||||
int DescriptorArray::Search(Name* name, int valid_descriptors) {
|
||||
return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors, NULL);
|
||||
return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3151,9 +3151,12 @@ class DescriptorArray: public FixedArray {
|
||||
|
||||
enum SearchMode { ALL_ENTRIES, VALID_ENTRIES };
|
||||
|
||||
template <SearchMode search_mode, typename T>
|
||||
inline int Search(T* array, Name* name, int valid_entries = 0,
|
||||
int* out_insertion_index = NULL);
|
||||
template<SearchMode search_mode, typename T>
|
||||
inline int LinearSearch(T* array, Name* name, int len, int valid_entries);
|
||||
|
||||
|
||||
template<SearchMode search_mode, typename T>
|
||||
inline int Search(T* array, Name* name, int valid_entries = 0);
|
||||
|
||||
|
||||
// HashTable is a subclass of FixedArray that implements a hash table
|
||||
|
@ -140,16 +140,13 @@ Object* TransitionArray::GetTargetValue(int transition_number) {
|
||||
}
|
||||
|
||||
|
||||
int TransitionArray::Search(Name* name, int* out_insertion_index) {
|
||||
int TransitionArray::Search(Name* name) {
|
||||
if (IsSimpleTransition()) {
|
||||
Name* key = GetKey(kSimpleTransitionIndex);
|
||||
if (key->Equals(name)) return kSimpleTransitionIndex;
|
||||
if (out_insertion_index != NULL) {
|
||||
*out_insertion_index = key->Hash() > name->Hash() ? 0 : 1;
|
||||
}
|
||||
return kNotFound;
|
||||
}
|
||||
return internal::Search<ALL_ENTRIES>(this, name, 0, out_insertion_index);
|
||||
return internal::Search<ALL_ENTRIES>(this, name);
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,6 +41,11 @@ void TransitionArray::NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin,
|
||||
}
|
||||
|
||||
|
||||
static bool InsertionPointFound(Name* key1, Name* key2) {
|
||||
return key1->Hash() > key2->Hash();
|
||||
}
|
||||
|
||||
|
||||
Handle<TransitionArray> TransitionArray::NewWith(Handle<Map> map,
|
||||
Handle<Name> name,
|
||||
Handle<Map> target,
|
||||
@ -94,36 +99,30 @@ 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);
|
||||
|
||||
if (index == kNotFound) {
|
||||
++new_nof;
|
||||
} else {
|
||||
insertion_index = index;
|
||||
}
|
||||
DCHECK(insertion_index >= 0 && insertion_index <= number_of_transitions);
|
||||
|
||||
int insertion_index = map->transitions()->Search(*name);
|
||||
if (insertion_index == kNotFound) ++new_nof;
|
||||
CHECK(new_nof <= kMaxNumberOfTransitions);
|
||||
|
||||
if (new_nof <= map->transitions()->number_of_transitions_storage()) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
TransitionArray* array = map->transitions();
|
||||
|
||||
if (index != kNotFound) {
|
||||
array->SetTarget(index, *target);
|
||||
if (insertion_index != kNotFound) {
|
||||
array->SetTarget(insertion_index, *target);
|
||||
return handle(array);
|
||||
}
|
||||
|
||||
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));
|
||||
uint32_t hash = name->Hash();
|
||||
for (insertion_index = number_of_transitions; insertion_index > 0;
|
||||
--insertion_index) {
|
||||
Name* key = array->GetKey(insertion_index - 1);
|
||||
if (key->Hash() <= hash) break;
|
||||
array->SetKey(insertion_index, key);
|
||||
array->SetTarget(insertion_index, array->GetTarget(insertion_index - 1));
|
||||
}
|
||||
array->SetKey(index, *name);
|
||||
array->SetTarget(index, *target);
|
||||
array->SetKey(insertion_index, *name);
|
||||
array->SetTarget(insertion_index, *target);
|
||||
return handle(array);
|
||||
}
|
||||
|
||||
@ -143,14 +142,8 @@ Handle<TransitionArray> TransitionArray::Insert(Handle<Map> map,
|
||||
number_of_transitions = array->number_of_transitions();
|
||||
new_nof = number_of_transitions;
|
||||
|
||||
insertion_index = kNotFound;
|
||||
index = array->Search(*name, &insertion_index);
|
||||
if (index == kNotFound) {
|
||||
++new_nof;
|
||||
} else {
|
||||
insertion_index = index;
|
||||
}
|
||||
DCHECK(insertion_index >= 0 && insertion_index <= number_of_transitions);
|
||||
insertion_index = array->Search(*name);
|
||||
if (insertion_index == kNotFound) ++new_nof;
|
||||
|
||||
result->Shrink(ToKeyIndex(new_nof));
|
||||
result->SetNumberOfTransitions(new_nof);
|
||||
@ -160,13 +153,18 @@ Handle<TransitionArray> TransitionArray::Insert(Handle<Map> map,
|
||||
result->SetPrototypeTransitions(array->GetPrototypeTransitions());
|
||||
}
|
||||
|
||||
DCHECK_NE(kNotFound, insertion_index);
|
||||
for (int i = 0; i < insertion_index; ++i) {
|
||||
result->NoIncrementalWriteBarrierCopyFrom(array, i, i);
|
||||
insertion_index = 0;
|
||||
for (; insertion_index < number_of_transitions; ++insertion_index) {
|
||||
if (InsertionPointFound(array->GetKey(insertion_index), *name)) break;
|
||||
result->NoIncrementalWriteBarrierCopyFrom(
|
||||
array, insertion_index, insertion_index);
|
||||
}
|
||||
|
||||
result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target);
|
||||
for (int i = insertion_index; i < number_of_transitions; ++i) {
|
||||
result->NoIncrementalWriteBarrierCopyFrom(array, i, i + 1);
|
||||
|
||||
for (; insertion_index < number_of_transitions; ++insertion_index) {
|
||||
result->NoIncrementalWriteBarrierCopyFrom(
|
||||
array, insertion_index, insertion_index + 1);
|
||||
}
|
||||
|
||||
result->set_back_pointer_storage(array->back_pointer_storage());
|
||||
|
@ -100,7 +100,7 @@ class TransitionArray: public FixedArray {
|
||||
SimpleTransitionFlag flag);
|
||||
|
||||
// Search a transition for a given property name.
|
||||
inline int Search(Name* name, int* out_insertion_index = NULL);
|
||||
inline int Search(Name* name);
|
||||
|
||||
// Allocates a TransitionArray.
|
||||
static Handle<TransitionArray> Allocate(Isolate* isolate,
|
||||
|
Loading…
Reference in New Issue
Block a user