Bug 875452 - Part 5: Add generic proxy stub to GetPropertyIC. (r=djvj)

This commit is contained in:
Eric Faust 2013-08-10 22:20:36 -07:00
parent 79574f6890
commit 161ef5c1e8
4 changed files with 97 additions and 2 deletions

View File

@ -0,0 +1,26 @@
// |jit-test| ion-eager
function causeBreak(t, n, r) {
gcPreserveCode();
gc();
}
function centralizeGetProp(p)
{
p.someProp;
}
var handler = {};
function test() {
var p = new Proxy({}, handler);
var count = 5;
for (var i = 0; i < count; i++) {
centralizeGetProp(p);
}
handler.get = causeBreak;
centralizeGetProp(p);
}
test();

View File

@ -1452,6 +1452,7 @@ GetPropertyIC::tryAttachProxy(JSContext *cx, IonScript *ion, HandleObject obj,
if (!output().hasValue())
return true;
// Skim off DOM proxies.
if (IsCacheableDOMProxy(obj)) {
RootedId id(cx, NameToId(name));
DOMProxyShadowsResult shadows = GetDOMProxyShadowsCheck()(cx, obj, id);
@ -1464,7 +1465,64 @@ GetPropertyIC::tryAttachProxy(JSContext *cx, IonScript *ion, HandleObject obj,
returnAddr, emitted);
}
return true;
return tryAttachGenericProxy(cx, ion, obj, name, returnAddr, emitted);
}
bool
GetPropertyIC::tryAttachGenericProxy(JSContext *cx, IonScript *ion, HandleObject obj,
HandlePropertyName name, void *returnAddr,
bool *emitted)
{
JS_ASSERT(canAttachStub());
JS_ASSERT(!*emitted);
JS_ASSERT(obj->is<ProxyObject>());
if (hasGenericProxyStub())
return true;
*emitted = true;
Label failures;
Label classPass;
MacroAssembler masm(cx);
RepatchStubAppender attacher(*this);
Register scratchReg = output().valueReg().scratchReg();
masm.setFramePushed(ion->frameSize());
// The branching around here is a little kludgy. It seems mostly unavoidable.
// Ensure that the incoming object has one of the magic class pointers, i.e,
// that it is one of an ObjectProxy, FunctionProxy, or OuterWindowProxy.
masm.branchTestObjClass(Assembler::Equal, object(), scratchReg,
ObjectProxyClassPtr, &classPass);
masm.branchTestObjClass(Assembler::Equal, object(), scratchReg,
FunctionProxyClassPtr, &classPass);
masm.branchTestObjClass(Assembler::NotEqual, object(), scratchReg,
OuterWindowProxyClassPtr, &failures);
masm.bind(&classPass);
// Ensure that the incoming object is not a DOM proxy, so that we can get to
// the specialized stubs
Address handlerAddr(object(), ProxyObject::offsetOfHandler());
masm.loadPrivate(handlerAddr, scratchReg);
Address familyAddr(scratchReg, BaseProxyHandler::offsetOfFamily());
masm.branchPtr(Assembler::Equal, familyAddr, ImmWord(GetDOMProxyHandlerFamily()),
&failures);
if (!EmitCallProxyGet(cx, masm, attacher, name, liveRegs_, object(), output(), returnAddr))
return false;
attacher.jumpRejoin(masm);
masm.bind(&failures);
attacher.jumpNextStub(masm);
JS_ASSERT(!hasGenericProxyStub_);
hasGenericProxyStub_ = true;
return linkAndAttachStub(cx, masm, attacher, ion, "Generic Proxy get");
}
bool
@ -1649,6 +1707,7 @@ GetPropertyIC::reset()
hasTypedArrayLengthStub_ = false;
hasStrictArgumentsLengthStub_ = false;
hasNormalArgumentsLengthStub_ = false;
hasGenericProxyStub_ = false;
}
bool

View File

@ -509,6 +509,7 @@ class GetPropertyIC : public RepatchIonCache
bool hasTypedArrayLengthStub_ : 1;
bool hasStrictArgumentsLengthStub_ : 1;
bool hasNormalArgumentsLengthStub_ : 1;
bool hasGenericProxyStub_ : 1;
public:
GetPropertyIC(RegisterSet liveRegs,
@ -523,7 +524,8 @@ class GetPropertyIC : public RepatchIonCache
hasArrayLengthStub_(false),
hasTypedArrayLengthStub_(false),
hasStrictArgumentsLengthStub_(false),
hasNormalArgumentsLengthStub_(false)
hasNormalArgumentsLengthStub_(false),
hasGenericProxyStub_(false)
{
}
@ -552,6 +554,9 @@ class GetPropertyIC : public RepatchIonCache
bool hasArgumentsLengthStub(bool strict) const {
return strict ? hasStrictArgumentsLengthStub_ : hasNormalArgumentsLengthStub_;
}
bool hasGenericProxyStub() const {
return hasGenericProxyStub_;
}
enum NativeGetPropCacheability {
CanAttachError,
@ -572,6 +577,8 @@ class GetPropertyIC : public RepatchIonCache
HandlePropertyName name, void *returnAddr, bool *emitted);
bool tryAttachProxy(JSContext *cx, IonScript *ion, HandleObject obj,
HandlePropertyName name, void *returnAddr, bool *emitted);
bool tryAttachGenericProxy(JSContext *cx, IonScript *ion, HandleObject obj,
HandlePropertyName name, void *returnAddr, bool *emitted);
bool tryAttachDOMProxyShadowed(JSContext *cx, IonScript *ion, HandleObject obj,
void *returnAddr, bool *emitted);
bool tryAttachDOMProxyUnshadowed(JSContext *cx, IonScript *ion, HandleObject obj,

View File

@ -73,6 +73,9 @@ class JS_FRIEND_API(BaseProxyHandler)
inline void *family() {
return mFamily;
}
static size_t offsetOfFamily() {
return offsetof(BaseProxyHandler, mFamily);
}
virtual bool isOuterWindow() {
return false;