mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 17:25:36 +00:00
Bug 918593 - Part 1: Allow caching of global object prototypal name sets in NameIC. (r=djvj)
This commit is contained in:
parent
9dff5bab8a
commit
525b3811ac
@ -3660,7 +3660,7 @@ GenerateScopeChainGuard(MacroAssembler &masm, JSObject *scopeObj,
|
||||
|
||||
static void
|
||||
GenerateScopeChainGuards(MacroAssembler &masm, JSObject *scopeChain, JSObject *holder,
|
||||
Register outputReg, Label *failures)
|
||||
Register outputReg, Label *failures, bool skipLastGuard = false)
|
||||
{
|
||||
JSObject *tobj = scopeChain;
|
||||
|
||||
@ -3669,7 +3669,11 @@ GenerateScopeChainGuards(MacroAssembler &masm, JSObject *scopeChain, JSObject *h
|
||||
while (true) {
|
||||
JS_ASSERT(IsCacheableNonGlobalScope(tobj) || tobj->is<GlobalObject>());
|
||||
|
||||
if (skipLastGuard && tobj == holder)
|
||||
break;
|
||||
|
||||
GenerateScopeChainGuard(masm, tobj, outputReg, NULL, failures);
|
||||
|
||||
if (tobj == holder)
|
||||
break;
|
||||
|
||||
@ -3773,7 +3777,8 @@ BindNameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain)
|
||||
}
|
||||
|
||||
bool
|
||||
NameIC::attachReadSlot(JSContext *cx, IonScript *ion, HandleObject scopeChain, HandleObject holder,
|
||||
NameIC::attachReadSlot(JSContext *cx, IonScript *ion, HandleObject scopeChain,
|
||||
HandleObject holderBase, HandleObject holder,
|
||||
HandleShape shape)
|
||||
{
|
||||
MacroAssembler masm(cx);
|
||||
@ -3782,26 +3787,16 @@ NameIC::attachReadSlot(JSContext *cx, IonScript *ion, HandleObject scopeChain, H
|
||||
|
||||
Register scratchReg = outputReg().valueReg().scratchReg();
|
||||
|
||||
// Don't guard the base of the proto chain the name was found on. It will be guarded
|
||||
// by GenerateReadSlot().
|
||||
masm.mov(scopeChainReg(), scratchReg);
|
||||
GenerateScopeChainGuards(masm, scopeChain, holder, scratchReg, &failures);
|
||||
GenerateScopeChainGuards(masm, scopeChain, holderBase, scratchReg, &failures,
|
||||
/* skipLastGuard = */true);
|
||||
|
||||
unsigned slot = shape->slot();
|
||||
if (holder->isFixedSlot(slot)) {
|
||||
Address addr(scratchReg, JSObject::getFixedSlotOffset(slot));
|
||||
masm.loadTypedOrValue(addr, outputReg());
|
||||
} else {
|
||||
masm.loadPtr(Address(scratchReg, JSObject::offsetOfSlots()), scratchReg);
|
||||
|
||||
Address addr(scratchReg, holder->dynamicSlotIndex(slot) * sizeof(Value));
|
||||
masm.loadTypedOrValue(addr, outputReg());
|
||||
}
|
||||
|
||||
attacher.jumpRejoin(masm);
|
||||
|
||||
if (failures.used()) {
|
||||
masm.bind(&failures);
|
||||
attacher.jumpNextStub(masm);
|
||||
}
|
||||
// GenerateScopeChain leaves the last scope chain in scrachReg, even though it
|
||||
// doesn't generate the extra guard.
|
||||
GenerateReadSlot(cx, ion, masm, attacher, holderBase, holder, shape, scratchReg,
|
||||
outputReg(), failures.used() ? &failures : NULL);
|
||||
|
||||
return linkAndAttachStub(cx, masm, attacher, ion, "generic");
|
||||
}
|
||||
@ -3815,8 +3810,6 @@ IsCacheableNameReadSlot(JSContext *cx, HandleObject scopeChain, HandleObject obj
|
||||
return false;
|
||||
if (!obj->isNative())
|
||||
return false;
|
||||
if (obj != holder)
|
||||
return false;
|
||||
|
||||
if (obj->is<GlobalObject>()) {
|
||||
// Support only simple property lookups.
|
||||
@ -3824,6 +3817,7 @@ IsCacheableNameReadSlot(JSContext *cx, HandleObject scopeChain, HandleObject obj
|
||||
!IsCacheableNoProperty(obj, holder, shape, pc, output))
|
||||
return false;
|
||||
} else if (obj->is<CallObject>()) {
|
||||
JS_ASSERT(obj == holder);
|
||||
if (!shape->hasDefaultGetter())
|
||||
return false;
|
||||
} else {
|
||||
@ -3904,7 +3898,7 @@ NameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain,
|
||||
|
||||
if (cache.canAttachStub()) {
|
||||
if (IsCacheableNameReadSlot(cx, scopeChain, obj, holder, shape, pc, cache.outputReg())) {
|
||||
if (!cache.attachReadSlot(cx, ion, scopeChain, obj, shape))
|
||||
if (!cache.attachReadSlot(cx, ion, scopeChain, obj, holder, shape))
|
||||
return false;
|
||||
} else if (IsCacheableNameCallGetter(scopeChain, obj, holder, shape)) {
|
||||
if (!cache.attachCallGetter(cx, ion, obj, holder, shape, returnAddr))
|
||||
|
@ -932,8 +932,8 @@ class NameIC : public RepatchIonCache
|
||||
return typeOf_;
|
||||
}
|
||||
|
||||
bool attachReadSlot(JSContext *cx, IonScript *ion, HandleObject scopeChain, HandleObject obj,
|
||||
HandleShape shape);
|
||||
bool attachReadSlot(JSContext *cx, IonScript *ion, HandleObject scopeChain,
|
||||
HandleObject holderBase, HandleObject holder, HandleShape shape);
|
||||
bool attachCallGetter(JSContext *cx, IonScript *ion, JSObject *obj, JSObject *holder,
|
||||
HandleShape shape, void *returnAddr);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user