v8/test/mjsunit/shared-memory/shared-array-surface.js
Shu-yu Guo bd5b3ae542 [shared-struct] Store length per-SharedArray instance
With shared space (instead of the shared isolate), the AccessorInfo
implementation of SharedArray's length property is no longer threadsafe.
Until AccessorInfos can be put into shared or RO space, go back to
storing the length field as a per-instance in-object field, which is
unfrotunately a little wasteful.

Bug: v8:12547
Change-Id: I99c1cbf26047da48a4b4c11e14ab7def7d4e4f60
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4039309
Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
Auto-Submit: Shu-yu Guo <syg@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84408}
2022-11-21 22:14:15 +00:00

122 lines
2.9 KiB
JavaScript

// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Flags: --shared-string-table --harmony-struct
'use strict';
(function TestNoPrototype() {
// For now the experimental shared arrays don't have a prototype.
assertNull(Object.getPrototypeOf(new SharedArray(10)));
assertNull(SharedArray.prototype);
assertThrows(() => {
SharedArray.prototype = {};
});
})();
(function TestPrimitives() {
// All primitives can be stored in fields.
let test_values =
[42, -0, Math.random(), undefined, null, true, false, 'foo'];
let arr = new SharedArray(test_values.length);
let i = 0;
for (let prim of test_values) {
arr[i] = prim;
assertEquals(arr[i], prim);
i++;
}
})();
(function TestObjects() {
let arr = new SharedArray(5);
// Shared objects cannot point to non-shared objects.
assertThrows(() => {
arr[0] = [];
});
assertThrows(() => {
arr[1] = {};
});
// Shared objects can point to other shared objects.
let S = new SharedStructType(['field']);
let shared_rhs = new S();
arr[3] = shared_rhs;
assertEquals(arr[3], shared_rhs);
shared_rhs = new SharedArray(10)
arr[4] = shared_rhs;
assertEquals(arr[4], shared_rhs);
})();
(function TestNotExtensible() {
let arr = new SharedArray(1);
// Shared structs are non-extensible.
assertThrows(() => {
arr[1] = 42;
});
assertThrows(() => {
Object.setPrototypeOf(arr, {});
});
assertThrows(() => {
Object.defineProperty(arr, 'nonExistent', {value: 42});
});
})();
(function TestBounds() {
// Max SharedArray size is 2**14-2.
assertDoesNotThrow(() => {
new SharedArray(2 ** 14 - 2);
});
assertThrows(
() => {
new SharedArray(2 ** 14 - 1);
},
RangeError,
'SharedArray length out of range (maximum of 2**14-2 allowed)');
assertThrows(
() => {
new SharedArray(-1);
},
RangeError,
'SharedArray length out of range (maximum of 2**14-2 allowed)');
})();
(function TestOwnPropertyEnumeration() {
let shared_array = new SharedArray(2);
shared_array[0] = 42;
assertEquals(2, shared_array.length);
let propDescs = Object.getOwnPropertyDescriptors(shared_array);
let desc = propDescs[0];
assertEquals(true, desc.writable);
assertEquals(false, desc.configurable);
assertEquals(true, desc.enumerable);
assertEquals(42, desc.value);
let vals = Object.values(shared_array);
assertArrayEquals([42, undefined], vals);
let entries = Object.entries(shared_array);
assertEquals(2, entries.length);
assertArrayEquals(['0', 42], entries[0]);
})();
(function TestForIn() {
let shared_array = new SharedArray(2);
let i = 0;
for (let index in shared_array) {
assertEquals(index, String(i));
i++;
}
})();
(function TestProxyLengthGetter() {
let a = new SharedArray(2);
let proxy = new Proxy(a, {});
assertEquals(2, proxy.length);
})();