Bug 899415 - OdinMonkey: split out declarations/definitions better across AsmJS .h/.cpp files (r=bbouvier)

--HG--
extra : rebase_source : 4d9a847bf5b70fe708d78f00335077a82c37fbcf
This commit is contained in:
Luke Wagner 2013-07-29 21:15:05 -05:00
parent 717b7365ad
commit bec496fd14
25 changed files with 355 additions and 327 deletions

View File

@ -15,6 +15,7 @@
#include "jswrapper.h"
#include "ion/AsmJS.h"
#include "ion/AsmJSLink.h"
#include "vm/ForkJoin.h"
#include "vm/Interpreter.h"
@ -984,32 +985,6 @@ GetObjectMetadata(JSContext *cx, unsigned argc, jsval *vp)
return true;
}
#ifndef JS_ION
JSBool
js::IsAsmJSCompilationAvailable(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
args.rval().set(BooleanValue(false));
return true;
}
JSBool
js::IsAsmJSModule(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
args.rval().set(BooleanValue(false));
return true;
}
JSBool
js::IsAsmJSFunction(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
args.rval().set(BooleanValue(false));
return true;
}
#endif
static JSFunctionSpecWithHelp TestingFunctions[] = {
JS_FN_HELP("gc", ::GC, 0, 0,
"gc([obj] | 'compartment')",

View File

@ -12,7 +12,7 @@
#include "frontend/FoldConstants.h"
#include "frontend/NameFunctions.h"
#include "frontend/Parser.h"
#include "ion/AsmJS.h"
#include "ion/AsmJSLink.h"
#include "vm/GlobalObject.h"
#include "jsobjinlines.h"

View File

@ -28,7 +28,7 @@
#include "frontend/Parser.h"
#include "frontend/TokenStream.h"
#include "ion/AsmJS.h"
#include "ion/AsmJSLink.h"
#include "vm/Debugger.h"
#include "jsatominlines.h"

View File

@ -33,6 +33,7 @@
#include "frontend/FoldConstants.h"
#include "frontend/ParseMaps.h"
#include "frontend/TokenStream.h"
#include "ion/AsmJS.h"
#include "vm/NumericConversions.h"
#include "vm/RegExpStatics.h"
#include "vm/Shape.h"

View File

@ -14,7 +14,6 @@
#include "jsmath.h"
#include "jsworkers.h"
#include "jswrapper.h"
#include "prmjtime.h"
#include "frontend/Parser.h"
@ -2531,88 +2530,6 @@ class FunctionCompiler
}
};
/*****************************************************************************/
// An AsmJSModule contains the persistent results of asm.js module compilation,
// viz., the jit code and dynamic link information.
//
// An AsmJSModule object is created at the end of module compilation and
// subsequently owned by an AsmJSModuleClass JSObject.
static void AsmJSModuleObject_finalize(FreeOp *fop, JSObject *obj);
static void AsmJSModuleObject_trace(JSTracer *trc, JSObject *obj);
static const unsigned ASM_CODE_RESERVED_SLOT = 0;
static const unsigned ASM_CODE_NUM_RESERVED_SLOTS = 1;
static Class AsmJSModuleClass = {
"AsmJSModuleObject",
JSCLASS_IS_ANONYMOUS | JSCLASS_IMPLEMENTS_BARRIERS |
JSCLASS_HAS_RESERVED_SLOTS(ASM_CODE_NUM_RESERVED_SLOTS),
JS_PropertyStub, /* addProperty */
JS_DeletePropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */
JS_StrictPropertyStub, /* setProperty */
JS_EnumerateStub,
JS_ResolveStub,
NULL, /* convert */
AsmJSModuleObject_finalize,
NULL, /* checkAccess */
NULL, /* call */
NULL, /* hasInstance */
NULL, /* construct */
AsmJSModuleObject_trace
};
AsmJSModule &
js::AsmJSModuleObjectToModule(JSObject *obj)
{
JS_ASSERT(obj->getClass() == &AsmJSModuleClass);
return *(AsmJSModule *)obj->getReservedSlot(ASM_CODE_RESERVED_SLOT).toPrivate();
}
bool
js::IsAsmJSModuleObject(JSObject *obj)
{
return obj->getClass() == &AsmJSModuleClass;
}
static const unsigned ASM_MODULE_FUNCTION_MODULE_OBJECT_SLOT = 0;
JSObject &
js::AsmJSModuleObject(JSFunction *moduleFun)
{
return moduleFun->getExtendedSlot(ASM_MODULE_FUNCTION_MODULE_OBJECT_SLOT).toObject();
}
void
js::SetAsmJSModuleObject(JSFunction *moduleFun, JSObject *moduleObj)
{
moduleFun->setExtendedSlot(ASM_MODULE_FUNCTION_MODULE_OBJECT_SLOT, OBJECT_TO_JSVAL(moduleObj));
}
static void
AsmJSModuleObject_finalize(FreeOp *fop, JSObject *obj)
{
fop->delete_(&AsmJSModuleObjectToModule(obj));
}
static void
AsmJSModuleObject_trace(JSTracer *trc, JSObject *obj)
{
AsmJSModuleObjectToModule(obj).trace(trc);
}
static JSObject *
NewAsmJSModuleObject(JSContext *cx, ScopedJSDeletePtr<AsmJSModule> *module)
{
JSObject *obj = NewObjectWithGivenProto(cx, &AsmJSModuleClass, NULL, NULL);
if (!obj)
return NULL;
obj->setReservedSlot(ASM_CODE_RESERVED_SLOT, PrivateValue(module->forget()));
return obj;
}
/*****************************************************************************/
// asm.js type-checking and code-generation algorithm
@ -6391,24 +6308,13 @@ js::CompileAsmJS(JSContext *cx, AsmJSParser &parser, ParseNode *stmtList, bool *
if (!moduleObj)
return false;
ParseNode *fn = parser.pc->maybeFunction;
RootedFunction origFun(cx, fn->pn_funbox->function());
RootedPropertyName name(cx, origFun->name());
RootedFunction moduleFun(cx, NewFunction(cx, NullPtr(), LinkAsmJS, origFun->nargs,
JSFunction::NATIVE_FUN, NullPtr(), name,
JSFunction::ExtendedFinalizeKind, TenuredObject));
FunctionBox *funbox = parser.pc->maybeFunction->pn_funbox;
RootedFunction moduleFun(cx, NewAsmJSModuleFunction(cx, funbox->function(), moduleObj));
if (!moduleFun)
return false;
SetAsmJSModuleObject(moduleFun, moduleObj);
// Replace the old interpreted function (which will now become garbage)
// with the new LinkAsmJS native function. This allows us to avoid creating
// bytecode for the entire asm.js module (which can be quite large). If
// link-time validation fails, LinkAsmJS will re-parse the whole module.
JS_ASSERT(fn->pn_funbox->function()->isInterpreted());
fn->pn_funbox->object = moduleFun;
JS_ASSERT(IsAsmJSModuleNative(fn->pn_funbox->function()->native()));
JS_ASSERT(funbox->function()->isInterpreted());
funbox->object = moduleFun;
*validated = true;
return Warn(cx, JSMSG_USE_ASM_TYPE_OK, compilationTimeReport);
@ -6426,58 +6332,3 @@ js::IsAsmJSCompilationAvailable(JSContext *cx, unsigned argc, Value *vp)
args.rval().set(BooleanValue(available));
return true;
}
static bool
IsMaybeWrappedNativeFunction(const Value &v, Native native)
{
if (!v.isObject())
return false;
JSObject *obj = CheckedUnwrap(&v.toObject());
if (!obj)
return false;
return obj->is<JSFunction>() && obj->as<JSFunction>().maybeNative() == native;
}
JSBool
js::IsAsmJSModule(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
bool rval = args.hasDefined(0) && IsMaybeWrappedNativeFunction(args[0], LinkAsmJS);
args.rval().set(BooleanValue(rval));
return true;
}
JSBool
js::IsAsmJSFunction(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
bool rval = args.hasDefined(0) && IsMaybeWrappedNativeFunction(args[0], CallAsmJS);
args.rval().set(BooleanValue(rval));
return true;
}
AsmJSModule::~AsmJSModule()
{
if (code_) {
for (unsigned i = 0; i < numExits(); i++) {
AsmJSModule::ExitDatum &exitDatum = exitIndexToGlobalDatum(i);
if (!exitDatum.fun)
continue;
if (!exitDatum.fun->hasScript())
continue;
JSScript *script = exitDatum.fun->nonLazyScript();
if (!script->hasIonScript())
continue;
DependentAsmJSModuleExit exit(this, i);
script->ionScript()->removeDependentAsmJSModule(exit);
}
}
for (size_t i = 0; i < numFunctionCounts(); i++)
js_delete(functionCounts(i));
}

