Author: [email protected]
Date: Mon Jun 22 07:29:35 2009
New Revision: 2239
Modified:
branches/bleeding_edge/src/heap.cc
branches/bleeding_edge/src/heap.h
branches/bleeding_edge/src/objects-inl.h
branches/bleeding_edge/src/objects.cc
Log:
Added descriptor lookup cache to eliminate some search overhead.
Reduced the KeyedLookupCache length to 64.
Review URL: http://codereview.chromium.org/141046
Modified: branches/bleeding_edge/src/heap.cc
==============================================================================
--- branches/bleeding_edge/src/heap.cc (original)
+++ branches/bleeding_edge/src/heap.cc Mon Jun 22 07:29:35 2009
@@ -502,6 +502,7 @@
// maps.
KeyedLookupCache::Clear();
ContextSlotCache::Clear();
+ DescriptorLookupCache::Clear();
CompilationCache::MarkCompactPrologue();
@@ -630,6 +631,9 @@
// Implements Cheney's copying algorithm
LOG(ResourceEvent("scavenge", "begin"));
+ // Clear descriptor cache.
+ DescriptorLookupCache::Clear();
+
// Used for updating survived_since_last_expansion_ at function end.
int survived_watermark = PromotedSpaceSize();
@@ -1392,6 +1396,9 @@
// Initialize context slot cache.
ContextSlotCache::Clear();
+ // Initialize descriptor cache.
+ DescriptorLookupCache::Clear();
+
// Initialize compilation cache.
CompilationCache::Clear();
@@ -3557,6 +3564,17 @@
int KeyedLookupCache::field_offsets_[KeyedLookupCache::kLength];
+
+
+void DescriptorLookupCache::Clear() {
+ for (int index = 0; index < kLength; index++) keys_[index].array = NULL;
+}
+
+
+DescriptorLookupCache::Key
+DescriptorLookupCache::keys_[DescriptorLookupCache::kLength];
+
+int DescriptorLookupCache::results_[DescriptorLookupCache::kLength];
#ifdef DEBUG
Modified: branches/bleeding_edge/src/heap.h
==============================================================================
--- branches/bleeding_edge/src/heap.h (original)
+++ branches/bleeding_edge/src/heap.h Mon Jun 22 07:29:35 2009
@@ -1148,13 +1148,67 @@
static void Clear();
private:
inline static int Hash(Map* map, String* name);
- static const int kLength = 128;
+ static const int kLength = 64;
struct Key {
Map* map;
String* name;
};
static Key keys_[kLength];
static int field_offsets_[kLength];
+};
+
+
+
+// Cache for mapping (array, property name) into descriptor index.
+// The cache contains both positive and negative results.
+// Descriptor index equals kNotFound means the property is absent.
+// Cleared at startup and prior to any gc.
+class DescriptorLookupCache {
+ public:
+ // Lookup descriptor index for (map, name).
+ // If absent, kAbsent is returned.
+ static int Lookup(DescriptorArray* array, String* name) {
+ if(!StringShape(name).IsSymbol()) return kAbsent;
+ int index = Hash(array, name);
+ Key& key = keys_[index];
+ if ((key.array == array) && (key.name == name)) return results_[index];
+ return kAbsent;
+ }
+
+ // Update an element in the cache.
+ static void Update(DescriptorArray* array, String* name, int result) {
+ ASSERT(result != kAbsent);
+ if(StringShape(name).IsSymbol()) {
+ int index = Hash(array, name);
+ Key& key = keys_[index];
+ key.array = array;
+ key.name = name;
+ results_[index] = result;
+ }
+ }
+
+ // Clear the cache.
+ static void Clear();
+
+ static const int kAbsent = -2;
+ private:
+ static int Hash(DescriptorArray* array, String* name) {
+ // Uses only lower 32 bits if pointers are larger.
+ uintptr_t array_hash =
+ static_cast<uint32_t>(reinterpret_cast<uintptr_t>(array)) >> 2;
+ uintptr_t name_hash =
+ static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name)) >> 2;
+ return (array_hash ^ name_hash) % kLength;
+ }
+
+ static const int kLength = 64;
+ struct Key {
+ DescriptorArray* array;
+ String* name;
+ };
+
+ static Key keys_[kLength];
+ static int results_[kLength];
};
Modified: branches/bleeding_edge/src/objects-inl.h
==============================================================================
--- branches/bleeding_edge/src/objects-inl.h (original)
+++ branches/bleeding_edge/src/objects-inl.h Mon Jun 22 07:29:35 2009
@@ -1299,7 +1299,6 @@
}
-
String* DescriptorArray::GetKey(int descriptor_number) {
ASSERT(descriptor_number < number_of_descriptors());
return String::cast(get(ToKeyIndex(descriptor_number)));
Modified: branches/bleeding_edge/src/objects.cc
==============================================================================
--- branches/bleeding_edge/src/objects.cc (original)
+++ branches/bleeding_edge/src/objects.cc Mon Jun 22 07:29:35 2009
@@ -1565,7 +1565,11 @@
void JSObject::LookupInDescriptor(String* name, LookupResult* result) {
DescriptorArray* descriptors = map()->instance_descriptors();
- int number = descriptors->Search(name);
+ int number = DescriptorLookupCache::Lookup(descriptors, name);
+ if (number == DescriptorLookupCache::kAbsent) {
+ number = descriptors->Search(name);
+ DescriptorLookupCache::Update(descriptors, name, number);
+ }
if (number != DescriptorArray::kNotFound) {
result->DescriptorResult(this, descriptors->GetDetails(number),
number);
} else {
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---