зеркало из https://github.com/mozilla/gecko-dev.git
Bug 900669 - OdinMonkey: factor LinkAsmJS in preparation for later changes (r=bbouvier)
This commit is contained in:
Родитель
1d6b0cfa7a
Коммит
dc4d4e8360
|
@ -552,27 +552,9 @@ SendBlocksToPerf(JSContext *cx, AsmJSModule &module)
|
|||
}
|
||||
#endif
|
||||
|
||||
// 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 bool
|
||||
LinkAsmJS(JSContext *cx, unsigned argc, JS::Value *vp)
|
||||
SendModuleToAttachedProfiler(JSContext *cx, AsmJSModule &module)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
RootedFunction fun(cx, &args.callee().as<JSFunction>());
|
||||
RootedObject moduleObj(cx, &fun->getExtendedSlot(MODULE_FUN_SLOT).toObject());
|
||||
AsmJSModule &module = AsmJSModuleObjectToModule(moduleObj);
|
||||
|
||||
// If linking fails, recompile the function (including emitting bytecode)
|
||||
// as if it's normal JS code.
|
||||
if (!DynamicallyLinkModule(cx, args, module)) {
|
||||
RootedPropertyName name(cx, fun->name());
|
||||
return HandleDynamicLinkFailure(cx, args, module, name);
|
||||
}
|
||||
|
||||
#if defined(MOZ_VTUNE)
|
||||
if (IsVTuneProfilingActive() && !SendFunctionsToVTune(cx, module))
|
||||
return false;
|
||||
|
@ -585,37 +567,77 @@ LinkAsmJS(JSContext *cx, unsigned argc, JS::Value *vp)
|
|||
return false;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static JSObject *
|
||||
CreateExportObject(JSContext *cx, HandleObject moduleObj)
|
||||
{
|
||||
AsmJSModule &module = AsmJSModuleObjectToModule(moduleObj);
|
||||
|
||||
if (module.numExportedFunctions() == 1) {
|
||||
const AsmJSModule::ExportedFunction &func = module.exportedFunction(0);
|
||||
if (!func.maybeFieldName()) {
|
||||
RootedFunction fun(cx, NewExportedFunction(cx, func, moduleObj, 0));
|
||||
if (!fun)
|
||||
return false;
|
||||
|
||||
args.rval().set(ObjectValue(*fun));
|
||||
return true;
|
||||
}
|
||||
if (!func.maybeFieldName())
|
||||
return NewExportedFunction(cx, func, moduleObj, 0);
|
||||
}
|
||||
|
||||
gc::AllocKind allocKind = gc::GetGCObjectKind(module.numExportedFunctions());
|
||||
RootedObject obj(cx, NewBuiltinClassInstance(cx, &JSObject::class_, allocKind));
|
||||
if (!obj)
|
||||
return false;
|
||||
return NULL;
|
||||
|
||||
for (unsigned i = 0; i < module.numExportedFunctions(); i++) {
|
||||
const AsmJSModule::ExportedFunction &func = module.exportedFunction(i);
|
||||
|
||||
RootedFunction fun(cx, NewExportedFunction(cx, func, moduleObj, i));
|
||||
if (!fun)
|
||||
return false;
|
||||
return NULL;
|
||||
|
||||
JS_ASSERT(func.maybeFieldName() != NULL);
|
||||
RootedId id(cx, NameToId(func.maybeFieldName()));
|
||||
RootedValue val(cx, ObjectValue(*fun));
|
||||
if (!DefineNativeProperty(cx, obj, id, val, NULL, NULL, JSPROP_ENUMERATE, 0, 0))
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Implements the semantics of an asm.js module function that has been successfully validated.
|
||||
static bool
|
||||
LinkAsmJS(JSContext *cx, unsigned argc, JS::Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
// The LinkAsmJS builtin (created by NewAsmJSModuleFunction) is an extended
|
||||
// function and stores its module in an extended slot.
|
||||
RootedFunction fun(cx, &args.callee().as<JSFunction>());
|
||||
RootedObject moduleObj(cx, &fun->getExtendedSlot(MODULE_FUN_SLOT).toObject());
|
||||
AsmJSModule &module = AsmJSModuleObjectToModule(moduleObj);
|
||||
|
||||
// Link the module by performing the link-time validation checks in the
|
||||
// asm.js spec and then patching the generated module to associate it with
|
||||
// the given heap (ArrayBuffer) and a new global data segment (the closure
|
||||
// state shared by the inner asm.js functions).
|
||||
if (!DynamicallyLinkModule(cx, args, module)) {
|
||||
// Linking failed, so reparse the entire asm.js module from scratch to
|
||||
// get normal interpreted bytecode which we can simply Invoke. Very slow.
|
||||
RootedPropertyName name(cx, fun->name());
|
||||
return HandleDynamicLinkFailure(cx, args, module, name);
|
||||
}
|
||||
|
||||
// Notify profilers so that asm.js generated code shows up with JS function
|
||||
// names and lines in native (i.e., not SPS) profilers.
|
||||
if (!SendModuleToAttachedProfiler(cx, module))
|
||||
return false;
|
||||
|
||||
// Link-time validation succeeded, so wrap all the exported functions with
|
||||
// CallAsmJS builtins that trampoline into the generated code.
|
||||
JSObject *obj = CreateExportObject(cx, moduleObj);
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
args.rval().set(ObjectValue(*obj));
|
||||
return true;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче