Commit 3ebccb7a authored by adamk@chromium.org's avatar adamk@chromium.org

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
parent 648e99e3
...@@ -5408,17 +5408,12 @@ MUST_USE_RESULT MaybeObject* JSObject::Freeze(Isolate* isolate) { ...@@ -5408,17 +5408,12 @@ MUST_USE_RESULT MaybeObject* JSObject::Freeze(Isolate* isolate) {
GetElementsCapacityAndUsage(&capacity, &used); GetElementsCapacityAndUsage(&capacity, &used);
MaybeObject* maybe_dict = SeededNumberDictionary::Allocate(heap, used); MaybeObject* maybe_dict = SeededNumberDictionary::Allocate(heap, used);
if (!maybe_dict->To(&new_element_dictionary)) return maybe_dict; 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 // Move elements to a dictionary; avoid calling NormalizeElements to avoid
// unnecessary transitions. // unnecessary transitions.
maybe_dict = CopyFastElementsToDictionary(isolate, elements(), length, maybe_dict = CopyFastElementsToDictionary(isolate, elements(), length,
new_element_dictionary); new_element_dictionary);
if (!maybe_dict->To(&new_element_dictionary)) return maybe_dict; if (!maybe_dict->To(&new_element_dictionary)) return maybe_dict;
// Freeze all the elements in the dictionary.
FreezeDictionary(new_element_dictionary);
} else { } else {
// No existing elements, use a pre-allocated empty backing store // No existing elements, use a pre-allocated empty backing store
new_element_dictionary = heap->empty_slow_element_dictionary(); new_element_dictionary = heap->empty_slow_element_dictionary();
...@@ -5470,8 +5465,17 @@ MUST_USE_RESULT MaybeObject* JSObject::Freeze(Isolate* isolate) { ...@@ -5470,8 +5465,17 @@ MUST_USE_RESULT MaybeObject* JSObject::Freeze(Isolate* isolate) {
} }
ASSERT(map()->has_dictionary_elements()); ASSERT(map()->has_dictionary_elements());
if (new_element_dictionary != NULL) if (new_element_dictionary != NULL) {
set_elements(new_element_dictionary); 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; return this;
} }
......
...@@ -253,3 +253,9 @@ var func = function(arg) { ...@@ -253,3 +253,9 @@ var func = function(arg) {
}; };
func('hello', 'world'); func('hello', 'world');
func('goodbye', 'world'); func('goodbye', 'world');
// Freezing sparse arrays
var sparseArr = [0, 1];
sparseArr[10000] = 10000;
Object.freeze(sparseArr);
assertTrue(Object.isFrozen(sparseArr));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment