Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(910)

Unified Diff: src/objects-inl.h

Issue 10909007: Sharing of descriptor arrays. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects-debug.cc ('k') | src/profile-generator.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index a7978338058b7e9b37dee0d0c17c90d734d04c1f..899e7dcb3fc63647842d1057b2ae76e08039ba4e 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1913,31 +1913,45 @@ int BinarySearch(T* array, String* name, int low, int high) {
// 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) {
+template<SearchMode search_mode, typename T>
+int LinearSearch(T* array, String* name, int len, int valid_entries) {
uint32_t hash = name->Hash();
- for (int number = 0; number < len; 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 && entry->Equals(name)) return sorted_index;
+ if (search_mode == ALL_ENTRIES) {
+ for (int number = 0; number < len; 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 && entry->Equals(name)) return sorted_index;
+ }
+ } else {
+ ASSERT(len >= valid_entries);
+ for (int number = 0; number < valid_entries; number++) {
+ String* entry = array->GetKey(number);
+ uint32_t current_hash = entry->Hash();
+ if (current_hash == hash && entry->Equals(name)) return number;
+ }
}
return T::kNotFound;
}
-template<typename T>
-int Search(T* array, String* name) {
- SLOW_ASSERT(array->IsSortedNoDuplicates());
+template<SearchMode search_mode, typename T>
+int Search(T* array, String* name, int valid_entries) {
+ if (search_mode == VALID_ENTRIES) {
+ SLOW_ASSERT(array->IsSortedNoDuplicates(valid_entries));
+ } else {
+ SLOW_ASSERT(array->IsSortedNoDuplicates());
+ }
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 (nof < kMaxElementsForLinearSearch) {
- return LinearSearch(array, name, nof);
+ if (search_mode == VALID_ENTRIES ||
+ (search_mode == ALL_ENTRIES && nof < kMaxElementsForLinearSearch)) {
+ return LinearSearch<search_mode>(array, name, nof, valid_entries);
}
// Slow case: perform binary search.
@@ -1945,20 +1959,21 @@ int Search(T* array, String* name) {
}
-int DescriptorArray::Search(String* name) {
- return internal::Search(this, name);
+int DescriptorArray::Search(String* name, int valid_descriptors) {
+ return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors);
}
-int DescriptorArray::SearchWithCache(String* name) {
- if (number_of_descriptors() == 0) return kNotFound;
+int DescriptorArray::SearchWithCache(String* name, Map* map) {
+ int number_of_own_descriptors = map->NumberOfOwnDescriptors();
+ if (number_of_own_descriptors == 0) return kNotFound;
DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache();
- int number = cache->Lookup(this, name);
+ int number = cache->Lookup(map, name);
if (number == DescriptorLookupCache::kAbsent) {
- number = Search(name);
- cache->Update(this, name, number);
+ number = Search(name, number_of_own_descriptors);
+ cache->Update(map, name, number);
}
return number;
@@ -1969,7 +1984,7 @@ void Map::LookupDescriptor(JSObject* holder,
String* name,
LookupResult* result) {
DescriptorArray* descriptors = this->instance_descriptors();
- int number = descriptors->SearchWithCache(name);
+ int number = descriptors->SearchWithCache(name, this);
if (number == DescriptorArray::kNotFound) return result->NotFound();
result->DescriptorResult(holder, descriptors->GetDetails(number), number);
}
@@ -2013,10 +2028,9 @@ String* DescriptorArray::GetSortedKey(int 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());
+void DescriptorArray::SetSortedKey(int descriptor_index, int pointer) {
+ PropertyDetails details = GetDetails(descriptor_index);
+ set(ToDetailsIndex(descriptor_index), details.set_pointer(pointer).AsSmi());
}
@@ -2100,21 +2114,22 @@ void DescriptorArray::Set(int descriptor_number,
void DescriptorArray::Append(Descriptor* desc,
const WhitenessWitness& witness,
int number_of_set_descriptors) {
- int enumeration_index = number_of_set_descriptors + 1;
+ int descriptor_number = number_of_set_descriptors;
+ int enumeration_index = descriptor_number + 1;
desc->SetEnumerationIndex(enumeration_index);
- Set(number_of_set_descriptors, desc, witness);
+ Set(descriptor_number, desc, witness);
uint32_t hash = desc->GetKey()->Hash();
int insertion;
- for (insertion = number_of_set_descriptors; insertion > 0; --insertion) {
+ for (insertion = descriptor_number; insertion > 0; --insertion) {
String* key = GetSortedKey(insertion - 1);
if (key->Hash() <= hash) break;
SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
}
- SetSortedKey(insertion, number_of_set_descriptors);
+ SetSortedKey(insertion, descriptor_number);
}
@@ -3013,6 +3028,16 @@ Code::Flags Code::flags() {
}
+void Map::set_owns_descriptors(bool is_shared) {
+ set_bit_field3(OwnsDescriptors::update(bit_field3(), is_shared));
+}
+
+
+bool Map::owns_descriptors() {
+ return OwnsDescriptors::decode(bit_field3());
+}
+
+
void Code::set_flags(Code::Flags flags) {
STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
// Make sure that all call stubs have an arguments count.
@@ -3448,9 +3473,17 @@ void Map::set_prototype(Object* value, WriteBarrierMode mode) {
}
+JSGlobalPropertyCell* Map::descriptors_pointer() {
+ ASSERT(HasTransitionArray());
+ return transitions()->descriptors_pointer();
+}
+
+
DescriptorArray* Map::instance_descriptors() {
- if (!HasTransitionArray()) return GetHeap()->empty_descriptor_array();
- return transitions()->descriptors();
+ if (HasTransitionArray()) return transitions()->descriptors();
+ Object* back_pointer = GetBackPointer();
+ if (!back_pointer->IsMap()) return GetHeap()->empty_descriptor_array();
+ return Map::cast(back_pointer)->instance_descriptors();
}
@@ -3460,29 +3493,31 @@ static MaybeObject* EnsureHasTransitionArray(Map* map) {
if (map->HasTransitionArray()) return map;
TransitionArray* transitions;
- MaybeObject* maybe_transitions = TransitionArray::Allocate(0);
+ JSGlobalPropertyCell* pointer = map->RetrieveDescriptorsPointer();
+ MaybeObject* maybe_transitions = TransitionArray::Allocate(0, pointer);
if (!maybe_transitions->To(&transitions)) return maybe_transitions;
+
+ transitions->set_back_pointer_storage(map->GetBackPointer());
map->set_transitions(transitions);
return transitions;
}
-MaybeObject* Map::SetDescriptors(DescriptorArray* value,
- WriteBarrierMode mode) {
+MaybeObject* Map::SetDescriptors(DescriptorArray* value) {
ASSERT(!is_shared());
MaybeObject* maybe_failure = EnsureHasTransitionArray(this);
if (maybe_failure->IsFailure()) return maybe_failure;
- transitions()->set_descriptors(value, mode);
+ ASSERT(NumberOfOwnDescriptors() <= value->number_of_descriptors());
+ transitions()->set_descriptors(value);
return this;
}
MaybeObject* Map::InitializeDescriptors(DescriptorArray* descriptors) {
-#ifdef DEBUG
int len = descriptors->number_of_descriptors();
+#ifdef DEBUG
ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors);
- SLOW_ASSERT(descriptors->IsSortedNoDuplicates());
bool used_indices[DescriptorArray::kMaxNumberOfDescriptors];
for (int i = 0; i < len; ++i) used_indices[i] = false;
@@ -3501,8 +3536,7 @@ MaybeObject* Map::InitializeDescriptors(DescriptorArray* descriptors) {
MaybeObject* maybe_failure = SetDescriptors(descriptors);
if (maybe_failure->IsFailure()) return maybe_failure;
- SetNumberOfOwnDescriptors(descriptors->number_of_descriptors());
-
+ SetNumberOfOwnDescriptors(len);
return this;
}
@@ -3571,9 +3605,21 @@ bool Map::CanHaveMoreTransitions() {
}
+JSGlobalPropertyCell* Map::RetrieveDescriptorsPointer() {
+ if (!owns_descriptors()) return NULL;
+ Object* back_pointer = GetBackPointer();
+ if (back_pointer->IsUndefined()) return NULL;
+ Map* map = Map::cast(back_pointer);
+ ASSERT(map->HasTransitionArray());
+ return map->transitions()->descriptors_pointer();
+}
+
+
MaybeObject* Map::AddTransition(String* key, Map* target) {
if (HasTransitionArray()) return transitions()->CopyInsert(key, target);
- return TransitionArray::NewWith(key, target);
+ JSGlobalPropertyCell* descriptors_pointer = RetrieveDescriptorsPointer();
+ return TransitionArray::NewWith(
+ key, target, descriptors_pointer, GetBackPointer());
}
@@ -3582,6 +3628,11 @@ void Map::SetTransition(int transition_index, Map* target) {
}
+Map* Map::GetTransition(int transition_index) {
+ return transitions()->GetTarget(transition_index);
+}
+
+
MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
MaybeObject* allow_elements = EnsureHasTransitionArray(this);
if (allow_elements->IsFailure()) return allow_elements;
@@ -3627,8 +3678,6 @@ TransitionArray* Map::transitions() {
void Map::set_transitions(TransitionArray* transition_array,
WriteBarrierMode mode) {
- transition_array->set_descriptors(instance_descriptors());
- transition_array->set_back_pointer_storage(GetBackPointer());
#ifdef DEBUG
if (HasTransitionArray()) {
ASSERT(transitions() != transition_array);
« no previous file with comments | « src/objects-debug.cc ('k') | src/profile-generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698