Index: src/objects-inl.h |
diff --git a/src/objects-inl.h b/src/objects-inl.h |
index 6c4cd54f6624601f2ca21814113a3cc11824b927..b00bcbfcbd19de217a4e3e9429e39401b6a5f46e 100644 |
--- a/src/objects-inl.h |
+++ b/src/objects-inl.h |
@@ -1887,15 +1887,6 @@ bool DescriptorArray::IsEmpty() { |
} |
-void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array, |
- int first, |
- int second) { |
- Object* tmp = array->get(first); |
- NoIncrementalWriteBarrierSet(array, first, array->get(second)); |
- NoIncrementalWriteBarrierSet(array, second, tmp); |
-} |
- |
- |
// 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. |
@@ -1908,7 +1899,7 @@ int BinarySearch(T* array, String* name, int low, int high) { |
while (low != high) { |
int mid = (low + high) / 2; |
- String* mid_name = array->GetKey(mid); |
+ String* mid_name = array->GetSortedKey(mid); |
uint32_t mid_hash = mid_name->Hash(); |
if (mid_hash >= hash) { |
@@ -1918,24 +1909,27 @@ int BinarySearch(T* array, String* name, int low, int high) { |
} |
} |
- for (; low <= limit && array->GetKey(low)->Hash() == hash; ++low) { |
- if (array->GetKey(low)->Equals(name)) return low; |
+ for (; low <= limit; ++low) { |
+ int sort_index = array->GetSortedKeyIndex(low); |
+ String* entry = array->GetKey(sort_index); |
+ if (entry->Hash() != hash) break; |
+ if (entry->Equals(name)) return sort_index; |
} |
return T::kNotFound; |
} |
- |
// Perform a linear search in this fixed array. len is the number of entry |
// indices that are valid. |
template<typename T> |
int LinearSearch(T* array, String* name, int len) { |
uint32_t hash = name->Hash(); |
for (int number = 0; number < len; number++) { |
- String* entry = array->GetKey(number); |
+ int sorted_index = array->GetSortedKeyIndex(number); |
+ String* entry = array->GetKey(sorted_index); |
uint32_t current_hash = entry->Hash(); |
if (current_hash > hash) break; |
- if (current_hash == hash && name->Equals(entry)) return number; |
+ if (current_hash == hash && entry->Equals(name)) return sorted_index; |
} |
return T::kNotFound; |
} |
@@ -1945,13 +1939,12 @@ template<typename T> |
int Search(T* array, String* name) { |
SLOW_ASSERT(array->IsSortedNoDuplicates()); |
- // Check for empty descriptor array. |
int nof = array->number_of_entries(); |
if (nof == 0) return T::kNotFound; |
// Fast case: do linear search for small arrays. |
const int kMaxElementsForLinearSearch = 8; |
- if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) { |
+ if (nof < kMaxElementsForLinearSearch) { |
return LinearSearch(array, name, nof); |
} |
@@ -1966,16 +1959,44 @@ int DescriptorArray::Search(String* name) { |
int DescriptorArray::SearchWithCache(String* name) { |
+ if (number_of_descriptors() == 0) return kNotFound; |
+ |
DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache(); |
int number = cache->Lookup(this, name); |
+ |
if (number == DescriptorLookupCache::kAbsent) { |
- number = internal::Search(this, name); |
+ number = Search(name); |
cache->Update(this, name, number); |
} |
+ |
return number; |
} |
+void Map::LookupDescriptor(JSObject* holder, |
+ String* name, |
+ LookupResult* result) { |
+ DescriptorArray* descriptors = this->instance_descriptors(); |
+ int number = descriptors->SearchWithCache(name); |
+ if (number == DescriptorArray::kNotFound) return result->NotFound(); |
+ result->DescriptorResult(holder, descriptors->GetDetails(number), number); |
+} |
+ |
+ |
+void Map::LookupTransition(JSObject* holder, |
+ String* name, |
+ LookupResult* result) { |
+ if (HasTransitionArray()) { |
+ TransitionArray* transition_array = transitions(); |
+ int number = transition_array->Search(name); |
+ if (number != TransitionArray::kNotFound) { |
+ return result->TransitionResult(holder, number); |
+ } |
+ } |
+ result->NotFound(); |
+} |
+ |
+ |
Object** DescriptorArray::GetKeySlot(int descriptor_number) { |
ASSERT(descriptor_number < number_of_descriptors()); |
return HeapObject::RawField( |
@@ -1990,6 +2011,23 @@ String* DescriptorArray::GetKey(int descriptor_number) { |
} |
+int DescriptorArray::GetSortedKeyIndex(int descriptor_number) { |
+ return GetDetails(descriptor_number).pointer(); |
+} |
+ |
+ |
+String* DescriptorArray::GetSortedKey(int descriptor_number) { |
+ return GetKey(GetSortedKeyIndex(descriptor_number)); |
+} |
+ |
+ |
+void DescriptorArray::SetSortedKey(int pointer, int descriptor_number) { |
+ int details_index = ToDetailsIndex(pointer); |
+ PropertyDetails details = PropertyDetails(Smi::cast(get(details_index))); |
+ set_unchecked(details_index, details.set_pointer(descriptor_number).AsSmi()); |
+} |
+ |
+ |
Object** DescriptorArray::GetValueSlot(int descriptor_number) { |
ASSERT(descriptor_number < number_of_descriptors()); |
return HeapObject::RawField( |
@@ -2051,8 +2089,9 @@ void DescriptorArray::Set(int descriptor_number, |
const WhitenessWitness&) { |
// Range check. |
ASSERT(descriptor_number < number_of_descriptors()); |
- ASSERT(desc->GetDetails().index() <= number_of_descriptors()); |
- ASSERT(desc->GetDetails().index() > 0); |
+ ASSERT(desc->GetDetails().descriptor_index() <= |
+ number_of_descriptors()); |
+ ASSERT(desc->GetDetails().descriptor_index() > 0); |
NoIncrementalWriteBarrierSet(this, |
ToKeyIndex(descriptor_number), |
@@ -2066,38 +2105,31 @@ void DescriptorArray::Set(int descriptor_number, |
} |
-int DescriptorArray::Append(Descriptor* desc, |
- const WhitenessWitness& witness, |
- int number_of_set_descriptors) { |
- int descriptor_number = number_of_set_descriptors; |
- int enumeration_index = descriptor_number + 1; |
+void DescriptorArray::Append(Descriptor* desc, |
+ const WhitenessWitness& witness, |
+ int number_of_set_descriptors) { |
+ int enumeration_index = number_of_set_descriptors + 1; |
desc->SetEnumerationIndex(enumeration_index); |
+ Set(number_of_set_descriptors, desc, witness); |
uint32_t hash = desc->GetKey()->Hash(); |
- for (; descriptor_number > 0; --descriptor_number) { |
- String* key = GetKey(descriptor_number - 1); |
+ int insertion; |
+ |
+ for (insertion = number_of_set_descriptors; insertion > 0; --insertion) { |
+ String* key = GetSortedKey(insertion - 1); |
if (key->Hash() <= hash) break; |
- Object* value = GetValue(descriptor_number - 1); |
- PropertyDetails details = GetDetails(descriptor_number - 1); |
- Descriptor moved_descriptor(key, value, details); |
- Set(descriptor_number, &moved_descriptor, witness); |
+ SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1)); |
} |
- Set(descriptor_number, desc, witness); |
- return descriptor_number; |
+ SetSortedKey(insertion, number_of_set_descriptors); |
} |
-void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors( |
- int first, int second) { |
- NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second)); |
- NoIncrementalWriteBarrierSwap(this, |
- ToValueIndex(first), |
- ToValueIndex(second)); |
- NoIncrementalWriteBarrierSwap(this, |
- ToDetailsIndex(first), |
- ToDetailsIndex(second)); |
+void DescriptorArray::SwapSortedKeys(int first, int second) { |
+ int first_key = GetSortedKeyIndex(first); |
+ SetSortedKey(first, GetSortedKeyIndex(second)); |
+ SetSortedKey(second, first_key); |
} |
@@ -3455,18 +3487,18 @@ MaybeObject* Map::SetDescriptors(DescriptorArray* value, |
MaybeObject* Map::InitializeDescriptors(DescriptorArray* descriptors) { |
+#ifdef DEBUG |
int len = descriptors->number_of_descriptors(); |
ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors); |
SLOW_ASSERT(descriptors->IsSortedNoDuplicates()); |
-#ifdef DEBUG |
bool used_indices[DescriptorArray::kMaxNumberOfDescriptors]; |
for (int i = 0; i < len; ++i) used_indices[i] = false; |
// Ensure that all enumeration indexes between 1 and length occur uniquely in |
// the descriptor array. |
for (int i = 0; i < len; ++i) { |
- int enum_index = descriptors->GetDetails(i).index() - |
+ int enum_index = descriptors->GetDetails(i).descriptor_index() - |
PropertyDetails::kInitialIndex; |
ASSERT(0 <= enum_index && enum_index < len); |
ASSERT(!used_indices[enum_index]); |
@@ -3477,14 +3509,8 @@ MaybeObject* Map::InitializeDescriptors(DescriptorArray* descriptors) { |
MaybeObject* maybe_failure = SetDescriptors(descriptors); |
if (maybe_failure->IsFailure()) return maybe_failure; |
- for (int i = 0; i < len; ++i) { |
- if (descriptors->GetDetails(i).index() == len) { |
- SetLastAdded(i); |
- return this; |
- } |
- } |
+ SetNumberOfOwnDescriptors(descriptors->number_of_descriptors()); |
- ASSERT(len == 0 && LastAdded() == kNoneAdded); |
return this; |
} |
@@ -3511,9 +3537,10 @@ void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) { |
void Map::AppendDescriptor(Descriptor* desc, |
const DescriptorArray::WhitenessWitness& witness) { |
DescriptorArray* descriptors = instance_descriptors(); |
- int set_descriptors = NumberOfSetDescriptors(); |
- int new_last_added = descriptors->Append(desc, witness, set_descriptors); |
- SetLastAdded(new_last_added); |
+ int number_of_own_descriptors = NumberOfOwnDescriptors(); |
+ ASSERT(number_of_own_descriptors < descriptors->number_of_descriptors()); |
+ descriptors->Append(desc, witness, number_of_own_descriptors); |
+ SetNumberOfOwnDescriptors(number_of_own_descriptors + 1); |
} |
@@ -5001,7 +5028,9 @@ void Dictionary<Shape, Key>::SetEntry(int entry, |
Object* key, |
Object* value, |
PropertyDetails details) { |
- ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0); |
+ ASSERT(!key->IsString() || |
+ details.IsDeleted() || |
+ details.dictionary_index() > 0); |
int index = HashTable<Shape, Key>::EntryToIndex(entry); |
AssertNoAllocation no_gc; |
WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc); |