View File

@ -7,34 +7,18 @@
#ifndef ion_AsmJS_h
#define ion_AsmJS_h
#ifdef XP_MACOSX
# include <mach/mach.h>
# include <pthread.h>
#endif
#include "jstypes.h"
#include "ds/LifoAlloc.h"
#include "js/CallArgs.h"
struct JSContext;
struct JSRuntime;
#include "jsapi.h"
namespace js {
class ScriptSource;
class SPSProfiler;
class AsmJSModule;
class SPSProfiler;
namespace frontend {
template <typename ParseHandler> struct Parser;
template <typename ParseHandler> struct ParseContext;
class FullParseHandler;
struct ParseNode;
}
namespace ion {
class MIRGenerator;
class LIRGraph;
}
typedef frontend::Parser<frontend::FullParseHandler> AsmJSParser;
typedef frontend::ParseContext<frontend::FullParseHandler> AsmJSParseContext;
@ -47,25 +31,6 @@ typedef frontend::ParseContext<frontend::FullParseHandler> AsmJSParseContext;
extern bool
CompileAsmJS(JSContext *cx, AsmJSParser &parser, frontend::ParseNode *stmtList, bool *validated);
// Implements the semantics of an asm.js module function that has been successfully validated.
// A successfully validated asm.js module does not have bytecode emitted, but rather a list of
// dynamic constraints that must be satisfied by the arguments passed by the caller. If these
// constraints are satisfied, then LinkAsmJS can return CallAsmJS native functions that trampoline
// into compiled code. If any of the constraints fails, LinkAsmJS reparses the entire asm.js module
// from source so that it can be run as plain bytecode.
extern JSBool
LinkAsmJS(JSContext *cx, unsigned argc, JS::Value *vp);
// The JSNative for the functions nested in an asm.js module. Calling this
// native will trampoline into generated code.
extern JSBool
CallAsmJS(JSContext *cx, unsigned argc, JS::Value *vp);
// Force any currently-executing asm.js code to call
// js_HandleExecutionInterrupt.
void
TriggerOperationCallbackForAsmJSCode(JSRuntime *rt);
// The JSRuntime maintains a stack of AsmJSModule activations. An "activation"
// of module A is an initial call from outside A into a function inside A,
// followed by a sequence of calls inside A, and terminated by a call that
@ -116,89 +81,25 @@ static const size_t AsmJSAllocationGranularity = 4096;
static const size_t AsmJSBufferProtectedSize = 4 * 1024ULL * 1024ULL * 1024ULL;
#endif
#ifdef XP_MACOSX
class AsmJSMachExceptionHandler
{
bool installed_;
pthread_t thread_;
mach_port_t port_;
void release();
public:
AsmJSMachExceptionHandler();
~AsmJSMachExceptionHandler() { release(); }
mach_port_t port() const { return port_; }
bool installed() const { return installed_; }
bool install(JSRuntime *rt);
void clearCurrentThread();
void setCurrentThread();
};
#endif
struct DependentAsmJSModuleExit
{
const AsmJSModule *module;
size_t exitIndex;
DependentAsmJSModuleExit(const AsmJSModule *module, size_t exitIndex)
: module(module),
exitIndex(exitIndex)
{ }
};
// Struct type for passing parallel compilation data between the main thread
// and compilation workers.
struct AsmJSParallelTask
{
LifoAlloc lifo; // Provider of all heap memory used for compilation.
void *func; // Really, a ModuleCompiler::Func*
ion::MIRGenerator *mir; // Passed from main thread to worker.
ion::LIRGraph *lir; // Passed from worker to main thread.
unsigned compileTime;
AsmJSParallelTask(size_t defaultChunkSize)
: lifo(defaultChunkSize), func(NULL), mir(NULL), lir(NULL), compileTime(0)
{ }
void init(void *func, ion::MIRGenerator *mir) {
this->func = func;
this->mir = mir;
this->lir = NULL;
}
};
// Returns true if the given native is the one that is used to implement asm.js
// module functions.
#ifdef JS_ION
extern bool
IsAsmJSModuleNative(JSNative native);
#else
inline bool
IsAsmJSModuleNative(JSNative native)
{
return false;
}
#endif
// Exposed for shell testing:
// Return whether asm.js optimization is inhibitted by the platform or
// dynamically disabled:
extern JSBool
IsAsmJSCompilationAvailable(JSContext *cx, unsigned argc, JS::Value *vp);
// Return whether the given value is a function containing "use asm" that has
// been validated according to the asm.js spec.
extern JSBool
IsAsmJSModule(JSContext *cx, unsigned argc, JS::Value *vp);
#else // JS_ION
// Return whether the given value is a nested function in an asm.js module that
// has been both compile- and link-time validated.
extern JSBool
IsAsmJSFunction(JSContext *cx, unsigned argc, JS::Value *vp);
inline JSBool
IsAsmJSCompilationAvailable(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
args.rval().set(BooleanValue(false));
return true;
}
#endif // JS_ION
} // namespace js
#endif /* ion_AsmJS_h */
#endif // ion_AsmJS_h

View File

@ -4,15 +4,16 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ion/AsmJSLink.h"
#ifdef MOZ_VTUNE
# include "jitprofiling.h"
#endif
#include "jscntxt.h"
#include "jsmath.h"
#include "jswrapper.h"
#include "frontend/BytecodeCompiler.h"
#include "ion/AsmJS.h"
#include "ion/AsmJSModule.h"
#include "ion/Ion.h"
#ifdef JS_ION_PERF
@ -23,7 +24,10 @@
using namespace js;
using namespace js::ion;
using namespace mozilla;
using mozilla::IsNaN;
static const unsigned MODULE_FUN_SLOT = 0;
static bool
LinkFail(JSContext *cx, const char *str)
@ -309,8 +313,10 @@ AsmJSActivation::~AsmJSActivation()
static const unsigned ASM_MODULE_SLOT = 0;
static const unsigned ASM_EXPORT_INDEX_SLOT = 1;
extern JSBool
js::CallAsmJS(JSContext *cx, unsigned argc, Value *vp)
// The JSNative for the functions nested in an asm.js module. Calling this
// native will trampoline into generated code.
static JSBool
CallAsmJS(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs callArgs = CallArgsFromVp(argc, vp);
RootedFunction callee(cx, &callArgs.callee().as<JSFunction>());
@ -563,12 +569,18 @@ SendBlocksToPerf(JSContext *cx, AsmJSModule &module)
}
#endif
JSBool
js::LinkAsmJS(JSContext *cx, unsigned argc, JS::Value *vp)
// Implements the semantics of an asm.js module function that has been successfully validated.
// A successfully validated asm.js module does not have bytecode emitted, but rather a list of
// dynamic constraints that must be satisfied by the arguments passed by the caller. If these
// constraints are satisfied, then LinkAsmJS can return CallAsmJS native functions that trampoline
// into compiled code. If any of the constraints fails, LinkAsmJS reparses the entire asm.js module
// from source so that it can be run as plain bytecode.
static JSBool
LinkAsmJS(JSContext *cx, unsigned argc, JS::Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedFunction fun(cx, &args.callee().as<JSFunction>());
RootedObject moduleObj(cx, &AsmJSModuleObject(fun));
RootedObject moduleObj(cx, &fun->getExtendedSlot(MODULE_FUN_SLOT).toObject());
AsmJSModule &module = AsmJSModuleObjectToModule(moduleObj);
// If linking fails, recompile the function (including emitting bytecode)
@ -625,8 +637,53 @@ js::LinkAsmJS(JSContext *cx, unsigned argc, JS::Value *vp)
return true;
}
JSFunction *
js::NewAsmJSModuleFunction(JSContext *cx, JSFunction *origFun, HandleObject moduleObj)
{
RootedPropertyName name(cx, origFun->name());
JSFunction *moduleFun = NewFunction(cx, NullPtr(), LinkAsmJS, origFun->nargs,
JSFunction::NATIVE_FUN, NullPtr(), name,
JSFunction::ExtendedFinalizeKind, TenuredObject);
if (!moduleFun)
return NULL;
moduleFun->setExtendedSlot(MODULE_FUN_SLOT, ObjectValue(*moduleObj));
return moduleFun;
}
bool
js::IsAsmJSModuleNative(js::Native native)
{
return native == LinkAsmJS;
}
static bool
IsMaybeWrappedNativeFunction(const Value &v, Native native)
{
if (!v.isObject())
return false;
JSObject *obj = CheckedUnwrap(&v.toObject());
if (!obj)
return false;
return obj->is<JSFunction>() && obj->as<JSFunction>().maybeNative() == native;
}
JSBool
js::IsAsmJSModule(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
bool rval = args.hasDefined(0) && IsMaybeWrappedNativeFunction(args[0], LinkAsmJS);
args.rval().set(BooleanValue(rval));
return true;
}
JSBool
js::IsAsmJSFunction(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
bool rval = args.hasDefined(0) && IsMaybeWrappedNativeFunction(args[0], CallAsmJS);
args.rval().set(BooleanValue(rval));
return true;
}

63
js/src/ion/AsmJSLink.h Normal file
View File

@ -0,0 +1,63 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_AsmJSLink_h
#define ion_AsmJSLink_h
#include "jsapi.h"
namespace js {
#ifdef JS_ION
// Create a new JSFunction to replace originalFun as the representation of the
// function defining the succesfully-validated module 'moduleObj'.
extern JSFunction *
NewAsmJSModuleFunction(JSContext *cx, JSFunction *originalFun, HandleObject moduleObj);
// Return whether this is the js::Native returned by NewAsmJSModuleFunction.
extern bool
IsAsmJSModuleNative(JSNative native);
// Return whether the given value is a function containing "use asm" that has
// been validated according to the asm.js spec.
extern JSBool
IsAsmJSModule(JSContext *cx, unsigned argc, JS::Value *vp);
// Return whether the given value is a nested function in an asm.js module that
// has been both compile- and link-time validated.
extern JSBool
IsAsmJSFunction(JSContext *cx, unsigned argc, JS::Value *vp);
#else // JS_ION
inline bool
IsAsmJSModuleNative(JSNative native)
{
return false;
}
inline JSBool
IsAsmJSFunction(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
args.rval().set(BooleanValue(false));
return true;
}
inline JSBool
IsAsmJSModule(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
args.rval().set(BooleanValue(false));
return true;
}
#endif // JS_ION
} // namespace js
#endif // ion_AsmJS_h

View File

@ -0,0 +1,97 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ion/AsmJSModule.h"
#include "ion/IonCode.h"
#include "jsobjinlines.h"
using namespace js;
static void AsmJSModuleObject_finalize(FreeOp *fop, JSObject *obj);
static void AsmJSModuleObject_trace(JSTracer *trc, JSObject *obj);
static const unsigned ASM_CODE_RESERVED_SLOT = 0;
static const unsigned ASM_CODE_NUM_RESERVED_SLOTS = 1;
static Class AsmJSModuleClass = {
"AsmJSModuleObject",
JSCLASS_IS_ANONYMOUS | JSCLASS_IMPLEMENTS_BARRIERS |
JSCLASS_HAS_RESERVED_SLOTS(ASM_CODE_NUM_RESERVED_SLOTS),
JS_PropertyStub, /* addProperty */
JS_DeletePropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */
JS_StrictPropertyStub, /* setProperty */
JS_EnumerateStub,
JS_ResolveStub,
NULL, /* convert */
AsmJSModuleObject_finalize,
NULL, /* checkAccess */
NULL, /* call */
NULL, /* hasInstance */
NULL, /* construct */
AsmJSModuleObject_trace
};
bool
js::IsAsmJSModuleObject(JSObject *obj)
{
return obj->getClass() == &AsmJSModuleClass;
}
AsmJSModule &
js::AsmJSModuleObjectToModule(JSObject *obj)
{
JS_ASSERT(IsAsmJSModuleObject(obj));
return *(AsmJSModule *)obj->getReservedSlot(ASM_CODE_RESERVED_SLOT).toPrivate();
}
static void
AsmJSModuleObject_finalize(FreeOp *fop, JSObject *obj)
{
fop->delete_(&AsmJSModuleObjectToModule(obj));
}
static void
AsmJSModuleObject_trace(JSTracer *trc, JSObject *obj)
{
AsmJSModuleObjectToModule(obj).trace(trc);
}
JSObject *
js::NewAsmJSModuleObject(JSContext *cx, ScopedJSDeletePtr<AsmJSModule> *module)
{
JSObject *obj = NewObjectWithGivenProto(cx, &AsmJSModuleClass, NULL, NULL);
if (!obj)
return NULL;
obj->setReservedSlot(ASM_CODE_RESERVED_SLOT, PrivateValue(module->forget()));
return obj;
}
AsmJSModule::~AsmJSModule()
{
if (code_) {
for (unsigned i = 0; i < numExits(); i++) {
AsmJSModule::ExitDatum &exitDatum = exitIndexToGlobalDatum(i);
if (!exitDatum.fun)
continue;
if (!exitDatum.fun->hasScript())
continue;
JSScript *script = exitDatum.fun->nonLazyScript();
if (!script->hasIonScript())
continue;
ion::DependentAsmJSModuleExit exit(this, i);
script->ionScript()->removeDependentAsmJSModule(exit);
}
}
for (size_t i = 0; i < numFunctionCounts(); i++)
js_delete(functionCounts(i));
}

