зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1299359 - Odin: put asm.js Atomics/SAB support behind wasmTestMode (r=lth)
MozReview-Commit-ID: 6nKQ3giYnic
This commit is contained in:
Родитель
f821d7aff6
Коммит
6da730f66d
|
@ -1967,6 +1967,9 @@ class MOZ_STACK_CLASS ModuleValidator
|
|||
bool addAtomicsBuiltinFunction(PropertyName* var, AsmJSAtomicsBuiltinFunction func,
|
||||
PropertyName* field)
|
||||
{
|
||||
if (!JitOptions.wasmTestMode)
|
||||
return failCurrentOffset("asm.js Atomics only enabled in wasm test mode");
|
||||
|
||||
atomicsPresent_ = true;
|
||||
|
||||
UniqueChars fieldChars = StringToNewUTF8CharsZ(cx_, *field);
|
||||
|
@ -7808,6 +7811,9 @@ CheckBuffer(JSContext* cx, const AsmJSMetadata& metadata, HandleValue bufferVal,
|
|||
Rooted<ArrayBufferObject*> abheap(cx, &buffer->as<ArrayBufferObject>());
|
||||
if (!ArrayBufferObject::prepareForAsmJS(cx, abheap))
|
||||
return LinkFail(cx, "Unable to prepare ArrayBuffer for asm.js use");
|
||||
} else {
|
||||
if (!buffer->as<SharedArrayBufferObject>().isPreparedForAsmJS())
|
||||
return LinkFail(cx, "SharedArrayBuffer must be created with wasm test mode enabled");
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -18,6 +18,8 @@ load(libdir + "asm.js");
|
|||
if (!isAsmJSCompilationAvailable())
|
||||
quit(0);
|
||||
|
||||
setJitCompilerOption('wasm.test-mode', 1);
|
||||
|
||||
if (!this.Atomics) {
|
||||
this.Atomics = { load: function (x, y) { return 0 },
|
||||
store: function (x, y, z) { return 0 },
|
||||
|
@ -32,16 +34,16 @@ if (!this.Atomics) {
|
|||
}
|
||||
|
||||
|
||||
function module_a(stdlib, foreign, heap) {
|
||||
var module_a = asmCompile("stdlib", "foreign", "heap", `
|
||||
"use asm";
|
||||
|
||||
var ld = stdlib.Atomics.load;
|
||||
|
||||
function f() { return 0; }
|
||||
return { f:f };
|
||||
}
|
||||
`);
|
||||
|
||||
function module_b(stdlib, foreign, heap) {
|
||||
var module_b = asmCompile("stdlib", "foreign", "heap", `
|
||||
"use asm";
|
||||
|
||||
var ld = stdlib.Atomics.load;
|
||||
|
@ -49,16 +51,16 @@ function module_b(stdlib, foreign, heap) {
|
|||
|
||||
function f() { return 0; }
|
||||
return { f:f };
|
||||
}
|
||||
`);
|
||||
|
||||
function module_c(stdlib, foreign, heap) {
|
||||
var module_c = asmCompile("stdlib", "foreign", "heap", `
|
||||
"use asm";
|
||||
|
||||
var i32a = new stdlib.Int32Array(heap);
|
||||
|
||||
function f() { return 0; }
|
||||
return { f:f };
|
||||
}
|
||||
`);
|
||||
|
||||
assertEq(isAsmJSModule(module_a), true);
|
||||
assertEq(isAsmJSModule(module_b), true);
|
||||
|
|
|
@ -2,14 +2,18 @@
|
|||
//
|
||||
// These should not be run with --no-asmjs, the guard below checks this.
|
||||
|
||||
load(libdir + "asm.js");
|
||||
|
||||
if (!this.SharedArrayBuffer || !isAsmJSCompilationAvailable())
|
||||
quit(0);
|
||||
|
||||
setJitCompilerOption('wasm.test-mode', 1);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Int8Array can be used on SharedArrayBuffer, if atomics are present
|
||||
|
||||
function m1(stdlib, ffi, heap) {
|
||||
var m1 = asmCompile("stdlib", "ffi", "heap", `
|
||||
"use asm";
|
||||
|
||||
var i8 = new stdlib.Int8Array(heap);
|
||||
|
@ -21,7 +25,7 @@ function m1(stdlib, ffi, heap) {
|
|||
}
|
||||
|
||||
return { f:f }
|
||||
}
|
||||
`);
|
||||
|
||||
assertEq(isAsmJSModule(m1), true);
|
||||
|
||||
|
@ -35,7 +39,7 @@ assertEq(f(), 37);
|
|||
// that are legal if the memory is known not to be shared that are illegal
|
||||
// when it is shared.
|
||||
|
||||
function m4(stdlib, ffi, heap) {
|
||||
var m4 = asmCompile("stdlib", "ffi", "heap", `
|
||||
"use asm";
|
||||
|
||||
var i8 = new stdlib.Int8Array(heap);
|
||||
|
@ -45,7 +49,7 @@ function m4(stdlib, ffi, heap) {
|
|||
}
|
||||
|
||||
return { i:i }
|
||||
}
|
||||
`);
|
||||
|
||||
assertEq(isAsmJSModule(m4), true);
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ if (!this.Atomics)
|
|||
quit();
|
||||
|
||||
load(libdir + "asm.js");
|
||||
setJitCompilerOption('wasm.test-mode', 1);
|
||||
|
||||
var code = `
|
||||
"use asm";
|
||||
|
|
|
@ -9,6 +9,8 @@ if (!this.SharedArrayBuffer || !this.Atomics)
|
|||
load(libdir + "asm.js");
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
setJitCompilerOption('wasm.test-mode', 1);
|
||||
|
||||
var loadModule_int32_code =
|
||||
USE_ASM + `
|
||||
var atomic_load = stdlib.Atomics.load;
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
if (!this.SharedArrayBuffer || !isAsmJSCompilationAvailable())
|
||||
quit(0);
|
||||
|
||||
load(libdir + "asm.js");
|
||||
setJitCompilerOption('wasm.test-mode', 1);
|
||||
|
||||
// The way this is constructed, either the first module does not
|
||||
// verify as asm.js (if the >>>0 is left off, which was legal prior to
|
||||
// bug 1155176), or the results of the two modules have to be equal.
|
||||
|
||||
function m(stdlib, ffi, heap) {
|
||||
var m = asmCompile("stdlib", "ffi", "heap", `
|
||||
"use asm";
|
||||
|
||||
var view = new stdlib.Uint32Array(heap);
|
||||
|
@ -17,7 +20,7 @@ function m(stdlib, ffi, heap) {
|
|||
}
|
||||
|
||||
return run;
|
||||
}
|
||||
`);
|
||||
|
||||
assertEq(isAsmJSModule(m), true);
|
||||
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
if (!this.SharedArrayBuffer)
|
||||
quit(0);
|
||||
|
||||
load(libdir + "asm.js");
|
||||
load(libdir + "asserts.js");
|
||||
setJitCompilerOption('wasm.test-mode', 1);
|
||||
|
||||
function m(stdlib, ffi, heap) {
|
||||
var m = asmCompile("stdlib", "ffi", "heap", `
|
||||
"use asm";
|
||||
var HEAP32 = new stdlib.Int32Array(heap);
|
||||
var add = stdlib.Atomics.add;
|
||||
|
@ -15,7 +17,7 @@ function m(stdlib, ffi, heap) {
|
|||
load(HEAP32, i1 >> 2);
|
||||
}
|
||||
return {add_sharedEv:add_sharedEv};
|
||||
}
|
||||
`);
|
||||
|
||||
if (isAsmJSCompilationAvailable())
|
||||
assertEq(isAsmJSModule(m), true);
|
||||
|
|
|
@ -81,6 +81,7 @@ MarkValidRegion(void* addr, size_t len)
|
|||
static uint64_t
|
||||
SharedArrayMappedSize()
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(jit::JitOptions.wasmTestMode);
|
||||
MOZ_RELEASE_ASSERT(sizeof(SharedArrayRawBuffer) < gc::SystemPageSize());
|
||||
return wasm::MappedSize + gc::SystemPageSize();
|
||||
}
|
||||
|
@ -113,13 +114,12 @@ SharedArrayRawBuffer::New(JSContext* cx, uint32_t length)
|
|||
uint32_t allocSize = SharedArrayAllocSize(length);
|
||||
if (allocSize <= length)
|
||||
return nullptr;
|
||||
|
||||
bool preparedForAsmJS = jit::JitOptions.wasmTestMode && IsValidAsmJSHeapLength(length);
|
||||
|
||||
void* p = nullptr;
|
||||
if (!IsValidAsmJSHeapLength(length)) {
|
||||
p = MapMemory(allocSize, true);
|
||||
if (!p)
|
||||
return nullptr;
|
||||
} else {
|
||||
#ifdef WASM_HUGE_MEMORY
|
||||
if (preparedForAsmJS) {
|
||||
// Test >= to guard against the case where multiple extant runtimes
|
||||
// race to allocate.
|
||||
if (++numLive >= maxLive) {
|
||||
|
@ -143,20 +143,23 @@ SharedArrayRawBuffer::New(JSContext* cx, uint32_t length)
|
|||
numLive--;
|
||||
return nullptr;
|
||||
}
|
||||
# if defined(MOZ_VALGRIND) && defined(VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE)
|
||||
|
||||
# if defined(MOZ_VALGRIND) && defined(VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE)
|
||||
// Tell Valgrind/Memcheck to not report accesses in the inaccessible region.
|
||||
VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE((unsigned char*)p + allocSize,
|
||||
SharedArrayMappedSize() - allocSize);
|
||||
# endif
|
||||
#else
|
||||
# endif
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
p = MapMemory(allocSize, true);
|
||||
if (!p)
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t* buffer = reinterpret_cast<uint8_t*>(p) + gc::SystemPageSize();
|
||||
uint8_t* base = buffer - sizeof(SharedArrayRawBuffer);
|
||||
SharedArrayRawBuffer* rawbuf = new (base) SharedArrayRawBuffer(buffer, length);
|
||||
SharedArrayRawBuffer* rawbuf = new (base) SharedArrayRawBuffer(buffer, length, preparedForAsmJS);
|
||||
MOZ_ASSERT(rawbuf->length == length); // Deallocation needs this
|
||||
return rawbuf;
|
||||
}
|
||||
|
@ -173,32 +176,30 @@ SharedArrayRawBuffer::dropReference()
|
|||
{
|
||||
// Drop the reference to the buffer.
|
||||
uint32_t refcount = --this->refcount_; // Atomic.
|
||||
if (refcount)
|
||||
return;
|
||||
|
||||
// If this was the final reference, release the buffer.
|
||||
if (refcount == 0) {
|
||||
SharedMem<uint8_t*> p = this->dataPointerShared() - gc::SystemPageSize();
|
||||
|
||||
MOZ_ASSERT(p.asValue() % gc::SystemPageSize() == 0);
|
||||
SharedMem<uint8_t*> p = this->dataPointerShared() - gc::SystemPageSize();
|
||||
MOZ_ASSERT(p.asValue() % gc::SystemPageSize() == 0);
|
||||
|
||||
uint8_t* address = p.unwrap(/*safe - only reference*/);
|
||||
uint32_t allocSize = SharedArrayAllocSize(this->length);
|
||||
|
||||
uint8_t* address = p.unwrap(/*safe - only reference*/);
|
||||
uint32_t allocSize = SharedArrayAllocSize(this->length);
|
||||
if (!IsValidAsmJSHeapLength(this->length)) {
|
||||
UnmapMemory(address, allocSize);
|
||||
} else {
|
||||
#if defined(WASM_HUGE_MEMORY)
|
||||
numLive--;
|
||||
UnmapMemory(address, SharedArrayMappedSize());
|
||||
# if defined(MOZ_VALGRIND) \
|
||||
&& defined(VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE)
|
||||
// Tell Valgrind/Memcheck to recommence reporting accesses in the
|
||||
// previously-inaccessible region.
|
||||
VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(address,
|
||||
SharedArrayMappedSize());
|
||||
# endif
|
||||
#else
|
||||
UnmapMemory(address, allocSize);
|
||||
if (this->preparedForAsmJS) {
|
||||
numLive--;
|
||||
UnmapMemory(address, SharedArrayMappedSize());
|
||||
# if defined(MOZ_VALGRIND) && defined(VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE)
|
||||
// Tell Valgrind/Memcheck to recommence reporting accesses in the
|
||||
// previously-inaccessible region.
|
||||
VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(address, SharedArrayMappedSize());
|
||||
# endif
|
||||
} else
|
||||
#endif
|
||||
}
|
||||
{
|
||||
UnmapMemory(address, allocSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,15 +46,17 @@ class SharedArrayRawBuffer
|
|||
private:
|
||||
mozilla::Atomic<uint32_t, mozilla::ReleaseAcquire> refcount_;
|
||||
uint32_t length;
|
||||
bool preparedForAsmJS;
|
||||
|
||||
// A list of structures representing tasks waiting on some
|
||||
// location within this buffer.
|
||||
FutexWaiter* waiters_;
|
||||
|
||||
protected:
|
||||
SharedArrayRawBuffer(uint8_t* buffer, uint32_t length)
|
||||
SharedArrayRawBuffer(uint8_t* buffer, uint32_t length, bool preparedForAsmJS)
|
||||
: refcount_(1),
|
||||
length(length),
|
||||
preparedForAsmJS(preparedForAsmJS),
|
||||
waiters_(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(buffer == dataPointerShared());
|
||||
|
@ -84,6 +86,10 @@ class SharedArrayRawBuffer
|
|||
return length;
|
||||
}
|
||||
|
||||
bool isPreparedForAsmJS() const {
|
||||
return preparedForAsmJS;
|
||||
}
|
||||
|
||||
uint32_t refcount() const { return refcount_; }
|
||||
|
||||
void addReference();
|
||||
|
@ -157,6 +163,9 @@ class SharedArrayBufferObject : public ArrayBufferObjectMaybeShared
|
|||
uint32_t byteLength() const {
|
||||
return rawBufferObject()->byteLength();
|
||||
}
|
||||
bool isPreparedForAsmJS() const {
|
||||
return rawBufferObject()->isPreparedForAsmJS();
|
||||
}
|
||||
|
||||
SharedMem<uint8_t*> dataPointerShared() const {
|
||||
return rawBufferObject()->dataPointerShared();
|
||||
|
|
Загрузка…
Ссылка в новой задаче