Commit 093ae17e authored by Stephan Herhut's avatar Stephan Herhut Committed by Commit Bot

Do not register shared array buffer backing stores with v8

There is a mechanism that registers the size of the backing store of a
typed array with v8 if such backing store is used by a typed array in a
v8 isolate. This is done so that v8 can properly assess the memory
pressure of an isolate in the presence of external allocations.

With shared array buffers, we can no longer attribute a buffer to a
specific isolate, as it might be used by multiple isolates at the
same time. The current implementation tries to work around this by
only registering with one isolate but ultimately fails at doing so,
leading to false data.

As a stop-gap fix, this change disables registering of shared buffers
completely to at least keep the data consistent while we design a
working solution.

Change-Id: Ib007cbad6af80e6c82d6ab809bf14ce95c54fc93
Bug: chromium:877055
Reviewed-on: https://chromium-review.googlesource.com/1186461
Commit-Queue: Stephan Herhut <herhut@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#585527}
parent 4f6427c2
Test sharing SharedArrayBuffers between dedicated workers.
Running SharedArrayBuffer test case
PASS: Passing SharedArrayBuffer in the transfer list threw.
PASS: SharedArrayBuffer not neutered during transfer.
PASS: Original data not changed during transfer.
PASS: Transferred data is OK.
PASS: Transferred data is OK.
Running Int8Array test case
PASS: Passing SharedArrayBuffer in the transfer list threw.
PASS: SharedArrayBuffer not neutered during transfer.
PASS: Original data not changed during transfer.
PASS: Transferred array type is OK.
PASS: Transferred data is OK.
PASS: Transferred array type is OK.
PASS: Transferred data is OK.
Running Uint8Array test case
PASS: Passing SharedArrayBuffer in the transfer list threw.
PASS: SharedArrayBuffer not neutered during transfer.
PASS: Original data not changed during transfer.
PASS: Transferred array type is OK.
PASS: Transferred data is OK.
PASS: Transferred array type is OK.
PASS: Transferred data is OK.
Running Uint8ClampedArray test case
PASS: Passing SharedArrayBuffer in the transfer list threw.
PASS: SharedArrayBuffer not neutered during transfer.
PASS: Original data not changed during transfer.
PASS: Transferred array type is OK.
PASS: Transferred data is OK.
PASS: Transferred array type is OK.
PASS: Transferred data is OK.
Running Int16Array test case
PASS: Passing SharedArrayBuffer in the transfer list threw.
PASS: SharedArrayBuffer not neutered during transfer.
PASS: Original data not changed during transfer.
PASS: Transferred array type is OK.
PASS: Transferred data is OK.
PASS: Transferred array type is OK.
PASS: Transferred data is OK.
Running Uint16Array test case
PASS: Passing SharedArrayBuffer in the transfer list threw.
PASS: SharedArrayBuffer not neutered during transfer.
PASS: Original data not changed during transfer.
PASS: Transferred array type is OK.
PASS: Transferred data is OK.
PASS: Transferred array type is OK.
PASS: Transferred data is OK.
Running Int32Array test case
PASS: Passing SharedArrayBuffer in the transfer list threw.
PASS: SharedArrayBuffer not neutered during transfer.
PASS: Original data not changed during transfer.
PASS: Transferred array type is OK.
PASS: Transferred data is OK.
PASS: Transferred array type is OK.
PASS: Transferred data is OK.
Running Uint32Array test case
PASS: Passing SharedArrayBuffer in the transfer list threw.
PASS: SharedArrayBuffer not neutered during transfer.
PASS: Original data not changed during transfer.
PASS: Transferred array type is OK.
PASS: Transferred data is OK.
PASS: Transferred array type is OK.
PASS: Transferred data is OK.
Running Float32Array test case
PASS: Passing SharedArrayBuffer in the transfer list threw.
PASS: SharedArrayBuffer not neutered during transfer.
PASS: Original data not changed during transfer.
PASS: Transferred array type is OK.
PASS: Transferred data is OK.
PASS: Transferred array type is OK.
PASS: Transferred data is OK.
Running Float64Array test case
PASS: Passing SharedArrayBuffer in the transfer list threw.
PASS: SharedArrayBuffer not neutered during transfer.
PASS: Original data not changed during transfer.
PASS: Transferred array type is OK.
PASS: Transferred data is OK.
PASS: Transferred array type is OK.
PASS: Transferred data is OK.
DONE
<!DOCTYPE html>
<html>
<body>
<p>Test sharing SharedArrayBuffers between dedicated workers.</p>
<div id="result"></div>
<script type="text/javascript">
function log(message)
{
document.getElementById("result").innerHTML += message + "</br>";
}
var testCases = [
"testSendSharedArrayBuffer",
"testSendInt8Array",
"testSendUint8Array",
"testSendUint8ClampedArray",
"testSendInt16Array",
"testSendUint16Array",
"testSendInt32Array",
"testSendUint32Array",
"testSendFloat32Array",
"testSendFloat64Array",
];
var testIndex = 0;
function logPendingMessages() {
if (pendingWorkerReplies > 0) return;
workerMessages.forEach(log);
workerMessages = [];
secondaryWorkerMessages.forEach(log);
secondaryWorkerMessages = [];
}
function runNextTest()
{
if (pendingWorkerReplies > 0) return;
if (testIndex < testCases.length) {
testIndex++;
try {
window[testCases[testIndex - 1]]();
} catch (ex) {
log("FAIL: unexpected exception " + ex);
runNextTest();
}
} else {
log("DONE");
if (window.testRunner)
testRunner.notifyDone();
}
}
function testSendSharedArrayBuffer()
{
runSendTest("SharedArrayBuffer");
}
function testSendInt8Array()
{
runSendTest("Int8Array");
}
function testSendUint8Array()
{
runSendTest("Uint8Array");
}
function testSendUint8ClampedArray()
{
runSendTest("Uint8ClampedArray");
}
function testSendInt16Array()
{
runSendTest("Int16Array");
}
function testSendUint16Array()
{
runSendTest("Uint16Array");
}
function testSendInt32Array()
{
runSendTest("Int32Array");
}
function testSendUint32Array()
{
runSendTest("Uint32Array");
}
function testSendFloat32Array()
{
runSendTest("Float32Array");
}
function testSendFloat64Array()
{
runSendTest("Float64Array");
}
function initializeTypedArray(ta, length) {
var i;
for (i = 0; i < length; ++i)
ta[i] = i;
}
function runSendTest(name)
{
var length = 8;
var type = window[name];
var sab;
var ta;
var msg;
log("Running " + name + " test case");
if (name == 'SharedArrayBuffer') {
sab = new SharedArrayBuffer(length);
ta = new Uint8Array(sab);
msg = {name: name, data: sab, length: length};
} else {
sab = new SharedArrayBuffer(length * type.BYTES_PER_ELEMENT);
ta = new type(sab);
msg = {name: name, data: ta, length: length};
}
initializeTypedArray(ta, length);
// Don't allow passing a SharedArrayBuffer in the transfer list.
try {
worker.postMessage(msg, [sab]);
log("FAIL: Passing SharedArrayBuffer in the transfer list did not throw.");
} catch (e) {
log("PASS: Passing SharedArrayBuffer in the transfer list threw.");
}
// Without Atomics, we can't safely test modifying the contents of the
// SharedArrayBuffer. All we can test for now is that the SharedArrayBuffer
// is not neutered when transferred to a Worker.
pendingWorkerReplies += 2;
worker.postMessage(msg);
secondaryWorker.postMessage(msg);
if (sab.length === 0)
log("FAIL: SharedArrayBuffer was neutered during transfer.");
else
log("PASS: SharedArrayBuffer not neutered during transfer.");
// Ensure the data wasn't changed.
for (i = 0; i < length; ++i) {
if (ta[i] != i) {
log("FAIL: Original data changed during transfer. Expected " + i +
" got " + ta[i]);
break;
}
}
if (i == length)
log("PASS: Original data not changed during transfer.");
}
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
}
if (window.internals && internals.runtimeFlags.sharedArrayBufferEnabled && window.SharedArrayBuffer) {
var worker = new Worker('../resources/worker-sharedarraybuffer-transfer.js');
var secondaryWorker = new Worker('../resources/worker-sharedarraybuffer-transfer.js');
var pendingWorkerReplies = 0;
var workerMessages = [];
var secondaryWorkerMessages = [];
runNextTest();
worker.onmessage = function(e) {
if (e.data != 'DONE') {
// The worker sent a pass/fail message.
workerMessages.push(e.data);
} else {
pendingWorkerReplies--;
logPendingMessages();
runNextTest();
}
};
secondaryWorker.onmessage = function(e) {
if (e.data != 'DONE') {
// The worker sent a pass/fail message.
secondaryWorkerMessages.push(e.data);
} else {
pendingWorkerReplies--;
logPendingMessages();
runNextTest();
}
};
} else {
log("SharedArrayBuffers are not enabled -- skipping test.");
testRunner.notifyDone();
}
</script>
</body>
</html>
......@@ -157,7 +157,7 @@ void ArrayBufferContents::DataHolder::AllocateNew(size_t length,
is_shared_ = is_shared;
AdjustAmountOfExternalAllocatedMemory(length);
RegisterExternalAllocationWithCurrentContext();
}
void ArrayBufferContents::DataHolder::Adopt(DataHandle data,
......@@ -168,7 +168,7 @@ void ArrayBufferContents::DataHolder::Adopt(DataHandle data,
data_ = std::move(data);
is_shared_ = is_shared;
AdjustAmountOfExternalAllocatedMemory(data.DataLength());
RegisterExternalAllocationWithCurrentContext();
}
void ArrayBufferContents::DataHolder::CopyMemoryFrom(const DataHolder& source) {
......@@ -181,12 +181,17 @@ void ArrayBufferContents::DataHolder::CopyMemoryFrom(const DataHolder& source) {
memcpy(data_.Data(), source.Data(), source.DataLength());
AdjustAmountOfExternalAllocatedMemory(source.DataLength());
RegisterExternalAllocationWithCurrentContext();
}
void ArrayBufferContents::DataHolder::
RegisterExternalAllocationWithCurrentContext() {
DCHECK(!has_registered_external_allocation_);
// Currently, we can only track an allocation if we have a single owner. For
// shared data this is not true, hence do not attempt to track at all.
// TODO(crbug.com/877055) Implement tracking of shared external allocations.
if (IsShared())
return;
AdjustAmountOfExternalAllocatedMemory(static_cast<int64_t>(DataLength()));
}
......@@ -194,6 +199,7 @@ void ArrayBufferContents::DataHolder::
UnregisterExternalAllocationWithCurrentContext() {
if (!has_registered_external_allocation_)
return;
DCHECK(!IsShared());
AdjustAmountOfExternalAllocatedMemory(-static_cast<int64_t>(DataLength()));
}
......
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