View File

@ -14,6 +14,7 @@
#include "jsscript.h"
#include "gc/Marking.h"
#include "ion/AsmJS.h"
#include "ion/IonMacroAssembler.h"
#if defined(JS_ION_PERF)
# include "ion/PerfSpewer.h"
@ -765,21 +766,20 @@ class AsmJSModule
}
};
// On success, return an AsmJSModuleClass JSObject that has taken ownership
// (and release()ed) the given module.
extern JSObject *
NewAsmJSModuleObject(JSContext *cx, ScopedJSDeletePtr<AsmJSModule> *module);
// Return whether the given object was created by NewAsmJSModuleObject.
extern bool
IsAsmJSModuleObject(JSObject *obj);
// The AsmJSModule C++ object is held by a JSObject that takes care of calling
// 'trace' and the destructor on finalization.
extern AsmJSModule &
AsmJSModuleObjectToModule(JSObject *obj);
extern bool
IsAsmJSModuleObject(JSObject *obj);
extern JSObject &
AsmJSModuleObject(JSFunction *moduleFun);
extern void
SetAsmJSModuleObject(JSFunction *moduleFun, JSObject *moduleObj);
} // namespace js
#endif // JS_ION

View File

@ -4,10 +4,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ion/AsmJSSignalHandlers.h"
#include "jscntxt.h"
#include "assembler/assembler/MacroAssembler.h"
#include "ion/AsmJS.h"
#include "ion/AsmJSModule.h"
#include "vm/ObjectImpl-inl.h"

View File

@ -0,0 +1,52 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_AsmJSSignalHandlers_h
#define ion_AsmJSSignalHandlers_h
struct JSRuntime;
#ifdef XP_MACOSX
# include <mach/mach.h>
# include <pthread.h>
#endif
namespace js {
// Force any currently-executing asm.js code to call
// js_HandleExecutionInterrupt.
extern void
TriggerOperationCallbackForAsmJSCode(JSRuntime *rt);
// On OSX we are forced to use the lower-level Mach exception mechanism instead
// of Unix signals. Mach exceptions are not handled on the victim's stack but
// rather require an extra thread. For simplicity, we create one such thread
// per JSRuntime (upon the first use of asm.js in the JSRuntime). This thread
// and related resources are owned by AsmJSMachExceptionHandler which is owned
// by JSRuntime.
#ifdef XP_MACOSX
class AsmJSMachExceptionHandler
{
bool installed_;
pthread_t thread_;
mach_port_t port_;
void release();
public:
AsmJSMachExceptionHandler();
~AsmJSMachExceptionHandler() { release(); }
mach_port_t port() const { return port_; }
bool installed() const { return installed_; }
bool install(JSRuntime *rt);
void clearCurrentThread();
void setCurrentThread();
};
#endif
} // namespace js
#endif // ion_AsmJSSignalHandlers_h

View File

@ -15,9 +15,8 @@
#endif
#include "gc/Marking.h"
#include "ion/AliasAnalysis.h"
#include "ion/AsmJS.h"
#include "ion/AsmJSModule.h"
#include "ion/AliasAnalysis.h"
#include "ion/BacktrackingAllocator.h"
#include "ion/BaselineCompiler.h"
#include "ion/BaselineInspector.h"

View File

