mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
717b7365ad
commit
bec496fd14
@ -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')",
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
63
js/src/ion/AsmJSLink.h
Normal 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
|
97
js/src/ion/AsmJSModule.cpp
Normal file
97
js/src/ion/AsmJSModule.cpp
Normal 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));
|
||||
}
|
@ -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
|
||||
|
@ -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"
|
||||
|
52
js/src/ion/AsmJSSignalHandlers.h
Normal file
52
js/src/ion/AsmJSSignalHandlers.h
Normal 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
|
@ -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"
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#include "jsinfer.h"
|
||||
|
||||
#include "ion/AsmJS.h"
|
||||
#include "ion/Bailouts.h"
|
||||
#include "ion/BaselineFrame.h"
|
||||
#include "ion/BaselineIC.h"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -197,6 +197,7 @@ if CONFIG['ENABLE_ION']:
|
||||
'AliasAnalysis.cpp',
|
||||
'AsmJS.cpp',
|
||||
'AsmJSLink.cpp',
|
||||
'AsmJSModule.cpp',
|
||||
'AsmJSSignalHandlers.cpp',
|
||||
'BacktrackingAllocator.cpp',
|
||||
'Bailouts.cpp',
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user