Bug 1299359 - Odin: put asm.js Atomics/SAB support behind wasmTestMode (r=lth)

MozReview-Commit-ID: 6nKQ3giYnic
This commit is contained in:
Luke Wagner 2016-09-05 09:50:43 -05:00
Родитель f821d7aff6
Коммит 6da730f66d
9 изменённых файлов: 75 добавлений и 45 удалений

Просмотреть файл

@ -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();