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
|
static void
|
||||||
GenerateScopeChainGuards(MacroAssembler &masm, JSObject *scopeChain, JSObject *holder,
|
GenerateScopeChainGuards(MacroAssembler &masm, JSObject *scopeChain, JSObject *holder,
|
||||||
Register outputReg, Label *failures)
|
Register outputReg, Label *failures, bool skipLastGuard = false)
|
||||||
{
|
{
|
||||||
JSObject *tobj = scopeChain;
|
JSObject *tobj = scopeChain;
|
||||||
|
|
||||||
@ -3669,7 +3669,11 @@ GenerateScopeChainGuards(MacroAssembler &masm, JSObject *scopeChain, JSObject *h
|
|||||||
while (true) {
|
while (true) {
|
||||||
JS_ASSERT(IsCacheableNonGlobalScope(tobj) || tobj->is<GlobalObject>());
|
JS_ASSERT(IsCacheableNonGlobalScope(tobj) || tobj->is<GlobalObject>());
|
||||||
|
|
||||||
|
if (skipLastGuard && tobj == holder)
|
||||||
|
break;
|
||||||
|
|
||||||
GenerateScopeChainGuard(masm, tobj, outputReg, NULL, failures);
|
GenerateScopeChainGuard(masm, tobj, outputReg, NULL, failures);
|
||||||
|
|
||||||
if (tobj == holder)
|
if (tobj == holder)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3773,7 +3777,8 @@ BindNameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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)
|
HandleShape shape)
|
||||||
{
|
{
|
||||||
MacroAssembler masm(cx);
|
MacroAssembler masm(cx);
|
||||||
@ -3782,26 +3787,16 @@ NameIC::attachReadSlot(JSContext *cx, IonScript *ion, HandleObject scopeChain, H
|
|||||||
|
|
||||||
Register scratchReg = outputReg().valueReg().scratchReg();
|
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);
|
masm.mov(scopeChainReg(), scratchReg);
|
||||||
GenerateScopeChainGuards(masm, scopeChain, holder, scratchReg, &failures);
|
GenerateScopeChainGuards(masm, scopeChain, holderBase, scratchReg, &failures,
|
||||||
|
/* skipLastGuard = */true);
|
||||||
|
|
||||||
unsigned slot = shape->slot();
|
// GenerateScopeChain leaves the last scope chain in scrachReg, even though it
|
||||||
if (holder->isFixedSlot(slot)) {
|
// doesn't generate the extra guard.
|
||||||
Address addr(scratchReg, JSObject::getFixedSlotOffset(slot));
|
GenerateReadSlot(cx, ion, masm, attacher, holderBase, holder, shape, scratchReg,
|
||||||
masm.loadTypedOrValue(addr, outputReg());
|
outputReg(), failures.used() ? &failures : NULL);
|
||||||
} 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return linkAndAttachStub(cx, masm, attacher, ion, "generic");
|
return linkAndAttachStub(cx, masm, attacher, ion, "generic");
|
||||||
}
|
}
|
||||||
@ -3815,8 +3810,6 @@ IsCacheableNameReadSlot(JSContext *cx, HandleObject scopeChain, HandleObject obj
|
|||||||
return false;
|
return false;
|
||||||
if (!obj->isNative())
|
if (!obj->isNative())
|
||||||
return false;
|
return false;
|
||||||
if (obj != holder)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (obj->is<GlobalObject>()) {
|
if (obj->is<GlobalObject>()) {
|
||||||
// Support only simple property lookups.
|
// Support only simple property lookups.
|
||||||
@ -3824,6 +3817,7 @@ IsCacheableNameReadSlot(JSContext *cx, HandleObject scopeChain, HandleObject obj
|
|||||||
!IsCacheableNoProperty(obj, holder, shape, pc, output))
|
!IsCacheableNoProperty(obj, holder, shape, pc, output))
|
||||||
return false;
|
return false;
|
||||||
} else if (obj->is<CallObject>()) {
|
} else if (obj->is<CallObject>()) {
|
||||||
|
JS_ASSERT(obj == holder);
|
||||||
if (!shape->hasDefaultGetter())
|
if (!shape->hasDefaultGetter())
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@ -3904,7 +3898,7 @@ NameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain,
|
|||||||
|
|
||||||
if (cache.canAttachStub()) {
|
if (cache.canAttachStub()) {
|
||||||
if (IsCacheableNameReadSlot(cx, scopeChain, obj, holder, shape, pc, cache.outputReg())) {
|
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;
|
return false;
|
||||||
} else if (IsCacheableNameCallGetter(scopeChain, obj, holder, shape)) {
|
} else if (IsCacheableNameCallGetter(scopeChain, obj, holder, shape)) {
|
||||||
if (!cache.attachCallGetter(cx, ion, obj, holder, shape, returnAddr))
|
if (!cache.attachCallGetter(cx, ion, obj, holder, shape, returnAddr))
|
||||||
|
@ -932,8 +932,8 @@ class NameIC : public RepatchIonCache
|
|||||||
return typeOf_;
|
return typeOf_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool attachReadSlot(JSContext *cx, IonScript *ion, HandleObject scopeChain, HandleObject obj,
|
bool attachReadSlot(JSContext *cx, IonScript *ion, HandleObject scopeChain,
|
||||||
HandleShape shape);
|
HandleObject holderBase, HandleObject holder, HandleShape shape);
|
||||||
bool attachCallGetter(JSContext *cx, IonScript *ion, JSObject *obj, JSObject *holder,
|
bool attachCallGetter(JSContext *cx, IonScript *ion, JSObject *obj, JSObject *holder,
|
||||||
HandleShape shape, void *returnAddr);
|
HandleShape shape, void *returnAddr);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user