mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 17:25:36 +00:00
Bug 1205390 - make Odin accept TypedArray constructors for shared memory. r=luke
This commit is contained in:
parent
20e8824b95
commit
1f96a66c3d
@ -230,7 +230,7 @@ ValidateArrayView(JSContext* cx, AsmJSModule::Global& global, HandleValue global
|
||||
|
||||
bool tac = IsTypedArrayConstructor(v, global.viewType());
|
||||
bool stac = IsSharedTypedArrayConstructor(v, global.viewType());
|
||||
if (!((tac || stac) && stac == isShared))
|
||||
if (!(tac || (stac && isShared)))
|
||||
return LinkFail(cx, "bad typed array constructor");
|
||||
|
||||
return true;
|
||||
|
@ -314,6 +314,10 @@ class AsmJSModule
|
||||
MOZ_ASSERT(pod.which_ == ArrayView || pod.which_ == SharedArrayView || pod.which_ == ArrayViewCtor);
|
||||
return pod.u.viewType_;
|
||||
}
|
||||
void makeViewShared() {
|
||||
MOZ_ASSERT(pod.which_ == ArrayView);
|
||||
pod.which_ = SharedArrayView;
|
||||
}
|
||||
PropertyName* mathName() const {
|
||||
MOZ_ASSERT(pod.which_ == MathBuiltinFunction);
|
||||
return name_;
|
||||
@ -1106,6 +1110,15 @@ class AsmJSModule
|
||||
return pod.isSharedView_ == shared;
|
||||
return !pod.isSharedView_ || shared;
|
||||
}
|
||||
void setViewsAreShared() {
|
||||
if (pod.hasArrayView_)
|
||||
pod.isSharedView_ = true;
|
||||
for (size_t i=0 ; i < globals_.length() ; i++) {
|
||||
Global& g = globals_[i];
|
||||
if (g.which() == Global::ArrayView)
|
||||
g.makeViewShared();
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
|
@ -773,6 +773,10 @@ class MOZ_STACK_CLASS ModuleValidator
|
||||
MOZ_ASSERT(isAnyArrayView());
|
||||
return u.viewInfo.isSharedView_;
|
||||
}
|
||||
void setViewIsSharedView() {
|
||||
MOZ_ASSERT(isAnyArrayView());
|
||||
u.viewInfo.isSharedView_ = true;
|
||||
}
|
||||
bool isMathFunction() const {
|
||||
return which_ == MathBuiltinFunction;
|
||||
}
|
||||
@ -918,6 +922,7 @@ class MOZ_STACK_CLASS ModuleValidator
|
||||
bool canValidateChangeHeap_;
|
||||
bool hasChangeHeap_;
|
||||
bool supportsSimd_;
|
||||
bool atomicsPresent_;
|
||||
|
||||
ScopedJSDeletePtr<ModuleCompileResults> compileResults_;
|
||||
DebugOnly<bool> finishedFunctionBodies_;
|
||||
@ -943,6 +948,7 @@ class MOZ_STACK_CLASS ModuleValidator
|
||||
canValidateChangeHeap_(false),
|
||||
hasChangeHeap_(false),
|
||||
supportsSimd_(cx->jitSupportsSimd()),
|
||||
atomicsPresent_(false),
|
||||
compileResults_(nullptr),
|
||||
finishedFunctionBodies_(false)
|
||||
{
|
||||
@ -1155,6 +1161,7 @@ class MOZ_STACK_CLASS ModuleValidator
|
||||
Global* global = moduleLifo_.new_<Global>(Global::AtomicsBuiltinFunction);
|
||||
if (!global)
|
||||
return false;
|
||||
atomicsPresent_ = true;
|
||||
global->u.atomicsBuiltinFunc_ = func;
|
||||
return globals_.putNew(varName, global);
|
||||
}
|
||||
@ -1509,6 +1516,14 @@ class MOZ_STACK_CLASS ModuleValidator
|
||||
}
|
||||
|
||||
void startFunctionBodies() {
|
||||
if (atomicsPresent_) {
|
||||
for (GlobalMap::Range r = globals_.all() ; !r.empty() ; r.popFront()) {
|
||||
Global* g = r.front().value();
|
||||
if (g->isAnyArrayView())
|
||||
g->setViewIsSharedView();
|
||||
}
|
||||
module_->setViewsAreShared();
|
||||
}
|
||||
module_->startFunctionBodies();
|
||||
}
|
||||
bool finishFunctionBodies(ScopedJSDeletePtr<ModuleCompileResults>* compileResults) {
|
||||
|
116
js/src/jit-test/tests/asm.js/sta-transition.js
Normal file
116
js/src/jit-test/tests/asm.js/sta-transition.js
Normal file
@ -0,0 +1,116 @@
|
||||
// Transitional test cases, useful while Odin accepts both
|
||||
// "Int32Array" and "SharedInt32Array" to construct a view onto shared
|
||||
// memory but the former only when an atomic operation is referenced,
|
||||
// as per spec. Eventually it will stop accepting "SharedInt32Array",
|
||||
// because that name is going away.
|
||||
//
|
||||
// These should not run with --no-asmjs.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Int8Array can be used on SharedArrayBuffer, if atomics are present
|
||||
|
||||
function m1(stdlib, ffi, heap) {
|
||||
"use asm";
|
||||
|
||||
var i8 = new stdlib.Int8Array(heap);
|
||||
var add = stdlib.Atomics.add;
|
||||
|
||||
function f() {
|
||||
add(i8, 0, 1);
|
||||
return 37;
|
||||
}
|
||||
|
||||
return { f:f }
|
||||
}
|
||||
|
||||
assertEq(isAsmJSModule(m1), true);
|
||||
|
||||
var { f } = m1(this, {}, new SharedArrayBuffer(65536));
|
||||
assertEq(f(), 37);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SharedInt8Array can still be used on SharedArrayBuffer.
|
||||
// (SharedInt8Array will eventually disappear, and this
|
||||
// test case with it.)
|
||||
|
||||
function m2(stdlib, ffi, heap) {
|
||||
"use asm";
|
||||
|
||||
var i8 = new stdlib.SharedInt8Array(heap);
|
||||
var add = stdlib.Atomics.add;
|
||||
|
||||
function g() {
|
||||
add(i8, 0, 1);
|
||||
return 42;
|
||||
}
|
||||
|
||||
return { g:g }
|
||||
}
|
||||
|
||||
assertEq(isAsmJSModule(m2), true);
|
||||
|
||||
var { g } = m2(this, {}, new SharedArrayBuffer(65536));
|
||||
assertEq(g(), 42);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SharedInt8Array still cannot be used on ArrayBuffer, even without
|
||||
// atomics present.
|
||||
// (SharedInt8Array will eventually disappear, and this
|
||||
// test case with it.)
|
||||
|
||||
function m3(stdlib, ffi, heap) {
|
||||
"use asm";
|
||||
|
||||
var i8 = new stdlib.SharedInt8Array(heap);
|
||||
|
||||
function h() {
|
||||
return i8[0]|0;
|
||||
}
|
||||
|
||||
return { h:h }
|
||||
}
|
||||
|
||||
// Running the shell with -w you should see an error here.
|
||||
|
||||
assertEq(isAsmJSModule(m3), true);
|
||||
try {
|
||||
var wasThrown = false;
|
||||
m3(this, {}, new ArrayBuffer(65536));
|
||||
}
|
||||
catch (e) {
|
||||
wasThrown = true;
|
||||
}
|
||||
assertEq(wasThrown, true);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Int8Array cannot be used on SharedArrayBuffer if atomics are not imported.
|
||||
// One argument for the restriction is that there are some optimizations
|
||||
// that are legal if the memory is known not to be shared that are illegal
|
||||
// when it is shared.
|
||||
|
||||
function m4(stdlib, ffi, heap) {
|
||||
"use asm";
|
||||
|
||||
var i8 = new stdlib.Int8Array(heap);
|
||||
|
||||
function i() {
|
||||
return i8[0]|0;
|
||||
}
|
||||
|
||||
return { i:i }
|
||||
}
|
||||
|
||||
assertEq(isAsmJSModule(m4), true);
|
||||
|
||||
// An error is not actually thrown because the link failure drops us
|
||||
// back to JS execution and then the Int8Array constructor will copy data
|
||||
// from the SharedArrayBuffer.
|
||||
//
|
||||
// Running the shell with -w you should see an error here.
|
||||
|
||||
var { i } = m4(this, {}, new SharedArrayBuffer(65536));
|
||||
assertEq(isAsmJSFunction(i), false);
|
@ -1,5 +1,5 @@
|
||||
// |jit-test| test-also-noasmjs
|
||||
if (!this.SharedArrayBuffer || !this.SharedInt32Array || !this.Atomics)
|
||||
if (!this.SharedArrayBuffer || !this.Atomics)
|
||||
quit();
|
||||
|
||||
// The code duplication below is very far from elegant but provides
|
||||
@ -8,6 +8,27 @@ if (!this.SharedArrayBuffer || !this.SharedInt32Array || !this.Atomics)
|
||||
load(libdir + "asm.js");
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
// This hack allows the test cases to run with --no-asmjs: the field values
|
||||
// are basically ignored in asm.js mode, and the correct (Firefox-specific)
|
||||
// field values are used in non-asm.js mode. If run in a non-Firefox
|
||||
// browser that does not have the parallel type hierarchy this should also
|
||||
// work.
|
||||
//
|
||||
// This hack will be removed when the parallel type hierarchy is removed
|
||||
// from Firefox, bug 1176214.
|
||||
|
||||
const atomicStdlib = {
|
||||
Atomics: Atomics,
|
||||
Int8Array: this.SharedInt8Array ? SharedInt8Array : Int8Array,
|
||||
Uint8Array: this.SharedUint8Array ? SharedUint8Array : Uint8Array,
|
||||
Int16Array: this.SharedInt16Array ? SharedInt16Array : Int16Array,
|
||||
Uint16Array: this.SharedUint16Array ? SharedUint16Array : Uint16Array,
|
||||
Int32Array: this.SharedInt32Array ? SharedInt32Array : Int32Array,
|
||||
Uint32Array: this.SharedUint32Array ? SharedUint32Array : Uint32Array,
|
||||
Float32Array: this.SharedFloat32Array ? SharedFloat32Array : Float32Array,
|
||||
Float64Array: this.SharedFloat64Array ? SharedFloat64Array : Float64Array
|
||||
};
|
||||
|
||||
var loadModule_int32_code =
|
||||
USE_ASM + `
|
||||
var atomic_fence = stdlib.Atomics.fence;
|
||||
@ -21,7 +42,7 @@ var loadModule_int32_code =
|
||||
var atomic_or = stdlib.Atomics.or;
|
||||
var atomic_xor = stdlib.Atomics.xor;
|
||||
|
||||
var i32a = new stdlib.SharedInt32Array(heap);
|
||||
var i32a = new stdlib.Int32Array(heap);
|
||||
|
||||
function do_fence() {
|
||||
atomic_fence();
|
||||
@ -233,7 +254,7 @@ var loadModule_int32 = asmCompile('stdlib', 'foreign', 'heap', loadModule_int32_
|
||||
|
||||
function test_int32(heap) {
|
||||
var i32a = new SharedInt32Array(heap);
|
||||
var i32m = asmLink(loadModule_int32, this, {}, heap);
|
||||
var i32m = asmLink(loadModule_int32, atomicStdlib, {}, heap);
|
||||
|
||||
var size = SharedInt32Array.BYTES_PER_ELEMENT;
|
||||
|
||||
@ -338,7 +359,7 @@ var loadModule_uint32_code =
|
||||
var atomic_or = stdlib.Atomics.or;
|
||||
var atomic_xor = stdlib.Atomics.xor;
|
||||
|
||||
var i32a = new stdlib.SharedUint32Array(heap);
|
||||
var i32a = new stdlib.Uint32Array(heap);
|
||||
|
||||
// Load element 0
|
||||
function do_load() {
|
||||
@ -516,7 +537,7 @@ var loadModule_uint32 = asmCompile('stdlib', 'foreign', 'heap', loadModule_uint3
|
||||
|
||||
function test_uint32(heap) {
|
||||
var i32a = new SharedUint32Array(heap);
|
||||
var i32m = loadModule_uint32(this, {}, heap);
|
||||
var i32m = loadModule_uint32(atomicStdlib, {}, heap);
|
||||
|
||||
var size = SharedUint32Array.BYTES_PER_ELEMENT;
|
||||
|
||||
@ -619,7 +640,7 @@ var loadModule_int16_code =
|
||||
var atomic_or = stdlib.Atomics.or;
|
||||
var atomic_xor = stdlib.Atomics.xor;
|
||||
|
||||
var i16a = new stdlib.SharedInt16Array(heap);
|
||||
var i16a = new stdlib.Int16Array(heap);
|
||||
|
||||
function do_fence() {
|
||||
atomic_fence();
|
||||
@ -802,7 +823,7 @@ var loadModule_int16 = asmCompile('stdlib', 'foreign', 'heap', loadModule_int16_
|
||||
|
||||
function test_int16(heap) {
|
||||
var i16a = new SharedInt16Array(heap);
|
||||
var i16m = loadModule_int16(this, {}, heap);
|
||||
var i16m = loadModule_int16(atomicStdlib, {}, heap);
|
||||
|
||||
var size = SharedInt16Array.BYTES_PER_ELEMENT;
|
||||
|
||||
@ -914,7 +935,7 @@ var loadModule_uint16_code =
|
||||
var atomic_or = stdlib.Atomics.or;
|
||||
var atomic_xor = stdlib.Atomics.xor;
|
||||
|
||||
var i16a = new stdlib.SharedUint16Array(heap);
|
||||
var i16a = new stdlib.Uint16Array(heap);
|
||||
|
||||
// Load element 0
|
||||
function do_load() {
|
||||
@ -1092,7 +1113,7 @@ var loadModule_uint16 = asmCompile('stdlib', 'foreign', 'heap', loadModule_uint1
|
||||
|
||||
function test_uint16(heap) {
|
||||
var i16a = new SharedUint16Array(heap);
|
||||
var i16m = loadModule_uint16(this, {}, heap);
|
||||
var i16m = loadModule_uint16(atomicStdlib, {}, heap);
|
||||
|
||||
var size = SharedUint16Array.BYTES_PER_ELEMENT;
|
||||
|
||||
@ -1202,7 +1223,7 @@ var loadModule_int8_code =
|
||||
var atomic_or = stdlib.Atomics.or;
|
||||
var atomic_xor = stdlib.Atomics.xor;
|
||||
|
||||
var i8a = new stdlib.SharedInt8Array(heap);
|
||||
var i8a = new stdlib.Int8Array(heap);
|
||||
|
||||
// Load element 0
|
||||
function do_load() {
|
||||
@ -1380,7 +1401,7 @@ var loadModule_int8 = asmCompile('stdlib', 'foreign', 'heap', loadModule_int8_co
|
||||
|
||||
function test_int8(heap) {
|
||||
var i8a = new SharedInt8Array(heap);
|
||||
var i8m = loadModule_int8(this, {}, heap);
|
||||
var i8m = loadModule_int8(atomicStdlib, {}, heap);
|
||||
|
||||
for ( var i=0 ; i < i8a.length ; i++ )
|
||||
i8a[i] = 0;
|
||||
@ -1483,7 +1504,7 @@ var loadModule_uint8_code =
|
||||
var atomic_or = stdlib.Atomics.or;
|
||||
var atomic_xor = stdlib.Atomics.xor;
|
||||
|
||||
var i8a = new stdlib.SharedUint8Array(heap);
|
||||
var i8a = new stdlib.Uint8Array(heap);
|
||||
|
||||
// Load element 0
|
||||
function do_load() {
|
||||
@ -1661,7 +1682,7 @@ var loadModule_uint8 = asmCompile('stdlib', 'foreign', 'heap', loadModule_uint8_
|
||||
|
||||
function test_uint8(heap) {
|
||||
var i8a = new SharedUint8Array(heap);
|
||||
var i8m = loadModule_uint8(this, {}, heap);
|
||||
var i8m = loadModule_uint8(atomicStdlib, {}, heap);
|
||||
|
||||
for ( var i=0 ; i < i8a.length ; i++ )
|
||||
i8a[i] = 0;
|
||||
@ -1816,7 +1837,7 @@ var loadModule_misc_code =
|
||||
var loadModule_misc = asmCompile('stdlib', 'foreign', 'heap', loadModule_misc_code);
|
||||
|
||||
function test_misc(heap) {
|
||||
var misc = loadModule_misc(this, {}, heap);
|
||||
var misc = loadModule_misc(atomicStdlib, {}, heap);
|
||||
|
||||
assertEq(misc.ilf1(), 1);
|
||||
assertEq(misc.ilf2(), 1);
|
||||
@ -1848,7 +1869,7 @@ setARMHwCapFlags('vfp');
|
||||
asmCompile('stdlib', 'ffi', 'heap',
|
||||
USE_ASM + `
|
||||
var atomic_exchange = stdlib.Atomics.exchange;
|
||||
var i8a = new stdlib.SharedInt8Array(heap);
|
||||
var i8a = new stdlib.Int8Array(heap);
|
||||
|
||||
function do_xchg() {
|
||||
var v = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user