Reviewers: Toon Verwaest,

Description:
Fix Object.freeze on dictionary-backed arrays to properly freeze elements

Follow-up to r14758: slightly rearranges JSObject::Freeze() to avoid duplicating
code while still retaining proper dictionary elements storage behavior.

Also fix a lint error.

Please review this at https://codereview.chromium.org/15737018/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/objects.cc
  M test/mjsunit/object-freeze.js


Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 375034c18c31551376c9dc625b0309b65a6e985a..2c8c339d996bd6429c7dc534605971893ed48be0 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -5408,17 +5408,12 @@ MUST_USE_RESULT MaybeObject* JSObject::Freeze(Isolate* isolate) {
       GetElementsCapacityAndUsage(&capacity, &used);
MaybeObject* maybe_dict = SeededNumberDictionary::Allocate(heap, used);
       if (!maybe_dict->To(&new_element_dictionary)) return maybe_dict;
-      // Make sure that we never go back to fast case.
-      new_element_dictionary->set_requires_slow_elements();

// Move elements to a dictionary; avoid calling NormalizeElements to avoid
       // unnecessary transitions.
maybe_dict = CopyFastElementsToDictionary(isolate, elements(), length,
                                                 new_element_dictionary);
       if (!maybe_dict->To(&new_element_dictionary)) return maybe_dict;
-
-      // Freeze all the elements in the dictionary.
-      FreezeDictionary(new_element_dictionary);
     } else {
       // No existing elements, use a pre-allocated empty backing store
       new_element_dictionary = heap->empty_slow_element_dictionary();
@@ -5470,8 +5465,17 @@ MUST_USE_RESULT MaybeObject* JSObject::Freeze(Isolate* isolate) {
   }

   ASSERT(map()->has_dictionary_elements());
-  if (new_element_dictionary != NULL)
+  if (new_element_dictionary != NULL) {
     set_elements(new_element_dictionary);
+  }
+
+  if (elements() != heap->empty_slow_element_dictionary()) {
+    SeededNumberDictionary* dictionary = element_dictionary();
+    // Make sure we never go back to the fast case
+    dictionary->set_requires_slow_elements();
+    // Freeze all elements in the dictionary
+    FreezeDictionary(dictionary);
+  }

   return this;
 }
Index: test/mjsunit/object-freeze.js
diff --git a/test/mjsunit/object-freeze.js b/test/mjsunit/object-freeze.js
index 6a177a4441fcc2ecb34a3dc16e07fc101ce267c2..619ada006ea710e1a26ba25b67b3e6ecdfed1530 100644
--- a/test/mjsunit/object-freeze.js
+++ b/test/mjsunit/object-freeze.js
@@ -253,3 +253,9 @@ var func = function(arg) {
 };
 func('hello', 'world');
 func('goodbye', 'world');
+
+// Freezing sparse arrays
+var sparseArr = [0, 1];
+sparseArr[10000] = 10000;
+Object.freeze(sparseArr);
+assertTrue(Object.isFrozen(sparseArr));


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to