Commit 56873d96 authored by Z Duong Nguyen-Huu's avatar Z Duong Nguyen-Huu Committed by Commit Bot

Handle COW map for sealed, frozen object

Basically, SetPropertyInternal is called without handling COW map.

Improve test coverage as well.

Bug: chromium:951438
Change-Id: Iea8c818ab6a8ddea204f86a9d676a1ea42fd07f0
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1562731
Commit-Queue: Z Nguyen-Huu <duongn@microsoft.com>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60834}
parent e65e5014
...@@ -157,6 +157,10 @@ inline bool IsFrozenOrSealedElementsKind(ElementsKind kind) { ...@@ -157,6 +157,10 @@ inline bool IsFrozenOrSealedElementsKind(ElementsKind kind) {
return IsInRange(kind, PACKED_SEALED_ELEMENTS, PACKED_FROZEN_ELEMENTS); return IsInRange(kind, PACKED_SEALED_ELEMENTS, PACKED_FROZEN_ELEMENTS);
} }
inline bool IsSealedElementsKind(ElementsKind kind) {
return kind == PACKED_SEALED_ELEMENTS;
}
inline bool IsSmiOrObjectElementsKind(ElementsKind kind) { inline bool IsSmiOrObjectElementsKind(ElementsKind kind) {
return kind == PACKED_SMI_ELEMENTS || kind == HOLEY_SMI_ELEMENTS || return kind == PACKED_SMI_ELEMENTS || kind == HOLEY_SMI_ELEMENTS ||
kind == PACKED_ELEMENTS || kind == HOLEY_ELEMENTS; kind == PACKED_ELEMENTS || kind == HOLEY_ELEMENTS;
......
...@@ -459,7 +459,7 @@ void LookupIterator::PrepareForDataProperty(Handle<Object> value) { ...@@ -459,7 +459,7 @@ void LookupIterator::PrepareForDataProperty(Handle<Object> value) {
} }
// Copy the backing store if it is copy-on-write. // Copy the backing store if it is copy-on-write.
if (IsSmiOrObjectElementsKind(to)) { if (IsSmiOrObjectElementsKind(to) || IsSealedElementsKind(to)) {
JSObject::EnsureWritableFastElements(holder_obj); JSObject::EnsureWritableFastElements(holder_obj);
} }
return; return;
......
...@@ -2059,7 +2059,8 @@ MaybeHandle<JSObject> JSObject::ObjectCreate(Isolate* isolate, ...@@ -2059,7 +2059,8 @@ MaybeHandle<JSObject> JSObject::ObjectCreate(Isolate* isolate,
void JSObject::EnsureWritableFastElements(Handle<JSObject> object) { void JSObject::EnsureWritableFastElements(Handle<JSObject> object) {
DCHECK(object->HasSmiOrObjectElements() || DCHECK(object->HasSmiOrObjectElements() ||
object->HasFastStringWrapperElements()); object->HasFastStringWrapperElements() ||
object->HasFrozenOrSealedElements());
FixedArray raw_elems = FixedArray::cast(object->elements()); FixedArray raw_elems = FixedArray::cast(object->elements());
Isolate* isolate = object->GetIsolate(); Isolate* isolate = object->GetIsolate();
if (raw_elems->map() != ReadOnlyRoots(isolate).fixed_cow_array_map()) return; if (raw_elems->map() != ReadOnlyRoots(isolate).fixed_cow_array_map()) return;
......
...@@ -414,6 +414,7 @@ function testPackedFrozenArray1(obj) { ...@@ -414,6 +414,7 @@ function testPackedFrozenArray1(obj) {
assertTrue(Array.isArray(obj)); assertTrue(Array.isArray(obj));
assertThrows(function() { obj.pop(); }, TypeError); assertThrows(function() { obj.pop(); }, TypeError);
assertThrows(function() { obj.push(); }, TypeError); assertThrows(function() { obj.push(); }, TypeError);
assertThrows(function() { obj.shift(); }, TypeError);
assertThrows(function() { obj.unshift(); }, TypeError); assertThrows(function() { obj.unshift(); }, TypeError);
assertThrows(function() { obj.copyWithin(0,0); }, TypeError); assertThrows(function() { obj.copyWithin(0,0); }, TypeError);
assertThrows(function() { obj.fill(0); }, TypeError); assertThrows(function() { obj.fill(0); }, TypeError);
...@@ -545,3 +546,9 @@ assertThrows(function() { ...@@ -545,3 +546,9 @@ assertThrows(function() {
value: obj, value: obj,
}); });
}, TypeError); }, TypeError);
// Regression test with simple array
var arr = ['a'];
Object.freeze(arr);
arr[0] = 'b';
assertEquals(arr[0], 'a');
...@@ -172,6 +172,7 @@ assertTrue(Array.isArray(obj)); ...@@ -172,6 +172,7 @@ assertTrue(Array.isArray(obj));
// Verify that the length can't be written by builtins. // Verify that the length can't be written by builtins.
assertThrows(function() { obj.push(1); }, TypeError); assertThrows(function() { obj.push(1); }, TypeError);
assertDoesNotThrow(function() { obj.shift(); });
assertThrows(function() { obj.unshift(1); }, TypeError); assertThrows(function() { obj.unshift(1); }, TypeError);
assertThrows(function() { obj.splice(0, 0, 1); }, TypeError); assertThrows(function() { obj.splice(0, 0, 1); }, TypeError);
assertDoesNotThrow(function() {obj.splice(0, 0)}); assertDoesNotThrow(function() {obj.splice(0, 0)});
...@@ -250,3 +251,9 @@ arr.fill('d'); ...@@ -250,3 +251,9 @@ arr.fill('d');
assertEquals(arr.join(''), "ddd"); assertEquals(arr.join(''), "ddd");
arr.pop(); arr.pop();
assertEquals(arr.join(''), "dd"); assertEquals(arr.join(''), "dd");
// Regression test with simple array
var arr = ['a'];
Object.preventExtensions(arr);
arr[0] = 'b';
assertEquals(arr[0], 'b');
...@@ -402,6 +402,7 @@ function testPackedSealedArray1(obj) { ...@@ -402,6 +402,7 @@ function testPackedSealedArray1(obj) {
// Verify that the length can't be written by builtins. // Verify that the length can't be written by builtins.
assertThrows(function() { obj.pop(); }, TypeError); assertThrows(function() { obj.pop(); }, TypeError);
assertThrows(function() { obj.push(1); }, TypeError); assertThrows(function() { obj.push(1); }, TypeError);
assertThrows(function() { obj.shift(); }, TypeError);
assertThrows(function() { obj.unshift(1); }, TypeError); assertThrows(function() { obj.unshift(1); }, TypeError);
assertThrows(function() { obj.splice(0); }, TypeError); assertThrows(function() { obj.splice(0); }, TypeError);
assertDoesNotThrow(function() { obj.splice(0, 0); }); assertDoesNotThrow(function() { obj.splice(0, 0); });
...@@ -521,3 +522,9 @@ assertThrows(function() { ...@@ -521,3 +522,9 @@ assertThrows(function() {
value: obj, value: obj,
}); });
}, TypeError); }, TypeError);
// Regression test with simple array
var arr = ['a'];
Object.seal(arr);
arr[0] = 'b';
assertEquals(arr[0], 'b');
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