Bug 1227567 - Add Ion cache for module namepsace imports r=shu

This commit is contained in:
Jon Coppeard 2015-12-02 10:10:26 +00:00
parent 2ee97dbd00
commit 539c6c9f63
2 changed files with 93 additions and 0 deletions

View File

@ -2039,6 +2039,93 @@ GetPropertyIC::tryAttachArgumentsLength(JSContext* cx, HandleScript outerScript,
JS::TrackedOutcome::ICGetPropStub_ArgumentsLength);
}
static void
GenerateReadModuleNamespace(JSContext* cx, IonScript* ion, MacroAssembler& masm,
IonCache::StubAttacher& attacher, ModuleNamespaceObject* ns,
ModuleEnvironmentObject* env, Shape* shape, Register object,
TypedOrValueRegister output, Label* failures)
{
MOZ_ASSERT(ns);
MOZ_ASSERT(env);
// If we have multiple failure jumps but didn't get a label from the
// outside, make one ourselves.
Label failures_;
if (!failures)
failures = &failures_;
// Check for the specific namespace object.
attacher.branchNextStubOrLabel(masm, Assembler::NotEqual, object, ImmGCPtr(ns), failures);
// If we need a scratch register, use either an output register or the
// object register.
bool restoreScratch = false;
Register scratchReg = InvalidReg; // Quell compiler warning.
if (output.hasValue()) {
scratchReg = output.valueReg().scratchReg();
} else if (output.type() == MIRType_Double) {
masm.push(object);
scratchReg = object;
restoreScratch = true;
} else {
scratchReg = output.typedReg().gpr();
}
// Slot access.
Register envReg = scratchReg;
masm.movePtr(ImmGCPtr(env), envReg);
EmitLoadSlot(masm, &env->as<NativeObject>(), shape, envReg, output, scratchReg);
// Restore scratch on success.
if (restoreScratch)
masm.pop(object);
attacher.jumpRejoin(masm);
masm.bind(failures);
attacher.jumpNextStub(masm);
}
bool
GetPropertyIC::tryAttachModuleNamespace(JSContext* cx, HandleScript outerScript, IonScript* ion,
HandleObject obj, HandleId id, void* returnAddr,
bool* emitted)
{
MOZ_ASSERT(canAttachStub());
MOZ_ASSERT(!*emitted);
MOZ_ASSERT(outerScript->ionScript() == ion);
if (!obj->is<ModuleNamespaceObject>())
return true;
Rooted<ModuleNamespaceObject*> ns(cx, &obj->as<ModuleNamespaceObject>());
RootedModuleEnvironmentObject env(cx);
RootedShape shape(cx);
if (!ns->bindings().lookup(id, env.address(), shape.address()))
return true;
// Don't emit a stub until the target binding has been initialized.
if (env->getSlot(shape->slot()).isMagic(JS_UNINITIALIZED_LEXICAL))
return true;
*emitted = true;
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
StubAttacher attacher(*this);
Label failures;
emitIdGuard(masm, id, &failures);
Label* maybeFailures = failures.used() ? &failures : nullptr;
GenerateReadModuleNamespace(cx, ion, masm, attacher, ns, env,
shape, object(), output(), maybeFailures);
return linkAndAttachStub(cx, masm, attacher, ion, "module namespace",
JS::TrackedOutcome::ICGetPropStub_ReadSlot);
}
static bool
ValueToNameOrSymbolId(JSContext* cx, HandleValue idval, MutableHandleId id, bool* nameOrSymbol)
{
@ -2085,6 +2172,9 @@ GetPropertyIC::tryAttachStub(JSContext* cx, HandleScript outerScript, IonScript*
void* returnAddr = GetReturnAddressToIonCode(cx);
if (!*emitted && !tryAttachModuleNamespace(cx, outerScript, ion, obj, id, returnAddr, emitted))
return false;
if (!*emitted && !tryAttachProxy(cx, outerScript, ion, obj, id, returnAddr, emitted))
return false;

View File

@ -559,6 +559,9 @@ class GetPropertyIC : public IonCache
IonScript* ion, HandleObject obj,
HandleValue idval, bool* emitted);
bool tryAttachModuleNamespace(JSContext* cx, HandleScript outerScript, IonScript* ion,
HandleObject obj, HandleId id, void* returnAddr, bool* emitted);
static bool update(JSContext* cx, HandleScript outerScript, size_t cacheIndex,
HandleObject obj, HandleValue id, MutableHandleValue vp);
};