Bug 1277011 - Wasm baseline: Cleanup around calls. r=bbouvier

--HG--
extra : rebase_source : 7e619f3fe032a5d5922763584276fe0d702bccd2
extra : source : 47beee7f2748d21cab19027a20636e0caa761a49
This commit is contained in:
Lars T Hansen 2016-07-06 12:22:58 +02:00
Родитель 811035a57c
Коммит 3481e05ad5
1 изменённых файлов: 100 добавлений и 85 удалений

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

@ -24,19 +24,14 @@
*
* Unimplemented functionality:
*
* - This is not actually a baseline compiler, as it performs no
* profiling and does not trigger ion compilation and function
* replacement (duh)
* - int64 load and store
* - Tiered compilation (bug 1277562)
* - int64 operations on 32-bit systems
* - SIMD
* - Atomics (very simple now, we have range checking)
* - current_memory, grow_memory
* - non-signaling interrupts
* - non-signaling bounds checks
* - profiler support (devtools)
* - Platform support:
* ARM-32
* ARM-64
* - ARM-32 support (bug 1277011)
*
* There are lots of machine dependencies here but they are pretty
* well isolated to a segment of the compiler. Many dependencies
@ -144,10 +139,11 @@ struct BaseCompilePolicy : ExprIterPolicy
typedef ExprIter<BaseCompilePolicy> BaseExprIter;
typedef bool IsUnsigned;
typedef bool IsLoad;
typedef bool ZeroOnOverflow;
typedef bool IsKnownNotZero;
typedef bool HandleNaNSpecially;
typedef bool EscapesSandbox;
typedef bool IsBuiltinCall;
#ifdef JS_CODEGEN_ARM64
// FIXME: This is not correct, indeed for ARM64 there is no reliable
@ -1883,6 +1879,7 @@ class BaseCompiler
explicit FunctionCall(uint32_t lineOrBytecode)
: lineOrBytecode_(lineOrBytecode),
callSavesMachineState_(false),
builtinCall_(false),
machineStateAreaSize_(0),
frameAlignAdjustment_(0),
stackArgAreaSize_(0),
@ -1892,6 +1889,7 @@ class BaseCompiler
uint32_t lineOrBytecode_;
ABIArgGenerator abi_;
bool callSavesMachineState_;
bool builtinCall_;
size_t machineStateAreaSize_;
size_t frameAlignAdjustment_;
size_t stackArgAreaSize_;
@ -1902,10 +1900,10 @@ class BaseCompiler
bool calleePopsArgs_;
};
void beginCall(FunctionCall& call, bool escapesSandbox)
void beginCall(FunctionCall& call, bool escapesSandbox, bool builtinCall)
{
call.callSavesMachineState_ = escapesSandbox;
if (call.callSavesMachineState_) {
if (escapesSandbox) {
#if defined(JS_CODEGEN_X64)
call.machineStateAreaSize_ = 16; // Save HeapReg
#elif defined(JS_CODEGEN_X86)
@ -1915,6 +1913,12 @@ class BaseCompiler
#endif
}
call.builtinCall_ = builtinCall;
if (builtinCall) {
// Call-outs need to use the appropriate system ABI.
// ARM will have something here.
}
call.frameAlignAdjustment_ = ComputeByteAlignment(masm.framePushed() + sizeof(AsmJSFrame),
JitStackAlignment);
}
@ -1997,7 +2001,7 @@ class BaseCompiler
loadI32(scratch, arg);
masm.store32(scratch, Address(StackPointer, argLoc.offsetFromArgBase()));
} else {
loadI32(argLoc.reg().gpr(), arg);
loadI32(argLoc.gpr(), arg);
}
break;
}
@ -2009,7 +2013,7 @@ class BaseCompiler
loadI64(Register64(scratch), arg);
masm.movq(scratch, Operand(StackPointer, argLoc.offsetFromArgBase()));
} else {
loadI64(Register64(argLoc.reg().gpr()), arg);
loadI64(argLoc.gpr64(), arg);
}
#else
MOZ_CRASH("BaseCompiler platform hook: passArg I64");
@ -2018,23 +2022,52 @@ class BaseCompiler
}
case ValType::F64: {
ABIArg argLoc = call.abi_.next(MIRType::Double);
if (argLoc.kind() == ABIArg::Stack) {
switch (argLoc.kind()) {
case ABIArg::Stack: {
ScratchF64 scratch(*this);
loadF64(scratch, arg);
masm.storeDouble(scratch, Address(StackPointer, argLoc.offsetFromArgBase()));
} else {
loadF64(argLoc.reg().fpu(), arg);
break;
}
#if defined(JS_CODEGEN_REGISTER_PAIR)
case ABIArg::GPR_PAIR: {
MOZ_CRASH("BaseCompiler platform hook: passArg F64 pair");
}
#endif
case ABIArg::FPU: {
loadF64(argLoc.fpu(), arg);
break;
}
case ABIArg::GPR: {
MOZ_CRASH("Unexpected parameter passing discipline");
}
}
break;
}
case ValType::F32: {
ABIArg argLoc = call.abi_.next(MIRType::Float32);
if (argLoc.kind() == ABIArg::Stack) {
switch (argLoc.kind()) {
case ABIArg::Stack: {
ScratchF32 scratch(*this);
loadF32(scratch, arg);
masm.storeFloat32(scratch, Address(StackPointer, argLoc.offsetFromArgBase()));
} else {
loadF32(argLoc.reg().fpu(), arg);
break;
}
case ABIArg::GPR: {
ScratchF32 scratch(*this);
loadF32(scratch, arg);
masm.moveFloat32ToGPR(scratch, argLoc.gpr());
break;
}
case ABIArg::FPU: {
loadF32(argLoc.fpu(), arg);
break;
}
#if defined(JS_CODEGEN_REGISTER_PAIR)
case ABIArg::GPR_PAIR: {
MOZ_CRASH("Unexpected parameter passing discipline");
}
#endif
}
break;
}
@ -2160,42 +2193,38 @@ class BaseCompiler
#ifdef JS_PUNBOX64
moveI64(RegI64(ReturnReg64), dest);
#else
MOZ_CRASH("BaseCompiler platform hook: pushReturned");
MOZ_CRASH("BaseCompiler platform hook: captureReturnedI64");
#endif
}
void captureReturnedF32(RegF32 dest) {
void captureReturnedF32(const FunctionCall& call, RegF32 dest) {
#ifdef JS_CODEGEN_X86
if (call.builtinCall_) {
masm.reserveStack(sizeof(float));
Operand op(esp, 0);
masm.fstp32(op);
masm.loadFloat32(op, dest.reg);
masm.freeStack(sizeof(float));
return;
}
#endif
moveF32(RegF32(ReturnFloat32Reg), dest);
}
void captureBuiltinReturnedF32(RegF32 dest) {
void captureReturnedF64(const FunctionCall& call, RegF64 dest) {
#ifdef JS_CODEGEN_X86
masm.reserveStack(sizeof(float));
Operand op(esp, 0);
masm.fstp32(op);
masm.loadFloat32(op, dest.reg);
masm.freeStack(sizeof(float));
#else
captureReturnedF32(dest);
if (call.builtinCall_) {
masm.reserveStack(sizeof(double));
Operand op(esp, 0);
masm.fstp(op);
masm.loadDouble(op, dest.reg);
masm.freeStack(sizeof(double));
return;
}
#endif
}
void captureReturnedF64(RegF64 dest) {
moveF64(RegF64(ReturnDoubleReg), dest);
}
void captureBuiltinReturnedF64(RegF64 dest) {
#ifdef JS_CODEGEN_X86
masm.reserveStack(sizeof(double));
Operand op(esp, 0);
masm.fstp(op);
masm.loadDouble(op, dest.reg);
masm.freeStack(sizeof(double));
#else
captureReturnedF64(dest);
#endif
}
void returnVoid() {
popStackBeforeBranch(ctl_[0].framePushed);
masm.jump(&returnLabel_);
@ -2448,11 +2477,11 @@ class BaseCompiler
#endif
}
bool popcntNeedsTemp() {
bool popcnt32NeedsTemp() const {
#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
return !AssemblerX86Shared::HasPOPCNT();
#else
return false;
MOZ_CRASH("BaseCompiler platform hook: popcnt32NeedsTemp");
#endif
}
@ -2464,6 +2493,14 @@ class BaseCompiler
#endif
}
bool popcnt64NeedsTemp() const {
#if defined(JS_CODEGEN_X64)
return !AssemblerX86Shared::HasPOPCNT();
#else
MOZ_CRASH("BaseCompiler platform hook: popcnt64NeedsTemp");
#endif
}
void popcntI64(RegI64 srcDest, RegI64 tmp) {
#if defined(JS_CODEGEN_X64)
masm.popcnt64(srcDest.reg, srcDest.reg, tmp.reg);
@ -2711,7 +2748,7 @@ class BaseCompiler
CodeOffset label = masm.vmovsdWithPatch(PatchedAbsoluteAddress(), r.reg);
masm.append(GlobalAccess(label, globalDataOffset));
#else
MOZ_CRASH("BaseCompiler platform hook: loadGlobalVarF32");
MOZ_CRASH("BaseCompiler platform hook: loadGlobalVarF64");
#endif
}
@ -3282,8 +3319,7 @@ class BaseCompiler
void endIfThenElse();
void doReturn(ExprType returnType);
void pushReturned(ExprType type);
void pushBuiltinReturned(ExprType type);
void pushReturned(const FunctionCall& call, ExprType type);
void emitCompareI32(JSOp compareOp, MCompare::CompareType compareType);
void emitCompareI64(JSOp compareOp, MCompare::CompareType compareType);
@ -4134,7 +4170,7 @@ void
BaseCompiler::emitPopcntI32()
{
RegI32 r0 = popI32();
if (popcntNeedsTemp()) {
if (popcnt32NeedsTemp()) {
RegI32 tmp = needI32();
popcntI32(r0, tmp);
freeI32(tmp);
@ -4148,7 +4184,7 @@ void
BaseCompiler::emitPopcntI64()
{
RegI64 r0 = popI64();
if (popcntNeedsTemp()) {
if (popcnt64NeedsTemp()) {
RegI64 tmp = needI64();
popcntI64(r0, tmp);
freeI64(tmp);
@ -5051,7 +5087,7 @@ BaseCompiler::skipCall(const ValTypeVector& args, ExprType maybeReturnType)
}
void
BaseCompiler::pushReturned(ExprType type)
BaseCompiler::pushReturned(const FunctionCall& call, ExprType type)
{
switch (type) {
case ExprType::Void: {
@ -5072,13 +5108,13 @@ BaseCompiler::pushReturned(ExprType type)
}
case ExprType::F32: {
RegF32 rv = needF32();
captureReturnedF32(rv);
captureReturnedF32(call, rv);
pushF32(rv);
break;
}
case ExprType::F64: {
RegF64 rv = needF64();
captureReturnedF64(rv);
captureReturnedF64(call, rv);
pushF64(rv);
break;
}
@ -5087,27 +5123,6 @@ BaseCompiler::pushReturned(ExprType type)
}
}
void
BaseCompiler::pushBuiltinReturned(ExprType type)
{
switch (type) {
case ExprType::F32: {
RegF32 rv = needF32();
captureBuiltinReturnedF32(rv);
pushF32(rv);
break;
}
case ExprType::F64: {
RegF64 rv = needF64();
captureBuiltinReturnedF64(rv);
pushF64(rv);
break;
}
default:
MOZ_CRASH("Compiler bug: unexpected type");
}
}
// For now, always sync() at the beginning of the call to easily save
// live values.
//
@ -5143,7 +5158,7 @@ BaseCompiler::emitCall(uint32_t callOffset)
size_t stackSpace = stackConsumed(numArgs);
FunctionCall baselineCall(lineOrBytecode);
beginCall(baselineCall, false);
beginCall(baselineCall, EscapesSandbox(false), IsBuiltinCall(false));
if (!emitCallArgs(sig.args(), baselineCall))
return false;
@ -5161,7 +5176,7 @@ BaseCompiler::emitCall(uint32_t callOffset)
popValueStackBy(numArgs);
masm.freeStack(stackSpace);
pushReturned(sig.ret());
pushReturned(baselineCall, sig.ret());
return true;
}
@ -5193,7 +5208,7 @@ BaseCompiler::emitCallIndirect(uint32_t callOffset)
size_t stackSpace = stackConsumed(numArgs+1);
FunctionCall baselineCall(lineOrBytecode);
beginCall(baselineCall, false);
beginCall(baselineCall, EscapesSandbox(false), IsBuiltinCall(false));
if (!emitCallArgs(sig.args(), baselineCall))
return false;
@ -5220,7 +5235,7 @@ BaseCompiler::emitCallIndirect(uint32_t callOffset)
popValueStackBy(numArgs+1);
masm.freeStack(stackSpace);
pushReturned(sig.ret());
pushReturned(baselineCall, sig.ret());
return true;
}
@ -5247,7 +5262,7 @@ BaseCompiler::emitCallImport(uint32_t callOffset)
size_t stackSpace = stackConsumed(numArgs);
FunctionCall baselineCall(lineOrBytecode);
beginCall(baselineCall, true);
beginCall(baselineCall, EscapesSandbox(true), IsBuiltinCall(false));
if (!emitCallArgs(sig.args(), baselineCall))
return false;
@ -5265,7 +5280,7 @@ BaseCompiler::emitCallImport(uint32_t callOffset)
popValueStackBy(numArgs);
masm.freeStack(stackSpace);
pushReturned(sig.ret());
pushReturned(baselineCall, sig.ret());
return true;
}
@ -5293,7 +5308,7 @@ BaseCompiler::emitUnaryMathBuiltinCall(uint32_t callOffset, SymbolicAddress call
size_t stackSpace = stackConsumed(numArgs);
FunctionCall baselineCall(lineOrBytecode);
beginCall(baselineCall, false);
beginCall(baselineCall, EscapesSandbox(false), IsBuiltinCall(true));
ExprType retType;
switch (operandType) {
@ -5324,7 +5339,7 @@ BaseCompiler::emitUnaryMathBuiltinCall(uint32_t callOffset, SymbolicAddress call
popValueStackBy(numArgs);
masm.freeStack(stackSpace);
pushBuiltinReturned(retType);
pushReturned(baselineCall, retType);
return true;
}
@ -5351,7 +5366,7 @@ BaseCompiler::emitBinaryMathBuiltinCall(uint32_t callOffset, SymbolicAddress cal
size_t stackSpace = stackConsumed(numArgs);
FunctionCall baselineCall(lineOrBytecode);
beginCall(baselineCall, false);
beginCall(baselineCall, EscapesSandbox(false), IsBuiltinCall(true));
ExprType retType = ExprType::F64;
if (!emitCallArgs(SigDD_, baselineCall))
@ -5370,7 +5385,7 @@ BaseCompiler::emitBinaryMathBuiltinCall(uint32_t callOffset, SymbolicAddress cal
popValueStackBy(numArgs);
masm.freeStack(stackSpace);
pushBuiltinReturned(retType);
pushReturned(baselineCall, retType);
return true;
}