Bug 900669 - OdinMonkey: factor LinkAsmJS in preparation for later changes (r=bbouvier)

This commit is contained in:
Luke Wagner 2013-08-06 15:54:30 -05:00
parent 9ee7c5c08e
commit 37c51eaf53

View File

@ -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;
}