Bug 1103056 - Make optimized asm.js FFI exit also work with Baseline scripts. r=luke,h4writer

This commit is contained in:
Jan de Mooij 2014-11-25 13:43:30 +01:00
parent 59dafd8d19
commit 84ad6705ec
15 changed files with 133 additions and 112 deletions

View File

@ -79,7 +79,7 @@ AsmJSFrameIterator::settle()
fp_ = nullptr;
MOZ_ASSERT(done());
break;
case AsmJSModule::CodeRange::IonFFI:
case AsmJSModule::CodeRange::JitFFI:
case AsmJSModule::CodeRange::SlowFFI:
case AsmJSModule::CodeRange::Interrupt:
case AsmJSModule::CodeRange::Inline:
@ -458,7 +458,7 @@ AsmJSProfilingFrameIterator::initFromFP(const AsmJSActivation &activation)
callerFP_ = CallerFPFromFP(fp);
AssertMatchesCallSite(*module_, codeRange, callerPC_, callerFP_, fp);
break;
case AsmJSModule::CodeRange::IonFFI:
case AsmJSModule::CodeRange::JitFFI:
case AsmJSModule::CodeRange::SlowFFI:
case AsmJSModule::CodeRange::Interrupt:
case AsmJSModule::CodeRange::Inline:
@ -513,7 +513,7 @@ AsmJSProfilingFrameIterator::AsmJSProfilingFrameIterator(const AsmJSActivation &
const AsmJSModule::CodeRange *codeRange = module_->lookupCodeRange(state.pc);
switch (codeRange->kind()) {
case AsmJSModule::CodeRange::Function:
case AsmJSModule::CodeRange::IonFFI:
case AsmJSModule::CodeRange::JitFFI:
case AsmJSModule::CodeRange::SlowFFI:
case AsmJSModule::CodeRange::Interrupt:
case AsmJSModule::CodeRange::Thunk: {
@ -615,7 +615,7 @@ AsmJSProfilingFrameIterator::operator++()
callerPC_ = nullptr;
break;
case AsmJSModule::CodeRange::Function:
case AsmJSModule::CodeRange::IonFFI:
case AsmJSModule::CodeRange::JitFFI:
case AsmJSModule::CodeRange::SlowFFI:
case AsmJSModule::CodeRange::Interrupt:
case AsmJSModule::CodeRange::Inline:
@ -672,15 +672,15 @@ AsmJSProfilingFrameIterator::label() const
//
// NB: these labels are regexp-matched by
// browser/devtools/profiler/cleopatra/js/parserWorker.js.
const char *ionFFIDescription = "fast FFI trampoline (in asm.js)";
const char *jitFFIDescription = "fast FFI trampoline (in asm.js)";
const char *slowFFIDescription = "slow FFI trampoline (in asm.js)";
const char *interruptDescription = "interrupt due to out-of-bounds or long execution (in asm.js)";
switch (AsmJSExit::ExtractReasonKind(exitReason_)) {
case AsmJSExit::Reason_None:
break;
case AsmJSExit::Reason_IonFFI:
return ionFFIDescription;
case AsmJSExit::Reason_JitFFI:
return jitFFIDescription;
case AsmJSExit::Reason_SlowFFI:
return slowFFIDescription;
case AsmJSExit::Reason_Interrupt:
@ -693,7 +693,7 @@ AsmJSProfilingFrameIterator::label() const
switch (codeRange->kind()) {
case AsmJSModule::CodeRange::Function: return codeRange->functionProfilingLabel(*module_);
case AsmJSModule::CodeRange::Entry: return "entry trampoline (in asm.js)";
case AsmJSModule::CodeRange::IonFFI: return ionFFIDescription;
case AsmJSModule::CodeRange::JitFFI: return jitFFIDescription;
case AsmJSModule::CodeRange::SlowFFI: return slowFFIDescription;
case AsmJSModule::CodeRange::Interrupt: return interruptDescription;
case AsmJSModule::CodeRange::Inline: return "inline stub (in asm.js)";

View File

@ -69,7 +69,7 @@ namespace AsmJSExit
// handler).
enum ReasonKind {
Reason_None,
Reason_IonFFI,
Reason_JitFFI,
Reason_SlowFFI,
Reason_Interrupt,
Reason_Builtin
@ -106,7 +106,7 @@ namespace AsmJSExit
typedef uint32_t Reason;
static const uint32_t None = Reason_None;
static const uint32_t IonFFI = Reason_IonFFI;
static const uint32_t JitFFI = Reason_JitFFI;
static const uint32_t SlowFFI = Reason_SlowFFI;
static const uint32_t Interrupt = Reason_Interrupt;
static inline Reason Builtin(BuiltinKind builtin) {

View File

@ -105,11 +105,11 @@ AsmJSModule::~AsmJSModule()
if (code_) {
for (unsigned i = 0; i < numExits(); i++) {
AsmJSModule::ExitDatum &exitDatum = exitIndexToGlobalDatum(i);
if (!exitDatum.ionScript)
if (!exitDatum.baselineScript)
continue;
jit::DependentAsmJSModuleExit exit(this, i);
exitDatum.ionScript->removeDependentAsmJSModule(exit);
exitDatum.baselineScript->removeDependentAsmJSModule(exit);
}
DeallocateExecutableMemory(code_, pod.totalBytes_, AsmJSPageSize);
@ -501,23 +501,31 @@ CoerceInPlace_ToNumber(MutableHandleValue val)
}
static bool
TryEnablingIon(JSContext *cx, AsmJSModule &module, HandleFunction fun, uint32_t exitIndex,
TryEnablingJit(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
// Test if the function is JIT compiled.
JSScript *script = fun->nonLazyScript();
if (!script->hasIonScript())
if (!script->hasBaselineScript()) {
MOZ_ASSERT(!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 correspond, since we just ran with those types,
// but there are reports this is asserting. Therefore doing it as a check, instead of DEBUG only.
// Ensure the argument types are included in the argument TypeSets stored in
// the TypeScript. This is necessary for Ion, because the FFI exit will
// use the skip-arg-checks entry point.
//
// Note that the TypeScript is never discarded while the script has a
// BaselineScript, so if those checks hold now they must hold at least until
// the BaselineScript is discarded and when that happens the FFI exit is
// patched back.
if (!types::TypeScript::ThisTypes(script)->hasType(types::Type::UndefinedType()))
return true;
for (uint32_t i = 0; i < fun->nargs(); i++) {
@ -533,11 +541,11 @@ TryEnablingIon(JSContext *cx, AsmJSModule &module, HandleFunction fun, uint32_t
if (module.exitIsOptimized(exitIndex))
return true;
IonScript *ionScript = script->ionScript();
if (!ionScript->addDependentAsmJSModule(cx, DependentAsmJSModuleExit(&module, exitIndex)))
BaselineScript *baselineScript = script->baselineScript();
if (!baselineScript->addDependentAsmJSModule(cx, DependentAsmJSModuleExit(&module, exitIndex)))
return false;
module.optimizeExit(exitIndex, ionScript);
module.optimizeExit(exitIndex, baselineScript);
return true;
}
@ -553,7 +561,7 @@ InvokeFromAsmJS(AsmJSActivation *activation, int32_t exitIndex, int32_t argc, Va
if (!Invoke(cx, UndefinedValue(), fval, argc, argv, rval))
return false;
return TryEnablingIon(cx, module, fun, exitIndex, argc, argv);
return TryEnablingJit(cx, module, fun, exitIndex, argc, argv);
}
// Use an int32_t return type instead of bool since bool does not have a
@ -748,7 +756,7 @@ AsmJSModule::staticallyLink(ExclusiveContext *cx)
AsmJSModule::ExitDatum &exitDatum = exitIndexToGlobalDatum(i);
exitDatum.exit = interpExitTrampoline(exits_[i]);
exitDatum.fun = nullptr;
exitDatum.ionScript = nullptr;
exitDatum.baselineScript = nullptr;
}
MOZ_ASSERT(isStaticallyLinked());
@ -904,7 +912,7 @@ AsmJSModule::detachHeap(JSContext *cx)
// Even if this->active(), to reach here, the activation must have called
// out via an FFI stub. FFI stubs check if heapDatum() is null on reentry
// and throw an exception if so.
MOZ_ASSERT_IF(active(), activation()->exitReason() == AsmJSExit::Reason_IonFFI ||
MOZ_ASSERT_IF(active(), activation()->exitReason() == AsmJSExit::Reason_JitFFI ||
activation()->exitReason() == AsmJSExit::Reason_SlowFFI);
restoreHeapToInitialState(maybeHeap_);
@ -1338,7 +1346,7 @@ AsmJSModule::CodeRange::CodeRange(Kind kind, uint32_t begin, uint32_t profilingR
MOZ_ASSERT(begin_ < profilingReturn_);
MOZ_ASSERT(profilingReturn_ < end_);
MOZ_ASSERT(u.kind_ == IonFFI || u.kind_ == SlowFFI || u.kind_ == Interrupt);
MOZ_ASSERT(u.kind_ == JitFFI || u.kind_ == SlowFFI || u.kind_ == Interrupt);
}
AsmJSModule::CodeRange::CodeRange(AsmJSExit::BuiltinKind builtin, uint32_t begin,

View File

@ -371,7 +371,7 @@ class AsmJSModule
unsigned ffiIndex_;
unsigned globalDataOffset_;
unsigned interpCodeOffset_;
unsigned ionCodeOffset_;
unsigned jitCodeOffset_;
friend class AsmJSModule;
@ -379,7 +379,7 @@ class AsmJSModule
Exit() {}
Exit(unsigned ffiIndex, unsigned globalDataOffset)
: ffiIndex_(ffiIndex), globalDataOffset_(globalDataOffset),
interpCodeOffset_(0), ionCodeOffset_(0)
interpCodeOffset_(0), jitCodeOffset_(0)
{}
unsigned ffiIndex() const {
return ffiIndex_;
@ -391,13 +391,13 @@ class AsmJSModule
MOZ_ASSERT(!interpCodeOffset_);
interpCodeOffset_ = off;
}
void initIonOffset(unsigned off) {
MOZ_ASSERT(!ionCodeOffset_);
ionCodeOffset_ = off;
void initJitOffset(unsigned off) {
MOZ_ASSERT(!jitCodeOffset_);
jitCodeOffset_ = off;
}
void updateOffsets(jit::MacroAssembler &masm) {
interpCodeOffset_ = masm.actualOffset(interpCodeOffset_);
ionCodeOffset_ = masm.actualOffset(ionCodeOffset_);
jitCodeOffset_ = masm.actualOffset(jitCodeOffset_);
}
size_t serializedSize() const;
@ -419,7 +419,7 @@ class AsmJSModule
struct ExitDatum
{
uint8_t *exit;
jit::IonScript *ionScript;
jit::BaselineScript *baselineScript;
HeapPtrFunction fun;
};
@ -558,7 +558,7 @@ class AsmJSModule
void setDeltas(uint32_t entry, uint32_t profilingJump, uint32_t profilingEpilogue);
public:
enum Kind { Function, Entry, IonFFI, SlowFFI, Interrupt, Thunk, Inline };
enum Kind { Function, Entry, JitFFI, SlowFFI, Interrupt, Thunk, Inline };
CodeRange() {}
CodeRange(uint32_t nameIndex, uint32_t lineNumber, const AsmJSFunctionLabels &l);
@ -570,7 +570,7 @@ class AsmJSModule
Kind kind() const { return Kind(u.kind_); }
bool isFunction() const { return kind() == Function; }
bool isEntry() const { return kind() == Entry; }
bool isFFI() const { return kind() == IonFFI || kind() == SlowFFI; }
bool isFFI() const { return kind() == JitFFI || kind() == SlowFFI; }
bool isInterrupt() const { return kind() == Interrupt; }
bool isThunk() const { return kind() == Thunk; }
@ -1325,10 +1325,10 @@ class AsmJSModule
MOZ_ASSERT(exit.interpCodeOffset_);
return code_ + exit.interpCodeOffset_;
}
uint8_t *ionExitTrampoline(const Exit &exit) const {
uint8_t *jitExitTrampoline(const Exit &exit) const {
MOZ_ASSERT(isFinished());
MOZ_ASSERT(exit.ionCodeOffset_);
return code_ + exit.ionCodeOffset_;
MOZ_ASSERT(exit.jitCodeOffset_);
return code_ + exit.jitCodeOffset_;
}
public:
@ -1463,17 +1463,17 @@ class AsmJSModule
ExitDatum &exitDatum = exitIndexToGlobalDatum(exitIndex);
return exitDatum.exit != interpExitTrampoline(exit(exitIndex));
}
void optimizeExit(unsigned exitIndex, jit::IonScript *ionScript) const {
void optimizeExit(unsigned exitIndex, jit::BaselineScript *baselineScript) const {
MOZ_ASSERT(!exitIsOptimized(exitIndex));
ExitDatum &exitDatum = exitIndexToGlobalDatum(exitIndex);
exitDatum.exit = ionExitTrampoline(exit(exitIndex));
exitDatum.ionScript = ionScript;
exitDatum.exit = jitExitTrampoline(exit(exitIndex));
exitDatum.baselineScript = baselineScript;
}
void detachIonCompilation(size_t exitIndex) const {
void detachJitCompilation(size_t exitIndex) const {
MOZ_ASSERT(isFinished());
ExitDatum &exitDatum = exitIndexToGlobalDatum(exitIndex);
exitDatum.exit = interpExitTrampoline(exit(exitIndex));
exitDatum.ionScript = nullptr;
exitDatum.baselineScript = nullptr;
}
/*************************************************************************/

View File

@ -1870,13 +1870,13 @@ class MOZ_STACK_CLASS ModuleCompiler
uint32_t end = masm_.currentOffset();
return module_->addCodeRange(AsmJSModule::CodeRange::SlowFFI, beg, pret, end);
}
bool finishGeneratingIonExit(unsigned exitIndex, Label *begin, Label *profilingReturn) {
bool finishGeneratingJitExit(unsigned exitIndex, Label *begin, Label *profilingReturn) {
MOZ_ASSERT(finishedFunctionBodies_);
uint32_t beg = begin->offset();
module_->exit(exitIndex).initIonOffset(beg);
module_->exit(exitIndex).initJitOffset(beg);
uint32_t pret = profilingReturn->offset();
uint32_t end = masm_.currentOffset();
return module_->addCodeRange(AsmJSModule::CodeRange::IonFFI, beg, pret, end);
return module_->addCodeRange(AsmJSModule::CodeRange::JitFFI, beg, pret, end);
}
bool finishGeneratingInterrupt(Label *begin, Label *profilingReturn) {
MOZ_ASSERT(finishedFunctionBodies_);
@ -8453,7 +8453,7 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
unsigned framePushed = Max(ionFrameSize, coerceFrameSize);
Label begin;
GenerateAsmJSExitPrologue(masm, framePushed, AsmJSExit::IonFFI, &begin);
GenerateAsmJSExitPrologue(masm, framePushed, AsmJSExit::JitFFI, &begin);
// 1. Descriptor
size_t argOffset = offsetToIonArgs;
@ -8501,7 +8501,7 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
argOffset += exit.sig().args().length() * sizeof(Value);
MOZ_ASSERT(argOffset == offsetToIonArgs + ionArgBytes);
// 6. Ion will clobber all registers, even non-volatiles. GlobalReg and
// 6. Jit code will clobber all registers, even non-volatiles. GlobalReg and
// HeapReg are removed from the general register set for asm.js code, so
// these will not have been saved by the caller like all other registers,
// so they must be explicitly preserved. Only save GlobalReg since
@ -8553,7 +8553,7 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
// 2. Call
AssertStackAlignment(masm, AsmJSStackAlignment);
masm.callIonFromAsmJS(callee);
masm.callJitFromAsmJS(callee);
AssertStackAlignment(masm, AsmJSStackAlignment);
{
@ -8625,7 +8625,7 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
GenerateCheckForHeapDetachment(m, ABIArgGenerator::NonReturn_VolatileReg0);
Label profilingReturn;
GenerateAsmJSExitEpilogue(masm, framePushed, AsmJSExit::IonFFI, &profilingReturn);
GenerateAsmJSExitEpilogue(masm, framePushed, AsmJSExit::JitFFI, &profilingReturn);
if (oolConvert.used()) {
masm.bind(&oolConvert);
@ -8669,7 +8669,7 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
MOZ_ASSERT(masm.framePushed() == 0);
return m.finishGeneratingIonExit(exitIndex, &begin, &profilingReturn) && !masm.oom();
return m.finishGeneratingJitExit(exitIndex, &begin, &profilingReturn) && !masm.oom();
}
// See "asm.js FFI calls" comment above.

View File

@ -8,6 +8,7 @@
#include "mozilla/MemoryReporting.h"
#include "asmjs/AsmJSModule.h"
#include "jit/BaselineCompiler.h"
#include "jit/BaselineIC.h"
#include "jit/CompileInfo.h"
@ -45,6 +46,7 @@ BaselineScript::BaselineScript(uint32_t prologueOffset, uint32_t epilogueOffset,
: method_(nullptr),
templateScope_(nullptr),
fallbackStubSpace_(),
dependentAsmJSModules_(nullptr),
prologueOffset_(prologueOffset),
epilogueOffset_(epilogueOffset),
#ifdef DEBUG
@ -440,9 +442,54 @@ BaselineScript::Destroy(FreeOp *fop, BaselineScript *script)
MOZ_ASSERT(fop->runtime()->gc.nursery.isEmpty());
#endif
script->unlinkDependentAsmJSModules(fop);
fop->delete_(script);
}
void
BaselineScript::unlinkDependentAsmJSModules(FreeOp *fop)
{
// Remove any links from AsmJSModules that contain optimized FFI calls into
// this BaselineScript.
if (dependentAsmJSModules_) {
for (size_t i = 0; i < dependentAsmJSModules_->length(); i++) {
DependentAsmJSModuleExit exit = (*dependentAsmJSModules_)[i];
exit.module->detachJitCompilation(exit.exitIndex);
}
fop->delete_(dependentAsmJSModules_);
dependentAsmJSModules_ = nullptr;
}
}
bool
BaselineScript::addDependentAsmJSModule(JSContext *cx, DependentAsmJSModuleExit exit)
{
if (!dependentAsmJSModules_) {
dependentAsmJSModules_ = cx->new_<Vector<DependentAsmJSModuleExit> >(cx);
if (!dependentAsmJSModules_)
return false;
}
return dependentAsmJSModules_->append(exit);
}
void
BaselineScript::removeDependentAsmJSModule(DependentAsmJSModuleExit exit)
{
if (!dependentAsmJSModules_)
return;
for (size_t i = 0; i < dependentAsmJSModules_->length(); i++) {
if ((*dependentAsmJSModules_)[i].module == exit.module &&
(*dependentAsmJSModules_)[i].exitIndex == exit.exitIndex)
{
dependentAsmJSModules_->erase(dependentAsmJSModules_->begin() + i);
break;
}
}
}
ICEntry &
BaselineScript::icEntry(size_t index)
{

View File

@ -93,6 +93,19 @@ struct PCMappingIndexEntry
uint32_t bufferOffset;
};
// Describes a single AsmJSModule which jumps (via an FFI exit with the given
// index) directly to a BaselineScript or IonScript.
struct DependentAsmJSModuleExit
{
const AsmJSModule *module;
size_t exitIndex;
DependentAsmJSModuleExit(const AsmJSModule *module, size_t exitIndex)
: module(module),
exitIndex(exitIndex)
{ }
};
struct BaselineScript
{
public:
@ -114,6 +127,10 @@ struct BaselineScript
// Allocated space for fallback stubs.
FallbackICStubSpace fallbackStubSpace_;
// If non-null, the list of AsmJSModules that contain an optimized call
// directly to this script.
Vector<DependentAsmJSModuleExit> *dependentAsmJSModules_;
// Native code offset right before the scope chain is initialized.
uint32_t prologueOffset_;
@ -347,6 +364,10 @@ struct BaselineScript
jsbytecode *pcForNativeAddress(JSScript *script, uint8_t *nativeAddress);
jsbytecode *pcForNativeOffset(JSScript *script, uint32_t nativeOffset);
bool addDependentAsmJSModule(JSContext *cx, DependentAsmJSModuleExit exit);
void unlinkDependentAsmJSModules(FreeOp *fop);
void removeDependentAsmJSModule(DependentAsmJSModuleExit exit);
private:
jsbytecode *pcForNativeOffset(JSScript *script, uint32_t nativeOffset, bool isReturn);

View File

@ -12,7 +12,6 @@
#include "jscompartment.h"
#include "jsprf.h"
#include "asmjs/AsmJSModule.h"
#include "gc/Marking.h"
#include "jit/AliasAnalysis.h"
#include "jit/BacktrackingAllocator.h"
@ -844,7 +843,6 @@ IonScript::IonScript()
parallelAge_(0),
recompileInfo_(),
osrPcMismatchCounter_(0),
dependentAsmJSModules(nullptr),
pendingBuilder_(nullptr)
{
}
@ -1222,32 +1220,9 @@ IonScript::destroyCaches()
getCacheFromIndex(i).destroy();
}
bool
IonScript::addDependentAsmJSModule(JSContext *cx, DependentAsmJSModuleExit exit)
{
if (!dependentAsmJSModules) {
dependentAsmJSModules = cx->new_<Vector<DependentAsmJSModuleExit> >(cx);
if (!dependentAsmJSModules)
return false;
}
return dependentAsmJSModules->append(exit);
}
void
IonScript::unlinkFromRuntime(FreeOp *fop)
{
// Remove any links from AsmJSModules that contain optimized FFI calls into
// this IonScript.
if (dependentAsmJSModules) {
for (size_t i = 0; i < dependentAsmJSModules->length(); i++) {
DependentAsmJSModuleExit exit = dependentAsmJSModules->begin()[i];
exit.module->detachIonCompilation(exit.exitIndex);
}
fop->delete_(dependentAsmJSModules);
dependentAsmJSModules = nullptr;
}
// The writes to the executable buffer below may clobber backedge jumps, so
// make sure that those backedges are unlinked from the runtime and not
// reclobbered with garbage if an interrupt is requested.

View File

@ -160,19 +160,6 @@ class IonCache;
struct PatchableBackedgeInfo;
struct CacheLocation;
// Describes a single AsmJSModule which jumps (via an FFI exit with the given
// index) directly into an IonScript.
struct DependentAsmJSModuleExit
{
const AsmJSModule *module;
size_t exitIndex;
DependentAsmJSModuleExit(const AsmJSModule *module, size_t exitIndex)
: module(module),
exitIndex(exitIndex)
{ }
};
// An IonScript attaches Ion-generated information to a JSScript.
struct IonScript
{
@ -298,10 +285,6 @@ struct IonScript
// a LOOPENTRY pc other than osrPc_.
uint32_t osrPcMismatchCounter_;
// If non-null, the list of AsmJSModules
// that contain an optimized call directly into this IonScript.
Vector<DependentAsmJSModuleExit> *dependentAsmJSModules;
IonBuilder *pendingBuilder_;
private:
@ -352,19 +335,6 @@ struct IonScript
PatchableBackedge *backedgeList() {
return (PatchableBackedge *) &bottomBuffer()[backedgeList_];
}
bool addDependentAsmJSModule(JSContext *cx, DependentAsmJSModuleExit exit);
void removeDependentAsmJSModule(DependentAsmJSModuleExit exit) {
if (!dependentAsmJSModules)
return;
for (size_t i = 0; i < dependentAsmJSModules->length(); i++) {
if (dependentAsmJSModules->begin()[i].module == exit.module &&
dependentAsmJSModules->begin()[i].exitIndex == exit.exitIndex)
{
dependentAsmJSModules->erase(dependentAsmJSModules->begin() + i);
break;
}
}
}
private:
void trace(JSTracer *trc);

View File

@ -1861,11 +1861,11 @@ MacroAssemblerARMCompat::callIon(Register callee)
}
void
MacroAssemblerARMCompat::callIonFromAsmJS(Register callee)
MacroAssemblerARMCompat::callJitFromAsmJS(Register callee)
{
ma_callIonNoPush(callee);
// The Ion ABI has the callee pop the return address off the stack.
// The JIT ABI has the callee pop the return address off the stack.
// The asm.js caller assumes that the call leaves sp unchanged, so bump
// the stack.
subPtr(Imm32(sizeof(void*)), sp);

View File

@ -1293,7 +1293,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
// Makes an Ion call using the only two methods that it is sane for
// independent code to make a call.
void callIon(Register callee);
void callIonFromAsmJS(Register callee);
void callJitFromAsmJS(Register callee);
void reserveStack(uint32_t amount);
void freeStack(uint32_t amount);

View File

@ -1549,11 +1549,11 @@ MacroAssemblerMIPSCompat::callIon(Register callee)
}
}
void
MacroAssemblerMIPSCompat::callIonFromAsmJS(Register callee)
MacroAssemblerMIPSCompat::callJitFromAsmJS(Register callee)
{
ma_callIonNoPush(callee);
// The Ion ABI has the callee pop the return address off the stack.
// The JIT ABI has the callee pop the return address off the stack.
// The asm.js caller assumes that the call leaves sp unchanged, so bump
// the stack.
subPtr(Imm32(sizeof(void*)), StackPointer);

View File

@ -1140,7 +1140,7 @@ public:
// Makes an Ion call using the only two methods that it is sane for
// indep code to make a call
void callIon(Register callee);
void callIonFromAsmJS(Register callee);
void callJitFromAsmJS(Register callee);
void reserveStack(uint32_t amount);
void freeStack(uint32_t amount);

View File

@ -191,7 +191,7 @@ class MacroAssemblerNone : public Assembler
void callWithExitFrame(JitCode *, Register) { MOZ_CRASH(); }
void callIon(Register callee) { MOZ_CRASH(); }
void callIonFromAsmJS(Register callee) { MOZ_CRASH(); }
void callJitFromAsmJS(Register callee) { MOZ_CRASH(); }
void nop() { MOZ_CRASH(); }
void breakpoint() { MOZ_CRASH(); }

View File

@ -1205,7 +1205,7 @@ class MacroAssemblerX86Shared : public Assembler
void callIon(Register callee) {
call(callee);
}
void callIonFromAsmJS(Register callee) {
void callJitFromAsmJS(Register callee) {
call(callee);
}
void call(AsmJSImmPtr target) {