mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 922861 - Implement caching getter calls in GetElementIC. (r=djvj)
This commit is contained in:
parent
b1c5789400
commit
f7ce83cf48
@ -6152,7 +6152,8 @@ CodeGenerator::addGetElementCache(LInstruction *ins, Register obj, ConstantOrReg
|
||||
{
|
||||
switch (gen->info().executionMode()) {
|
||||
case SequentialExecution: {
|
||||
GetElementIC cache(obj, index, output, monitoredResult);
|
||||
RegisterSet liveRegs = ins->safepoint()->liveRegs();
|
||||
GetElementIC cache(liveRegs, obj, index, output, monitoredResult);
|
||||
return addCache(ins, allocateCache(cache));
|
||||
}
|
||||
case ParallelExecution: {
|
||||
|
@ -984,20 +984,24 @@ static bool
|
||||
GenerateCallGetter(JSContext *cx, IonScript *ion, MacroAssembler &masm,
|
||||
IonCache::StubAttacher &attacher, JSObject *obj, PropertyName *name,
|
||||
JSObject *holder, HandleShape shape, RegisterSet &liveRegs, Register object,
|
||||
TypedOrValueRegister output, void *returnAddr)
|
||||
TypedOrValueRegister output, void *returnAddr, Label *failures = NULL)
|
||||
{
|
||||
JS_ASSERT(obj->isNative());
|
||||
JS_ASSERT(output.hasValue());
|
||||
// Initial shape check.
|
||||
|
||||
// Use the passed in label if there was one. Otherwise, we'll have to make our own.
|
||||
Label stubFailure;
|
||||
failures = failures ? failures : &stubFailure;
|
||||
|
||||
// Initial shape check.
|
||||
masm.branchPtr(Assembler::NotEqual, Address(object, JSObject::offsetOfShape()),
|
||||
ImmGCPtr(obj->lastProperty()), &stubFailure);
|
||||
ImmGCPtr(obj->lastProperty()), failures);
|
||||
|
||||
Register scratchReg = output.valueReg().scratchReg();
|
||||
|
||||
// Note: this may clobber the object register if it's used as scratch.
|
||||
if (obj != holder)
|
||||
GeneratePrototypeGuards(cx, ion, masm, obj, holder, object, scratchReg, &stubFailure);
|
||||
GeneratePrototypeGuards(cx, ion, masm, obj, holder, object, scratchReg, failures);
|
||||
|
||||
// Guard on the holder's shape.
|
||||
Register holderReg = scratchReg;
|
||||
@ -1005,7 +1009,7 @@ GenerateCallGetter(JSContext *cx, IonScript *ion, MacroAssembler &masm,
|
||||
masm.branchPtr(Assembler::NotEqual,
|
||||
Address(holderReg, JSObject::offsetOfShape()),
|
||||
ImmGCPtr(holder->lastProperty()),
|
||||
&stubFailure);
|
||||
failures);
|
||||
|
||||
// Now we're good to go to invoke the native call.
|
||||
if (!EmitGetterCall(cx, masm, attacher, obj, holder, shape, liveRegs, object,
|
||||
@ -1016,7 +1020,7 @@ GenerateCallGetter(JSContext *cx, IonScript *ion, MacroAssembler &masm,
|
||||
attacher.jumpRejoin(masm);
|
||||
|
||||
// Jump to next stub.
|
||||
masm.bind(&stubFailure);
|
||||
masm.bind(failures);
|
||||
attacher.jumpNextStub(masm);
|
||||
|
||||
return true;
|
||||
@ -2965,7 +2969,8 @@ GetElementIC::canAttachGetProp(JSObject *obj, const Value &idval, jsid id)
|
||||
|
||||
bool
|
||||
GetElementIC::attachGetProp(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
const Value &idval, HandlePropertyName name)
|
||||
const Value &idval, HandlePropertyName name,
|
||||
void *returnAddr)
|
||||
{
|
||||
JS_ASSERT(index().reg().hasValue());
|
||||
|
||||
@ -2973,9 +2978,14 @@ GetElementIC::attachGetProp(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
RootedShape shape(cx);
|
||||
|
||||
GetPropertyIC::NativeGetPropCacheability canCache =
|
||||
CanAttachNativeGetProp(cx, *this, obj, name, &holder, &shape);
|
||||
CanAttachNativeGetProp(cx, *this, obj, name, &holder, &shape,
|
||||
/* skipArrayLen =*/true);
|
||||
|
||||
if (canCache != GetPropertyIC::CanAttachReadSlot) {
|
||||
bool cacheable = canCache == GetPropertyIC::CanAttachReadSlot ||
|
||||
(canCache == GetPropertyIC::CanAttachCallGetter &&
|
||||
output().hasValue());
|
||||
|
||||
if (!cacheable) {
|
||||
IonSpew(IonSpew_InlineCaches, "GETELEM uncacheable property");
|
||||
return true;
|
||||
}
|
||||
@ -2990,8 +3000,19 @@ GetElementIC::attachGetProp(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
masm.branchTestValue(Assembler::NotEqual, val, idval, &failures);
|
||||
|
||||
RepatchStubAppender attacher(*this);
|
||||
GenerateReadSlot(cx, ion, masm, attacher, obj, holder, shape, object(), output(),
|
||||
&failures);
|
||||
if (canCache == GetPropertyIC::CanAttachReadSlot) {
|
||||
GenerateReadSlot(cx, ion, masm, attacher, obj, holder, shape, object(), output(),
|
||||
&failures);
|
||||
} else {
|
||||
JS_ASSERT(canCache == GetPropertyIC::CanAttachCallGetter);
|
||||
// Set the frame for bailout safety of the OOL call.
|
||||
masm.setFramePushed(ion->frameSize());
|
||||
if (!GenerateCallGetter(cx, ion, masm, attacher, obj, name, holder, shape, liveRegs_,
|
||||
object(), output(), returnAddr, &failures))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return linkAndAttachStub(cx, masm, attacher, ion, "property");
|
||||
}
|
||||
@ -3316,7 +3337,8 @@ bool
|
||||
GetElementIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
|
||||
HandleValue idval, MutableHandleValue res)
|
||||
{
|
||||
IonScript *ion = GetTopIonJSScript(cx)->ionScript();
|
||||
void *returnAddr;
|
||||
IonScript *ion = GetTopIonJSScript(cx, &returnAddr)->ionScript();
|
||||
GetElementIC &cache = ion->getCache(cacheIndex).toGetElement();
|
||||
RootedScript script(cx);
|
||||
jsbytecode *pc;
|
||||
@ -3353,7 +3375,7 @@ GetElementIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
|
||||
}
|
||||
if (!attachedStub && cache.monitoredResult() && canAttachGetProp(obj, idval, id)) {
|
||||
RootedPropertyName name(cx, JSID_TO_ATOM(id)->asPropertyName());
|
||||
if (!cache.attachGetProp(cx, ion, obj, idval, name))
|
||||
if (!cache.attachGetProp(cx, ion, obj, idval, name, returnAddr))
|
||||
return false;
|
||||
attachedStub = true;
|
||||
}
|
||||
|
@ -705,6 +705,8 @@ class SetPropertyIC : public RepatchIonCache
|
||||
class GetElementIC : public RepatchIonCache
|
||||
{
|
||||
protected:
|
||||
RegisterSet liveRegs_;
|
||||
|
||||
Register object_;
|
||||
ConstantOrRegister index_;
|
||||
TypedOrValueRegister output_;
|
||||
@ -719,9 +721,10 @@ class GetElementIC : public RepatchIonCache
|
||||
static const size_t MAX_FAILED_UPDATES;
|
||||
|
||||
public:
|
||||
GetElementIC(Register object, ConstantOrRegister index,
|
||||
GetElementIC(RegisterSet liveRegs, Register object, ConstantOrRegister index,
|
||||
TypedOrValueRegister output, bool monitoredResult)
|
||||
: object_(object),
|
||||
: liveRegs_(liveRegs),
|
||||
object_(object),
|
||||
index_(index),
|
||||
output_(output),
|
||||
monitoredResult_(monitoredResult),
|
||||
@ -761,7 +764,7 @@ class GetElementIC : public RepatchIonCache
|
||||
|
||||
// Helpers for CanAttachNativeGetProp
|
||||
typedef JSContext * Context;
|
||||
bool allowGetters() const { return false; }
|
||||
bool allowGetters() const { JS_ASSERT(!idempotent()); return true; }
|
||||
bool allowArrayLength(Context, HandleObject) const { return false; }
|
||||
bool canMonitorSingletonUndefinedSlot(HandleObject holder, HandleShape shape) const {
|
||||
return monitoredResult();
|
||||
@ -772,7 +775,8 @@ class GetElementIC : public RepatchIonCache
|
||||
static bool canAttachTypedArrayElement(JSObject *obj, const Value &idval,
|
||||
TypedOrValueRegister output);
|
||||
|
||||
bool attachGetProp(JSContext *cx, IonScript *ion, HandleObject obj, const Value &idval, HandlePropertyName name);
|
||||
bool attachGetProp(JSContext *cx, IonScript *ion, HandleObject obj, const Value &idval,
|
||||
HandlePropertyName name, void *returnAddr);
|
||||
bool attachDenseElement(JSContext *cx, IonScript *ion, JSObject *obj, const Value &idval);
|
||||
bool attachTypedArrayElement(JSContext *cx, IonScript *ion, TypedArrayObject *tarr,
|
||||
const Value &idval);
|
||||
|
Loading…
Reference in New Issue
Block a user