From 3ebccb7aae31a26efaebc674ebc5a8a62b6be621 Mon Sep 17 00:00:00 2001 From: "adamk@chromium.org" Date: Wed, 22 May 2013 20:40:04 +0000 Subject: [PATCH] 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. R=verwaest@chromium.org Review URL: https://codereview.chromium.org/15737018 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14759 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/objects.cc | 16 ++++++++++------ test/mjsunit/object-freeze.js | 6 ++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/objects.cc b/src/objects.cc index 375034c..2c8c339 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; } diff --git a/test/mjsunit/object-freeze.js b/test/mjsunit/object-freeze.js index 6a177a4..619ada0 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)); -- 2.7.4