@ -13,7 +13,6 @@
#include "jsinfer.h"
#include "gc/Heap.h"
#include "ion/AsmJS.h"
#include "ion/IonTypes.h"
namespace JSC {
@ -23,6 +22,9 @@ namespace JSC {
class JSScript;
namespace js {
class AsmJSModule;
namespace ion {
// The maximum size of any buffer associated with an assembler or code object.
@ -145,6 +147,19 @@ class SafepointIndex;
class OsiIndex;
class IonCache;
// 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
{

View File

@ -8,7 +8,6 @@
#include "jsinfer.h"
#include "ion/AsmJS.h"
#include "ion/Bailouts.h"
#include "ion/BaselineFrame.h"
#include "ion/BaselineIC.h"

View File

@ -18,7 +18,6 @@
#elif defined(JS_CPU_ARM)
# include "ion/arm/MacroAssembler-arm.h"
#endif
#include "ion/AsmJS.h"
#include "ion/IonCompartment.h"
#include "ion/IonInstrumentation.h"
#include "ion/ParallelFunctions.h"

View File

@ -61,7 +61,7 @@
#include "frontend/Parser.h" // for JS_BufferIsCompileableUnit
#include "gc/Marking.h"
#include "gc/Memory.h"
#include "ion/AsmJS.h"
#include "ion/AsmJSLink.h"
#include "js/CharacterEncoding.h"
#if ENABLE_INTL_API
#include "unicode/uclean.h"

View File

@ -25,10 +25,7 @@
#include "jswatchpoint.h"
#include "frontend/SourceNotes.h"
#include "ion/AsmJS.h"
#ifdef JS_ION
#include "ion/AsmJSModule.h"
#endif
#include "vm/Debugger.h"
#include "vm/Interpreter.h"
#include "vm/Shape.h"

View File

@ -14,7 +14,7 @@
#include "jsfun.h"
#include "jsopcode.h"
#include "ion/AsmJS.h"
#include "ion/AsmJSLink.h"
#include "vm/GlobalObject.h"
#include "vm/RegExpObject.h"
#include "vm/Shape.h"

View File

@ -13,7 +13,6 @@
#include "frontend/BytecodeCompiler.h"
#ifdef JS_WORKER_THREADS
# include "ion/AsmJS.h"
# include "ion/ExecutionModeInlines.h"
# include "ion/IonBuilder.h"
#endif

View File

@ -23,8 +23,9 @@
namespace js {
struct WorkerThread;
struct AsmJSParallelTask;
struct ParseTask;
namespace ion {
class IonBuilder;
}
@ -32,10 +33,6 @@ namespace ion {
#if defined(JS_THREADSAFE) && defined(JS_ION)
# define JS_WORKER_THREADS
struct WorkerThread;
struct AsmJSParallelTask;
struct ParseTask;
/* Per-runtime state for off thread work items. */
class WorkerThreadState
{
@ -309,6 +306,27 @@ PauseOffThreadParsing();
void
ResumeOffThreadParsing();
#ifdef JS_ION
struct AsmJSParallelTask
{
LifoAlloc lifo; // Provider of all heap memory used for compilation.
void *func; // Really, a ModuleCompiler::Func*
ion::MIRGenerator *mir; // Passed from main thread to worker.
ion::LIRGraph *lir; // Passed from worker to main thread.
unsigned compileTime;
AsmJSParallelTask(size_t defaultChunkSize)
: lifo(defaultChunkSize), func(NULL), mir(NULL), lir(NULL), compileTime(0)
{ }
void init(void *func, ion::MIRGenerator *mir) {
this->func = func;
this->mir = mir;
this->lir = NULL;
}
};
#endif
struct ParseTask
{
JSRuntime *runtime;

View File

@ -197,6 +197,7 @@ if CONFIG['ENABLE_ION']:
'AliasAnalysis.cpp',
'AsmJS.cpp',
'AsmJSLink.cpp',
'AsmJSModule.cpp',
'AsmJSSignalHandlers.cpp',
'BacktrackingAllocator.cpp',
'Bailouts.cpp',

View File

@ -25,6 +25,7 @@
#include "jswrapper.h"
#include "js/MemoryMetrics.h"
#include "ion/AsmJSSignalHandlers.h"
#include "ion/IonCompartment.h"
#include "ion/PcScriptCache.h"
#include "yarr/BumpPointerAllocator.h"

View File

@ -30,6 +30,7 @@
#include "gc/Nursery.h"
#include "gc/Statistics.h"
#include "gc/StoreBuffer.h"
#include "ion/AsmJSSignalHandlers.h"
#include "js/HashTable.h"
#include "js/Vector.h"
#include "vm/DateTime.h"

View File

@ -31,6 +31,7 @@
#include "gc/Barrier.h"
#include "gc/Marking.h"
#include "ion/AsmJS.h"
#include "vm/GlobalObject.h"
#include "vm/Interpreter.h"
#include "vm/NumericConversions.h"