Bug 1027885 - OdinMonkey: avoid passing JSContext to C++ functions that can instead use innermostAsmJSActivation (r=dougc)

This commit is contained in:
Luke Wagner 2014-07-21 10:56:02 -05:00
Родитель af44b6bf3d
Коммит 3414c83d98
7 изменённых файлов: 169 добавлений и 243 удалений

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

@ -5880,12 +5880,6 @@ LoadAsmJSActivationIntoRegister(MacroAssembler &masm, Register reg)
#endif
}
static void
LoadJSContextFromActivation(MacroAssembler &masm, Register activation, Register dest)
{
masm.loadPtr(Address(activation, AsmJSActivation::offsetOfContext()), dest);
}
static void
AssertStackAlignment(MacroAssembler &masm)
{
@ -6070,102 +6064,6 @@ GenerateEntry(ModuleCompiler &m, const AsmJSModule::ExportedFunction &exportedFu
return true;
}
// This function and InvokeFromAsmJS* functions all return int32_t rather than
// bool to prevent the compiler from optimizing bits higher than what's
// actually needed for a bool (as the result is tested in asm.js generated code
// which the compiler isn't aware of).
static inline int32_t
TryEnablingIon(JSContext *cx, AsmJSModule &module, HandleFunction fun, uint32_t exitIndex,
int32_t argc, Value *argv)
{
if (!fun->hasScript())
return true;
// Test if the function is Ion compiled
JSScript *script = fun->nonLazyScript();
if (!script->hasIonScript())
return true;
// Currently we can't rectify arguments. Therefore disabling if argc is too low.
if (fun->nargs() > size_t(argc))
return true;
// Normally the types should corresond, since we just ran with those types,
// but there are reports this is asserting. Therefore doing it as a check, instead of DEBUG only.
if (!types::TypeScript::ThisTypes(script)->hasType(types::Type::UndefinedType()))
return true;
for(uint32_t i = 0; i < fun->nargs(); i++) {
types::StackTypeSet *typeset = types::TypeScript::ArgTypes(script, i);
types::Type type = types::Type::DoubleType();
if (!argv[i].isDouble())
type = types::Type::PrimitiveType(argv[i].extractNonDoubleType());
if (!typeset->hasType(type))
return true;
}
// Enable
IonScript *ionScript = script->ionScript();
if (!ionScript->addDependentAsmJSModule(cx, DependentAsmJSModuleExit(&module, exitIndex)))
return false;
module.exitIndexToGlobalDatum(exitIndex).exit = module.ionExitTrampoline(module.exit(exitIndex));
return true;
}
namespace js {
// See comment above TryEnablingIon.
int32_t
InvokeFromAsmJS(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv,
MutableHandleValue rval)
{
AsmJSModule &module = cx->mainThread().asmJSActivationStackFromOwnerThread()->module();
RootedFunction fun(cx, module.exitIndexToGlobalDatum(exitIndex).fun);
RootedValue fval(cx, ObjectValue(*fun));
if (!Invoke(cx, UndefinedValue(), fval, argc, argv, rval))
return false;
return TryEnablingIon(cx, module, fun, exitIndex, argc, argv);
}
int32_t
InvokeFromAsmJS_Ignore(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv)
{
RootedValue rval(cx);
return InvokeFromAsmJS(cx, exitIndex, argc, argv, &rval);
}
int32_t
InvokeFromAsmJS_ToInt32(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv)
{
RootedValue rval(cx);
if (!InvokeFromAsmJS(cx, exitIndex, argc, argv, &rval))
return false;
int32_t i32;
if (!ToInt32(cx, rval, &i32))
return false;
argv[0] = Int32Value(i32);
return true;
}
int32_t
InvokeFromAsmJS_ToNumber(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv)
{
RootedValue rval(cx);
if (!InvokeFromAsmJS(cx, exitIndex, argc, argv, &rval))
return false;
double dbl;
if (!ToNumber(cx, rval, &dbl))
return false;
argv[0] = DoubleValue(dbl);
return true;
}
} // namespace js
static void
FillArgumentArray(ModuleCompiler &m, const VarTypeVector &argTypes,
unsigned offsetToArgs, unsigned offsetToCallerStackArgs,
@ -6226,8 +6124,7 @@ GenerateFFIInterpreterExit(ModuleCompiler &m, const ModuleCompiler::ExitDescript
LoadAsmJSActivationIntoRegister(masm, activation);
masm.storePtr(StackPointer, Address(activation, AsmJSActivation::offsetOfExitFP()));
MIRType typeArray[] = { MIRType_Pointer, // cx
MIRType_Pointer, // exitDatum
MIRType typeArray[] = { MIRType_Pointer, // exitDatum
MIRType_Int32, // argc
MIRType_Pointer }; // argv
MIRTypeVector invokeArgTypes(m.cx());
@ -6235,9 +6132,9 @@ GenerateFFIInterpreterExit(ModuleCompiler &m, const ModuleCompiler::ExitDescript
// At the point of the call, the stack layout shall be (sp grows to the left):
// | stack args | padding | Value argv[] | padding | retaddr | caller stack args |
// The padding between stack args and argv ensures that sp is aligned. The
// padding between argv and retaddr ensures that argv is aligned.
unsigned offsetToArgv = AlignBytes(StackArgBytes(invokeArgTypes), StackAlignment);
// The padding between stack args and argv ensures that argv is aligned. The
// padding between argv and retaddr ensures that sp is aligned.
unsigned offsetToArgv = AlignBytes(StackArgBytes(invokeArgTypes), sizeof(double));
unsigned argvBytes = Max<size_t>(1, exit.sig().args().length()) * sizeof(Value);
unsigned stackDec = StackDecrementForCall(masm, offsetToArgv + argvBytes);
masm.reserveStack(stackDec);
@ -6250,23 +6147,14 @@ GenerateFFIInterpreterExit(ModuleCompiler &m, const ModuleCompiler::ExitDescript
// Prepare the arguments for the call to InvokeFromAsmJS_*.
ABIArgMIRTypeIter i(invokeArgTypes);
// argument 0: cx
if (i->kind() == ABIArg::GPR) {
LoadJSContextFromActivation(masm, activation, i->gpr());
} else {
LoadJSContextFromActivation(masm, activation, scratch);
masm.storePtr(scratch, Address(StackPointer, i->offsetFromArgBase()));
}
i++;
// argument 1: exitIndex
// argument 0: exitIndex
if (i->kind() == ABIArg::GPR)
masm.mov(ImmWord(exitIndex), i->gpr());
else
masm.store32(Imm32(exitIndex), Address(StackPointer, i->offsetFromArgBase()));
i++;
// argument 2: argc
// argument 1: argc
unsigned argc = exit.sig().args().length();
if (i->kind() == ABIArg::GPR)
masm.mov(ImmWord(argc), i->gpr());
@ -6274,7 +6162,7 @@ GenerateFFIInterpreterExit(ModuleCompiler &m, const ModuleCompiler::ExitDescript
masm.store32(Imm32(argc), Address(StackPointer, i->offsetFromArgBase()));
i++;
// argument 3: argv
// argument 2: argv
Address argv(StackPointer, offsetToArgv);
if (i->kind() == ABIArg::GPR) {
masm.computeEffectiveAddress(argv, i->gpr());
@ -6371,25 +6259,26 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
// Ion calls use the following stack layout (sp grows to the left):
// | return address | descriptor | callee | argc | this | arg1 | arg2 | ...
unsigned offsetToArgs = MaybeRetAddr;
unsigned argBytes = 3 * sizeof(size_t) + (1 + exit.sig().args().length()) * sizeof(Value);
unsigned totalIonBytes = offsetToArgs + argBytes + savedRegBytes;
unsigned offsetToIonArgs = MaybeRetAddr;
unsigned ionArgBytes = 3 * sizeof(size_t) + (1 + exit.sig().args().length()) * sizeof(Value);
unsigned totalIonBytes = offsetToIonArgs + ionArgBytes + savedRegBytes;
unsigned ionFrameSize = StackDecrementForCall(masm, totalIonBytes);
// Coercion calls use the following stack layout (sp grows to the left):
// | stack args | Value argv[1] | ...
// | stack args | padding | Value argv[1] | ...
// The padding between args and argv ensures that argv is aligned.
MIRTypeVector coerceArgTypes(m.cx());
coerceArgTypes.infallibleAppend(MIRType_Pointer); // cx
coerceArgTypes.infallibleAppend(MIRType_Pointer); // argv
unsigned bytesAfterArgs = sizeof(Value) + savedRegBytes;
unsigned coerceFrameSize = StackDecrementForCall(masm, coerceArgTypes, bytesAfterArgs);
unsigned offsetToCoerceArgv = AlignBytes(StackArgBytes(coerceArgTypes), sizeof(double));
unsigned totalCoerceBytes = offsetToCoerceArgv + sizeof(Value) + savedRegBytes;
unsigned coerceFrameSize = StackDecrementForCall(masm, totalCoerceBytes);
// Allocate a frame large enough for both of the above calls.
unsigned framePushed = Max(ionFrameSize, coerceFrameSize);
masm.reserveStack(framePushed);
// 1. Descriptor
size_t argOffset = offsetToArgs;
size_t argOffset = offsetToIonArgs;
uint32_t descriptor = MakeFrameDescriptor(framePushed, JitFrame_Entry);
masm.storePtr(ImmWord(uintptr_t(descriptor)), Address(StackPointer, argOffset));
argOffset += sizeof(size_t);
@ -6430,7 +6319,7 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
unsigned offsetToCallerStackArgs = framePushed + AsmJSFrameSize;
FillArgumentArray(m, exit.sig().args(), argOffset, offsetToCallerStackArgs, scratch);
argOffset += exit.sig().args().length() * sizeof(Value);
JS_ASSERT(argOffset == offsetToArgs + argBytes);
JS_ASSERT(argOffset == offsetToIonArgs + ionArgBytes);
// 6. Store asm.js pinned registers
#if defined(JS_CODEGEN_X64)
@ -6556,24 +6445,11 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
masm.setFramePushed(framePushed);
// Store return value into argv[0]
unsigned offsetToArgv = StackArgBytes(coerceArgTypes);
JS_ASSERT(offsetToArgv % sizeof(Value) == 0);
masm.storeValue(JSReturnOperand, Address(StackPointer, offsetToArgv));
masm.storeValue(JSReturnOperand, Address(StackPointer, offsetToCoerceArgv));
// argument 0: argv
ABIArgMIRTypeIter i(coerceArgTypes);
// argument 0: cx
LoadAsmJSActivationIntoRegister(masm, scratch);
if (i->kind() == ABIArg::GPR) {
LoadJSContextFromActivation(masm, scratch, i->gpr());
} else {
LoadJSContextFromActivation(masm, scratch, scratch);
masm.storePtr(scratch, Address(StackPointer, i->offsetFromArgBase()));
}
i++;
// argument 1: argv
Address argv(StackPointer, offsetToArgv);
Address argv(StackPointer, offsetToCoerceArgv);
if (i->kind() == ABIArg::GPR) {
masm.computeEffectiveAddress(argv, i->gpr());
} else {
@ -6589,12 +6465,12 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
case RetType::Signed:
masm.call(AsmJSImmPtr(AsmJSImm_CoerceInPlace_ToInt32));
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
masm.unboxInt32(Address(StackPointer, offsetToArgv), ReturnReg);
masm.unboxInt32(Address(StackPointer, offsetToCoerceArgv), ReturnReg);
break;
case RetType::Double:
masm.call(AsmJSImmPtr(AsmJSImm_CoerceInPlace_ToNumber));
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
masm.loadDouble(Address(StackPointer, offsetToArgv), ReturnDoubleReg);
masm.loadDouble(Address(StackPointer, offsetToCoerceArgv), ReturnDoubleReg);
break;
default:
MOZ_ASSUME_UNREACHABLE("Unsupported convert type");
@ -6629,7 +6505,7 @@ GenerateStackOverflowExit(ModuleCompiler &m, Label *throwLabel)
masm.align(CodeAlignment);
masm.bind(&m.stackOverflowLabel());
// The stack-overflow is checked before bumping the stack.
// For the benefit of AssertStackAlignment.
masm.setFramePushed(0);
// Store the frame pointer in AsmJSActivation::exitFP for stack unwinding.
@ -6637,24 +6513,8 @@ GenerateStackOverflowExit(ModuleCompiler &m, Label *throwLabel)
LoadAsmJSActivationIntoRegister(masm, activation);
masm.storePtr(StackPointer, Address(activation, AsmJSActivation::offsetOfExitFP()));
MIRTypeVector argTypes(m.cx());
argTypes.infallibleAppend(MIRType_Pointer); // cx
unsigned stackDec = StackDecrementForCall(masm, argTypes);
masm.reserveStack(stackDec);
ABIArgMIRTypeIter i(argTypes);
// argument 0: cx
if (i->kind() == ABIArg::GPR) {
LoadJSContextFromActivation(masm, activation, i->gpr());
} else {
LoadJSContextFromActivation(masm, activation, activation);
masm.storePtr(activation, Address(StackPointer, i->offsetFromArgBase()));
}
i++;
JS_ASSERT(i.done());
// Even without arguments, various platforms require stack adjustment.
masm.reserveStack(ComputeByteAlignment(AsmJSFrameSize + ShadowStackSpace, StackAlignment));
AssertStackAlignment(masm);
masm.call(AsmJSImmPtr(AsmJSImm_ReportOverRecursed));
@ -6697,34 +6557,23 @@ GenerateAsyncInterruptExit(ModuleCompiler &m, Label *throwLabel)
masm.setFramePushed(0); // set to zero so we can use masm.framePushed() below
masm.PushRegsInMask(AllRegsExceptSP); // save all GP/FP registers (except SP)
Register activation = ABIArgGenerator::NonArgReturnVolatileReg0;
Register scratch = ABIArgGenerator::NonArgReturnVolatileReg1;
Register scratch = ABIArgGenerator::NonArgReturnVolatileReg0;
// Store resumePC into the reserved space.
LoadAsmJSActivationIntoRegister(masm, activation);
masm.loadPtr(Address(activation, AsmJSActivation::offsetOfResumePC()), scratch);
LoadAsmJSActivationIntoRegister(masm, scratch);
masm.loadPtr(Address(scratch, AsmJSActivation::offsetOfResumePC()), scratch);
masm.storePtr(scratch, Address(StackPointer, masm.framePushed() + sizeof(void*)));
// We know that StackPointer is word-aligned, but not necessarily
// stack-aligned, so we need to align it dynamically.
masm.mov(StackPointer, ABIArgGenerator::NonVolatileReg);
#if defined(JS_CODEGEN_X86)
// Ensure that at least one slot is pushed for passing 'cx' below.
masm.push(Imm32(0));
#endif
masm.andPtr(Imm32(~(StackAlignment - 1)), StackPointer);
if (ShadowStackSpace)
masm.subPtr(Imm32(ShadowStackSpace), StackPointer);
// argument 0: cx
#if defined(JS_CODEGEN_X86)
LoadJSContextFromActivation(masm, activation, scratch);
masm.storePtr(scratch, Address(StackPointer, 0));
#elif defined(JS_CODEGEN_X64)
LoadJSContextFromActivation(masm, activation, IntArgReg0);
#endif
AssertStackAlignment(masm);
masm.call(AsmJSImmPtr(AsmJSImm_HandleExecutionInterrupt));
masm.branchIfFalseBool(ReturnReg, throwLabel);
// Restore the StackPointer to it's position before the call.
@ -6752,9 +6601,6 @@ GenerateAsyncInterruptExit(ModuleCompiler &m, Label *throwLabel)
masm.loadPtr(Address(IntArgReg0, AsmJSActivation::offsetOfResumePC()), IntArgReg1);
masm.storePtr(IntArgReg1, Address(s0, masm.framePushed()));
// argument 0: cx
masm.loadPtr(Address(IntArgReg0, AsmJSActivation::offsetOfContext()), IntArgReg0);
// MIPS ABI requires rewserving stack for registes $a0 to $a3.
masm.subPtr(Imm32(4 * sizeof(intptr_t)), StackPointer);
@ -6791,9 +6637,6 @@ GenerateAsyncInterruptExit(ModuleCompiler &m, Label *throwLabel)
masm.loadPtr(Address(IntArgReg0, AsmJSActivation::offsetOfResumePC()), IntArgReg1);
masm.storePtr(IntArgReg1, Address(r6, 14 * sizeof(uint32_t*)));
// argument 0: cx
masm.loadPtr(Address(IntArgReg0, AsmJSActivation::offsetOfContext()), IntArgReg0);
masm.PushRegsInMask(RegisterSet(GeneralRegisterSet(0), FloatRegisterSet(FloatRegisters::AllDoubleMask))); // save all FP registers
masm.call(AsmJSImm_HandleExecutionInterrupt);
masm.branchIfFalseBool(ReturnReg, throwLabel);
@ -6842,9 +6685,6 @@ GenerateSyncInterruptExit(ModuleCompiler &m, Label *throwLabel)
masm.align(CodeAlignment);
masm.bind(&m.syncInterruptLabel());
MIRTypeVector argTypes(m.cx());
argTypes.infallibleAppend(MIRType_Pointer); // cx
// See AsmJSFrameSize comment in Assembler-shared.h.
#if defined(JS_CODEGEN_ARM)
masm.push(lr);
@ -6859,22 +6699,9 @@ GenerateSyncInterruptExit(ModuleCompiler &m, Label *throwLabel)
masm.PushRegsInMask(VolatileRegs);
unsigned stackDec = StackDecrementForCall(masm, argTypes);
unsigned stackDec = StackDecrementForCall(masm, ShadowStackSpace);
masm.reserveStack(stackDec);
ABIArgMIRTypeIter i(argTypes);
// argument 0: cx
if (i->kind() == ABIArg::GPR) {
LoadJSContextFromActivation(masm, activation, i->gpr());
} else {
LoadJSContextFromActivation(masm, activation, activation);
masm.storePtr(activation, Address(StackPointer, i->offsetFromArgBase()));
}
i++;
JS_ASSERT(i.done());
AssertStackAlignment(masm);
masm.call(AsmJSImmPtr(AsmJSImm_HandleExecutionInterrupt));
masm.branchIfFalseBool(ReturnReg, throwLabel);

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

@ -32,6 +32,7 @@
#include "jsobjinlines.h"
#include "frontend/ParseNode-inl.h"
#include "vm/Stack-inl.h"
using namespace js;
using namespace jit;
@ -448,9 +449,25 @@ AsmJSModule::setAutoFlushICacheRange()
AutoFlushICache::setRange(uintptr_t(code_), pod.codeBytes_);
}
static int32_t
CoerceInPlace_ToInt32(JSContext *cx, MutableHandleValue val)
static void
AsmJSReportOverRecursed()
{
JSContext *cx = PerThreadData::innermostAsmJSActivation()->cx();
js_ReportOverRecursed(cx);
}
static void
AsmJSHandleExecutionInterrupt()
{
JSContext *cx = PerThreadData::innermostAsmJSActivation()->cx();
HandleExecutionInterrupt(cx);
}
static int32_t
CoerceInPlace_ToInt32(MutableHandleValue val)
{
JSContext *cx = PerThreadData::innermostAsmJSActivation()->cx();
int32_t i32;
if (!ToInt32(cx, val, &i32))
return false;
@ -460,8 +477,10 @@ CoerceInPlace_ToInt32(JSContext *cx, MutableHandleValue val)
}
static int32_t
CoerceInPlace_ToNumber(JSContext *cx, MutableHandleValue val)
CoerceInPlace_ToNumber(MutableHandleValue val)
{
JSContext *cx = PerThreadData::innermostAsmJSActivation()->cx();
double dbl;
if (!ToNumber(cx, val, &dbl))
return false;
@ -470,19 +489,109 @@ CoerceInPlace_ToNumber(JSContext *cx, MutableHandleValue val)
return true;
}
namespace js {
static bool
TryEnablingIon(JSContext *cx, AsmJSModule &module, HandleFunction fun, uint32_t exitIndex,
int32_t argc, Value *argv)
{
if (!fun->hasScript())
return true;
// Defined in AsmJS.cpp:
// Test if the function is Ion compiled
JSScript *script = fun->nonLazyScript();
if (!script->hasIonScript())
return true;
int32_t
InvokeFromAsmJS_Ignore(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv);
// Currently we can't rectify arguments. Therefore disabling if argc is too low.
if (fun->nargs() > size_t(argc))
return true;
int32_t
InvokeFromAsmJS_ToInt32(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv);
// Normally the types should corresond, since we just ran with those types,
// but there are reports this is asserting. Therefore doing it as a check, instead of DEBUG only.
if (!types::TypeScript::ThisTypes(script)->hasType(types::Type::UndefinedType()))
return true;
for(uint32_t i = 0; i < fun->nargs(); i++) {
types::StackTypeSet *typeset = types::TypeScript::ArgTypes(script, i);
types::Type type = types::Type::DoubleType();
if (!argv[i].isDouble())
type = types::Type::PrimitiveType(argv[i].extractNonDoubleType());
if (!typeset->hasType(type))
return true;
}
int32_t
InvokeFromAsmJS_ToNumber(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv);
// Enable
IonScript *ionScript = script->ionScript();
if (!ionScript->addDependentAsmJSModule(cx, DependentAsmJSModuleExit(&module, exitIndex)))
return false;
module.exitIndexToGlobalDatum(exitIndex).exit = module.ionExitTrampoline(module.exit(exitIndex));
return true;
}
static bool
InvokeFromAsmJS(AsmJSActivation *activation, int32_t exitIndex, int32_t argc, Value *argv,
MutableHandleValue rval)
{
JSContext *cx = activation->cx();
AsmJSModule &module = activation->module();
RootedFunction fun(cx, module.exitIndexToGlobalDatum(exitIndex).fun);
RootedValue fval(cx, ObjectValue(*fun));
if (!Invoke(cx, UndefinedValue(), fval, argc, argv, rval))
return false;
return TryEnablingIon(cx, module, fun, exitIndex, argc, argv);
}
// Use an int32_t return type instead of bool since bool does not have a
// specified width and the caller is assuming a word-sized return.
static int32_t
InvokeFromAsmJS_Ignore(int32_t exitIndex, int32_t argc, Value *argv)
{
AsmJSActivation *activation = PerThreadData::innermostAsmJSActivation();
JSContext *cx = activation->cx();
RootedValue rval(cx);
return InvokeFromAsmJS(activation, exitIndex, argc, argv, &rval);
}
// Use an int32_t return type instead of bool since bool does not have a
// specified width and the caller is assuming a word-sized return.
static int32_t
InvokeFromAsmJS_ToInt32(int32_t exitIndex, int32_t argc, Value *argv)
{
AsmJSActivation *activation = PerThreadData::innermostAsmJSActivation();
JSContext *cx = activation->cx();
RootedValue rval(cx);
if (!InvokeFromAsmJS(activation, exitIndex, argc, argv, &rval))
return false;
int32_t i32;
if (!ToInt32(cx, rval, &i32))
return false;
argv[0] = Int32Value(i32);
return true;
}
// Use an int32_t return type instead of bool since bool does not have a
// specified width and the caller is assuming a word-sized return.
static int32_t
InvokeFromAsmJS_ToNumber(int32_t exitIndex, int32_t argc, Value *argv)
{
AsmJSActivation *activation = PerThreadData::innermostAsmJSActivation();
JSContext *cx = activation->cx();
RootedValue rval(cx);
if (!InvokeFromAsmJS(activation, exitIndex, argc, argv, &rval))
return false;
double dbl;
if (!ToNumber(cx, rval, &dbl))
return false;
argv[0] = DoubleValue(dbl);
return true;
}
#if defined(JS_CODEGEN_ARM)
@ -524,19 +633,19 @@ AddressOf(AsmJSImmKind kind, ExclusiveContext *cx)
case AsmJSImm_StackLimit:
return cx->stackLimitAddressForJitCode(StackForUntrustedScript);
case AsmJSImm_ReportOverRecursed:
return RedirectCall(FuncCast<void (JSContext*)>(js_ReportOverRecursed), Args_General1);
return RedirectCall(FuncCast(AsmJSReportOverRecursed), Args_General0);
case AsmJSImm_HandleExecutionInterrupt:
return RedirectCall(FuncCast(js::HandleExecutionInterrupt), Args_General1);
return RedirectCall(FuncCast(AsmJSHandleExecutionInterrupt), Args_General0);
case AsmJSImm_InvokeFromAsmJS_Ignore:
return RedirectCall(FuncCast(InvokeFromAsmJS_Ignore), Args_General4);
return RedirectCall(FuncCast(InvokeFromAsmJS_Ignore), Args_General3);
case AsmJSImm_InvokeFromAsmJS_ToInt32:
return RedirectCall(FuncCast(InvokeFromAsmJS_ToInt32), Args_General4);
return RedirectCall(FuncCast(InvokeFromAsmJS_ToInt32), Args_General3);
case AsmJSImm_InvokeFromAsmJS_ToNumber:
return RedirectCall(FuncCast(InvokeFromAsmJS_ToNumber), Args_General4);
return RedirectCall(FuncCast(InvokeFromAsmJS_ToNumber), Args_General3);
case AsmJSImm_CoerceInPlace_ToInt32:
return RedirectCall(FuncCast(CoerceInPlace_ToInt32), Args_General2);
return RedirectCall(FuncCast(CoerceInPlace_ToInt32), Args_General1);
case AsmJSImm_CoerceInPlace_ToNumber:
return RedirectCall(FuncCast(CoerceInPlace_ToNumber), Args_General2);
return RedirectCall(FuncCast(CoerceInPlace_ToNumber), Args_General1);
case AsmJSImm_ToInt32:
return RedirectCall(FuncCast<int32_t (double)>(js::ToInt32), Args_Int_Double);
#if defined(JS_CODEGEN_ARM)

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

@ -150,16 +150,6 @@ using mozilla::DebugOnly;
// thread/stack as the victim (Unix and Windows), we can use TLS to find any
// currently executing asm.js code.
#if !defined(XP_MACOSX)
static AsmJSActivation *
InnermostAsmJSActivation()
{
PerThreadData *threadData = TlsPerThreadData.get();
if (!threadData)
return nullptr;
return threadData->asmJSActivationStackFromOwnerThread();
}
static JSRuntime *
RuntimeForCurrentThread()
{
@ -451,7 +441,7 @@ HandleException(PEXCEPTION_POINTERS exception)
if (rt->jitRuntime() && rt->jitRuntime()->handleAccessViolation(rt, faultingAddress))
return true;
AsmJSActivation *activation = InnermostAsmJSActivation();
AsmJSActivation *activation = PerThreadData::innermostAsmJSActivation();
if (!activation)
return false;
@ -648,7 +638,7 @@ HandleMachException(JSRuntime *rt, const ExceptionRequest &request)
if (rt->jitRuntime() && rt->jitRuntime()->handleAccessViolation(rt, faultingAddress))
return true;
AsmJSActivation *activation = rt->mainThread.asmJSActivationStackFromAnyThread();
AsmJSActivation *activation = rt->mainThread.asmJSActivationStack();
if (!activation)
return false;
@ -898,7 +888,7 @@ HandleSignal(int signum, siginfo_t *info, void *ctx)
if (rt->jitRuntime() && rt->jitRuntime()->handleAccessViolation(rt, faultingAddress))
return true;
AsmJSActivation *activation = InnermostAsmJSActivation();
AsmJSActivation *activation = PerThreadData::innermostAsmJSActivation();
if (!activation)
return false;
@ -1048,7 +1038,7 @@ js::RequestInterruptForAsmJSCode(JSRuntime *rt, int interruptModeRaw)
return;
}
AsmJSActivation *activation = rt->mainThread.asmJSActivationStackFromAnyThread();
AsmJSActivation *activation = rt->mainThread.asmJSActivationStack();
if (!activation)
return;

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

@ -4065,7 +4065,6 @@ Simulator::execute()
// Get the PC to simulate. Cannot use the accessor here as we need the raw
// PC value and not the one used as input to arithmetic instructions.
int program_counter = get_pc();
AsmJSActivation *activation = TlsPerThreadData.get()->asmJSActivationStackFromOwnerThread();
while (program_counter != end_sim_pc) {
if (EnableStopSimAt && (icount_ == Simulator::StopSimAt)) {
@ -4080,7 +4079,7 @@ Simulator::execute()
int32_t rpc = resume_pc_;
if (MOZ_UNLIKELY(rpc != 0)) {
// AsmJS signal handler ran and we have to adjust the pc.
activation->setResumePC((void *)get_pc());
PerThreadData::innermostAsmJSActivation()->setResumePC((void *)get_pc());
set_pc(rpc);
resume_pc_ = 0;
}

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

@ -3310,7 +3310,7 @@ Simulator::execute()
// Get the PC to simulate. Cannot use the accessor here as we need the
// raw PC value and not the one used as input to arithmetic instructions.
int program_counter = get_pc();
AsmJSActivation *activation = TlsPerThreadData.get()->asmJSActivationStackFromOwnerThread();
AsmJSActivation *activation = TlsPerThreadData.get()->asmJSActivationStack();
while (program_counter != end_sim_pc) {
if (enableStopSimAt && (icount_ == Simulator::StopSimAt)) {

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

@ -548,7 +548,7 @@ ArrayBufferObject::canNeuterAsmJSArrayBuffer(JSContext *cx, ArrayBufferObject &b
{
JS_ASSERT(!buffer.isSharedArrayBuffer());
#ifdef JS_ION
AsmJSActivation *act = cx->mainThread().asmJSActivationStackFromOwnerThread();
AsmJSActivation *act = cx->mainThread().asmJSActivationStack();
for (; act; act = act->prevAsmJS()) {
if (act->module().maybeHeapBufferObject() == &buffer)
break;

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

@ -591,11 +591,12 @@ class PerThreadData : public PerThreadDataFriendFields
return offsetof(PerThreadData, activation_);
}
js::AsmJSActivation *asmJSActivationStackFromAnyThread() const {
js::AsmJSActivation *asmJSActivationStack() const {
return asmJSActivationStack_;
}
js::AsmJSActivation *asmJSActivationStackFromOwnerThread() const {
return asmJSActivationStack_;
static js::AsmJSActivation *innermostAsmJSActivation() {
PerThreadData *ptd = TlsPerThreadData.get();
return ptd ? ptd->asmJSActivationStack_ : nullptr;
}
js::Activation *activation() const {