Version 3.17.8

Added missing license headers. (Chromium issue 98597)

Inserted missing type cast in JSON.stringify. (issue 2570)

Reverted "Send SIGPROF signals on the profiler event processor thread" (issue 2571)

Fixed Array.length, String.length and Function.prototype LoadICs on x64. (issue 2568)

ES6 symbols: filter symbols form for-in loops and Object.keys. (issue 2158)

Properly handle misses for StoreArrayLengthStub on ia32 and x64 (issue 2566)

Fixed x32 handling of Atomic64. (Chromium issue chromium-os:36866)

Removed "library" variable from standalone.gypi. (Chromium issue 111541)

Fixed HCheckSmiOrInt <-> HBoundsCheck interaction wrt. representations. (issue 2556)

Enabled zapping of disposed global handles in release mode. (Chromium issue 176056)

Added workaround for redefinition of __proto__ property. (issue 2565)

ES6 symbols: Allow symbols as property names. (issue 2158)

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@13864 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/heap.cc b/src/heap.cc
index 7ce9263..4f85705 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -2865,14 +2865,14 @@
   CreateFixedStubs();
 
   // Allocate the dictionary of intrinsic function names.
-  { MaybeObject* maybe_obj = StringDictionary::Allocate(Runtime::kNumFunctions);
+  { MaybeObject* maybe_obj = NameDictionary::Allocate(Runtime::kNumFunctions);
     if (!maybe_obj->ToObject(&obj)) return false;
   }
   { MaybeObject* maybe_obj = Runtime::InitializeIntrinsicFunctionNames(this,
                                                                        obj);
     if (!maybe_obj->ToObject(&obj)) return false;
   }
-  set_intrinsic_function_names(StringDictionary::cast(obj));
+  set_intrinsic_function_names(NameDictionary::cast(obj));
 
   { MaybeObject* maybe_obj = AllocateInitialNumberStringCache();
     if (!maybe_obj->ToObject(&obj)) return false;
@@ -4066,9 +4066,9 @@
 static bool HasDuplicates(DescriptorArray* descriptors) {
   int count = descriptors->number_of_descriptors();
   if (count > 1) {
-    String* prev_key = descriptors->GetKey(0);
+    Name* prev_key = descriptors->GetKey(0);
     for (int i = 1; i != count; i++) {
-      String* current_key = descriptors->GetKey(i);
+      Name* current_key = descriptors->GetKey(i);
       if (prev_key == current_key) return true;
       prev_key = current_key;
     }
@@ -4521,9 +4521,9 @@
   int initial_size = map->instance_type() == JS_GLOBAL_OBJECT_TYPE ? 64 : 512;
 
   // Allocate a dictionary object for backing storage.
-  StringDictionary* dictionary;
+  NameDictionary* dictionary;
   MaybeObject* maybe_dictionary =
-      StringDictionary::Allocate(
+      NameDictionary::Allocate(
           map->NumberOfOwnDescriptors() * 2 + initial_size);
   if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
 
@@ -7443,7 +7443,7 @@
 }
 
 
-int KeyedLookupCache::Hash(Map* map, String* name) {
+int KeyedLookupCache::Hash(Map* map, Name* name) {
   // Uses only lower 32 bits if pointers are larger.
   uintptr_t addr_hash =
       static_cast<uint32_t>(reinterpret_cast<uintptr_t>(map)) >> kMapHashShift;
@@ -7451,7 +7451,7 @@
 }
 
 
-int KeyedLookupCache::Lookup(Map* map, String* name) {
+int KeyedLookupCache::Lookup(Map* map, Name* name) {
   int index = (Hash(map, name) & kHashMask);
   for (int i = 0; i < kEntriesPerBucket; i++) {
     Key& key = keys_[index + i];
@@ -7463,37 +7463,43 @@
 }
 
 
-void KeyedLookupCache::Update(Map* map, String* name, int field_offset) {
-  String* internalized_name;
-  if (HEAP->InternalizeStringIfExists(name, &internalized_name)) {
-    int index = (Hash(map, internalized_name) & kHashMask);
-    // After a GC there will be free slots, so we use them in order (this may
-    // help to get the most frequently used one in position 0).
-    for (int i = 0; i< kEntriesPerBucket; i++) {
-      Key& key = keys_[index];
-      Object* free_entry_indicator = NULL;
-      if (key.map == free_entry_indicator) {
-        key.map = map;
-        key.name = internalized_name;
-        field_offsets_[index + i] = field_offset;
-        return;
-      }
+void KeyedLookupCache::Update(Map* map, Name* name, int field_offset) {
+  if (!name->IsUniqueName()) {
+    String* internalized_string;
+    if (!HEAP->InternalizeStringIfExists(
+            String::cast(name), &internalized_string)) {
+      return;
     }
-    // No free entry found in this bucket, so we move them all down one and
-    // put the new entry at position zero.
-    for (int i = kEntriesPerBucket - 1; i > 0; i--) {
-      Key& key = keys_[index + i];
-      Key& key2 = keys_[index + i - 1];
-      key = key2;
-      field_offsets_[index + i] = field_offsets_[index + i - 1];
-    }
-
-    // Write the new first entry.
-    Key& key = keys_[index];
-    key.map = map;
-    key.name = internalized_name;
-    field_offsets_[index] = field_offset;
+    name = internalized_string;
   }
+
+  int index = (Hash(map, name) & kHashMask);
+  // After a GC there will be free slots, so we use them in order (this may
+  // help to get the most frequently used one in position 0).
+  for (int i = 0; i< kEntriesPerBucket; i++) {
+    Key& key = keys_[index];
+    Object* free_entry_indicator = NULL;
+    if (key.map == free_entry_indicator) {
+      key.map = map;
+      key.name = name;
+      field_offsets_[index + i] = field_offset;
+      return;
+    }
+  }
+  // No free entry found in this bucket, so we move them all down one and
+  // put the new entry at position zero.
+  for (int i = kEntriesPerBucket - 1; i > 0; i--) {
+    Key& key = keys_[index + i];
+    Key& key2 = keys_[index + i - 1];
+    key = key2;
+    field_offsets_[index + i] = field_offsets_[index + i - 1];
+  }
+
+  // Write the new first entry.
+  Key& key = keys_[index];
+  key.map = map;
+  key.name = name;
+  field_offsets_[index] = field_offset;
 }