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
-~----------~----~----~----~------~----~------~--~---

Reply via email to