mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 994957 - Fix pseudostack update by Ion ICs in inlined scripts to use top-level script in the frame and the pc of the call it makes to the inlined script. r=jandem
This commit is contained in:
parent
cb05abe1d6
commit
766eb08622
@ -6753,6 +6753,7 @@ CodeGenerator::visitCallsiteCloneCache(LCallsiteCloneCache *ins)
|
||||
Register output = ToRegister(ins->output());
|
||||
|
||||
CallsiteCloneIC cache(callee, mir->block()->info().script(), mir->callPc(), output);
|
||||
cache.setProfilerLeavePC(mir->profilerLeavePc());
|
||||
return addCache(ins, allocateCache(cache));
|
||||
}
|
||||
|
||||
@ -6786,6 +6787,7 @@ CodeGenerator::visitGetNameCache(LGetNameCache *ins)
|
||||
bool isTypeOf = ins->mir()->accessKind() != MGetNameCache::NAME;
|
||||
|
||||
NameIC cache(liveRegs, isTypeOf, scopeChain, ins->mir()->name(), output);
|
||||
cache.setProfilerLeavePC(ins->mir()->profilerLeavePc());
|
||||
return addCache(ins, allocateCache(cache));
|
||||
}
|
||||
|
||||
@ -6812,15 +6814,17 @@ CodeGenerator::visitNameIC(OutOfLineUpdateCache *ool, DataPtr<NameIC> &ic)
|
||||
bool
|
||||
CodeGenerator::addGetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
|
||||
PropertyName *name, TypedOrValueRegister output,
|
||||
bool monitoredResult)
|
||||
bool monitoredResult, jsbytecode *profilerLeavePc)
|
||||
{
|
||||
switch (gen->info().executionMode()) {
|
||||
case SequentialExecution: {
|
||||
GetPropertyIC cache(liveRegs, objReg, name, output, monitoredResult);
|
||||
cache.setProfilerLeavePC(profilerLeavePc);
|
||||
return addCache(ins, allocateCache(cache));
|
||||
}
|
||||
case ParallelExecution: {
|
||||
GetPropertyParIC cache(objReg, name, output);
|
||||
cache.setProfilerLeavePC(profilerLeavePc);
|
||||
return addCache(ins, allocateCache(cache));
|
||||
}
|
||||
default:
|
||||
@ -6831,15 +6835,17 @@ CodeGenerator::addGetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Regi
|
||||
bool
|
||||
CodeGenerator::addSetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
|
||||
PropertyName *name, ConstantOrRegister value, bool strict,
|
||||
bool needsTypeBarrier)
|
||||
bool needsTypeBarrier, jsbytecode *profilerLeavePc)
|
||||
{
|
||||
switch (gen->info().executionMode()) {
|
||||
case SequentialExecution: {
|
||||
SetPropertyIC cache(liveRegs, objReg, name, value, strict, needsTypeBarrier);
|
||||
cache.setProfilerLeavePC(profilerLeavePc);
|
||||
return addCache(ins, allocateCache(cache));
|
||||
}
|
||||
case ParallelExecution: {
|
||||
SetPropertyParIC cache(objReg, name, value, strict, needsTypeBarrier);
|
||||
cache.setProfilerLeavePC(profilerLeavePc);
|
||||
return addCache(ins, allocateCache(cache));
|
||||
}
|
||||
default:
|
||||
@ -6850,17 +6856,20 @@ CodeGenerator::addSetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Regi
|
||||
bool
|
||||
CodeGenerator::addSetElementCache(LInstruction *ins, Register obj, Register unboxIndex,
|
||||
Register temp, FloatRegister tempFloat, ValueOperand index,
|
||||
ConstantOrRegister value, bool strict, bool guardHoles)
|
||||
ConstantOrRegister value, bool strict, bool guardHoles,
|
||||
jsbytecode *profilerLeavePc)
|
||||
{
|
||||
switch (gen->info().executionMode()) {
|
||||
case SequentialExecution: {
|
||||
SetElementIC cache(obj, unboxIndex, temp, tempFloat, index, value, strict,
|
||||
guardHoles);
|
||||
cache.setProfilerLeavePC(profilerLeavePc);
|
||||
return addCache(ins, allocateCache(cache));
|
||||
}
|
||||
case ParallelExecution: {
|
||||
SetElementParIC cache(obj, unboxIndex, temp, tempFloat, index, value, strict,
|
||||
guardHoles);
|
||||
cache.setProfilerLeavePC(profilerLeavePc);
|
||||
return addCache(ins, allocateCache(cache));
|
||||
}
|
||||
default:
|
||||
@ -6877,7 +6886,8 @@ CodeGenerator::visitGetPropertyCacheV(LGetPropertyCacheV *ins)
|
||||
bool monitoredResult = ins->mir()->monitoredResult();
|
||||
TypedOrValueRegister output = TypedOrValueRegister(GetValueOutput(ins));
|
||||
|
||||
return addGetPropertyCache(ins, liveRegs, objReg, name, output, monitoredResult);
|
||||
return addGetPropertyCache(ins, liveRegs, objReg, name, output, monitoredResult,
|
||||
ins->mir()->profilerLeavePc());
|
||||
}
|
||||
|
||||
bool
|
||||
@ -6889,7 +6899,8 @@ CodeGenerator::visitGetPropertyCacheT(LGetPropertyCacheT *ins)
|
||||
bool monitoredResult = ins->mir()->monitoredResult();
|
||||
TypedOrValueRegister output(ins->mir()->type(), ToAnyRegister(ins->getDef(0)));
|
||||
|
||||
return addGetPropertyCache(ins, liveRegs, objReg, name, output, monitoredResult);
|
||||
return addGetPropertyCache(ins, liveRegs, objReg, name, output, monitoredResult,
|
||||
ins->mir()->profilerLeavePc());
|
||||
}
|
||||
|
||||
typedef bool (*GetPropertyICFn)(JSContext *, size_t, HandleObject, MutableHandleValue);
|
||||
@ -6945,16 +6956,18 @@ CodeGenerator::visitGetPropertyParIC(OutOfLineUpdateCache *ool, DataPtr<GetPrope
|
||||
bool
|
||||
CodeGenerator::addGetElementCache(LInstruction *ins, Register obj, ConstantOrRegister index,
|
||||
TypedOrValueRegister output, bool monitoredResult,
|
||||
bool allowDoubleResult)
|
||||
bool allowDoubleResult, jsbytecode *profilerLeavePc)
|
||||
{
|
||||
switch (gen->info().executionMode()) {
|
||||
case SequentialExecution: {
|
||||
RegisterSet liveRegs = ins->safepoint()->liveRegs();
|
||||
GetElementIC cache(liveRegs, obj, index, output, monitoredResult, allowDoubleResult);
|
||||
cache.setProfilerLeavePC(profilerLeavePc);
|
||||
return addCache(ins, allocateCache(cache));
|
||||
}
|
||||
case ParallelExecution: {
|
||||
GetElementParIC cache(obj, index, output, monitoredResult, allowDoubleResult);
|
||||
cache.setProfilerLeavePC(profilerLeavePc);
|
||||
return addCache(ins, allocateCache(cache));
|
||||
}
|
||||
default:
|
||||
@ -6970,7 +6983,8 @@ CodeGenerator::visitGetElementCacheV(LGetElementCacheV *ins)
|
||||
TypedOrValueRegister output = TypedOrValueRegister(GetValueOutput(ins));
|
||||
const MGetElementCache *mir = ins->mir();
|
||||
|
||||
return addGetElementCache(ins, obj, index, output, mir->monitoredResult(), mir->allowDoubleResult());
|
||||
return addGetElementCache(ins, obj, index, output, mir->monitoredResult(),
|
||||
mir->allowDoubleResult(), mir->profilerLeavePc());
|
||||
}
|
||||
|
||||
bool
|
||||
@ -6981,7 +6995,8 @@ CodeGenerator::visitGetElementCacheT(LGetElementCacheT *ins)
|
||||
TypedOrValueRegister output(ins->mir()->type(), ToAnyRegister(ins->output()));
|
||||
const MGetElementCache *mir = ins->mir();
|
||||
|
||||
return addGetElementCache(ins, obj, index, output, mir->monitoredResult(), mir->allowDoubleResult());
|
||||
return addGetElementCache(ins, obj, index, output, mir->monitoredResult(),
|
||||
mir->allowDoubleResult(), mir->profilerLeavePc());
|
||||
}
|
||||
|
||||
typedef bool (*GetElementICFn)(JSContext *, size_t, HandleObject, HandleValue, MutableHandleValue);
|
||||
@ -7017,7 +7032,8 @@ CodeGenerator::visitSetElementCacheV(LSetElementCacheV *ins)
|
||||
ConstantOrRegister value = TypedOrValueRegister(ToValue(ins, LSetElementCacheV::Value));
|
||||
|
||||
return addSetElementCache(ins, obj, unboxIndex, temp, tempFloat, index, value,
|
||||
ins->mir()->strict(), ins->mir()->guardHoles());
|
||||
ins->mir()->strict(), ins->mir()->guardHoles(),
|
||||
ins->mir()->profilerLeavePc());
|
||||
}
|
||||
|
||||
bool
|
||||
@ -7036,7 +7052,8 @@ CodeGenerator::visitSetElementCacheT(LSetElementCacheT *ins)
|
||||
value = TypedOrValueRegister(ins->mir()->value()->type(), ToAnyRegister(tmp));
|
||||
|
||||
return addSetElementCache(ins, obj, unboxIndex, temp, tempFloat, index, value,
|
||||
ins->mir()->strict(), ins->mir()->guardHoles());
|
||||
ins->mir()->strict(), ins->mir()->guardHoles(),
|
||||
ins->mir()->profilerLeavePc());
|
||||
}
|
||||
|
||||
typedef bool (*SetElementICFn)(JSContext *, size_t, HandleObject, HandleValue, HandleValue);
|
||||
@ -7112,6 +7129,7 @@ CodeGenerator::visitBindNameCache(LBindNameCache *ins)
|
||||
Register scopeChain = ToRegister(ins->scopeChain());
|
||||
Register output = ToRegister(ins->output());
|
||||
BindNameIC cache(scopeChain, ins->mir()->name(), output);
|
||||
cache.setProfilerLeavePC(ins->mir()->profilerLeavePc());
|
||||
|
||||
return addCache(ins, allocateCache(cache));
|
||||
}
|
||||
@ -7206,7 +7224,8 @@ CodeGenerator::visitSetPropertyCacheV(LSetPropertyCacheV *ins)
|
||||
ConstantOrRegister value = TypedOrValueRegister(ToValue(ins, LSetPropertyCacheV::Value));
|
||||
|
||||
return addSetPropertyCache(ins, liveRegs, objReg, ins->mir()->name(), value,
|
||||
ins->mir()->strict(), ins->mir()->needsTypeBarrier());
|
||||
ins->mir()->strict(), ins->mir()->needsTypeBarrier(),
|
||||
ins->mir()->profilerLeavePc());
|
||||
}
|
||||
|
||||
bool
|
||||
@ -7222,7 +7241,8 @@ CodeGenerator::visitSetPropertyCacheT(LSetPropertyCacheT *ins)
|
||||
value = TypedOrValueRegister(ins->valueType(), ToAnyRegister(ins->getOperand(1)));
|
||||
|
||||
return addSetPropertyCache(ins, liveRegs, objReg, ins->mir()->name(), value,
|
||||
ins->mir()->strict(), ins->mir()->needsTypeBarrier());
|
||||
ins->mir()->strict(), ins->mir()->needsTypeBarrier(),
|
||||
ins->mir()->profilerLeavePc());
|
||||
}
|
||||
|
||||
typedef bool (*SetPropertyICFn)(JSContext *, size_t, HandleObject, HandleValue);
|
||||
|
@ -353,16 +353,16 @@ class CodeGenerator : public CodeGeneratorSpecific
|
||||
private:
|
||||
bool addGetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
|
||||
PropertyName *name, TypedOrValueRegister output,
|
||||
bool monitoredResult);
|
||||
bool monitoredResult, jsbytecode *profilerLeavePc);
|
||||
bool addGetElementCache(LInstruction *ins, Register obj, ConstantOrRegister index,
|
||||
TypedOrValueRegister output, bool monitoredResult,
|
||||
bool allowDoubleResult);
|
||||
bool allowDoubleResult, jsbytecode *profilerLeavePc);
|
||||
bool addSetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
|
||||
PropertyName *name, ConstantOrRegister value, bool strict,
|
||||
bool needsTypeBarrier);
|
||||
bool needsTypeBarrier, jsbytecode *profilerLeavePc);
|
||||
bool addSetElementCache(LInstruction *ins, Register obj, Register unboxIndex, Register temp,
|
||||
FloatRegister tempFloat, ValueOperand index, ConstantOrRegister value,
|
||||
bool strict, bool guardHoles);
|
||||
bool strict, bool guardHoles, jsbytecode *profilerLeavePc);
|
||||
bool checkForAbortPar(LInstruction *lir);
|
||||
|
||||
bool generateBranchV(const ValueOperand &value, Label *ifTrue, Label *ifFalse, FloatRegister fr);
|
||||
|
@ -80,6 +80,15 @@ class InlineScriptTree {
|
||||
return caller_;
|
||||
}
|
||||
|
||||
bool isOutermostCaller() const {
|
||||
return caller_ == nullptr;
|
||||
}
|
||||
InlineScriptTree *outermostCaller() {
|
||||
if (isOutermostCaller())
|
||||
return this;
|
||||
return caller_->outermostCaller();
|
||||
}
|
||||
|
||||
jsbytecode *callerPc() const {
|
||||
return callerPc_;
|
||||
}
|
||||
|
@ -1195,11 +1195,12 @@ GetPropertyIC::allowArrayLength(Context cx, HandleObject obj) const
|
||||
}
|
||||
|
||||
bool
|
||||
GetPropertyIC::tryAttachNative(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
GetPropertyIC::tryAttachNative(JSContext *cx, JSScript *topScript, IonScript *ion, HandleObject obj,
|
||||
HandlePropertyName name, void *returnAddr, bool *emitted)
|
||||
{
|
||||
JS_ASSERT(canAttachStub());
|
||||
JS_ASSERT(!*emitted);
|
||||
JS_ASSERT(topScript->ionScript() == ion);
|
||||
|
||||
RootedShape shape(cx);
|
||||
RootedObject holder(cx);
|
||||
@ -1211,7 +1212,7 @@ GetPropertyIC::tryAttachNative(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
|
||||
*emitted = true;
|
||||
|
||||
MacroAssembler masm(cx, ion, script_, pc_);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
|
||||
RepatchStubAppender attacher(*this);
|
||||
const char *attachKind;
|
||||
@ -1244,8 +1245,8 @@ GetPropertyIC::tryAttachNative(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
}
|
||||
|
||||
bool
|
||||
GetPropertyIC::tryAttachTypedArrayLength(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
HandlePropertyName name, bool *emitted)
|
||||
GetPropertyIC::tryAttachTypedArrayLength(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
HandleObject obj, HandlePropertyName name, bool *emitted)
|
||||
{
|
||||
JS_ASSERT(canAttachStub());
|
||||
JS_ASSERT(!*emitted);
|
||||
@ -1270,7 +1271,7 @@ GetPropertyIC::tryAttachTypedArrayLength(JSContext *cx, IonScript *ion, HandleOb
|
||||
|
||||
*emitted = true;
|
||||
|
||||
MacroAssembler masm(cx, ion);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
RepatchStubAppender attacher(*this);
|
||||
GenerateTypedArrayLength(cx, masm, attacher, obj, object(), output());
|
||||
|
||||
@ -1353,7 +1354,7 @@ EmitCallProxyGet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at
|
||||
}
|
||||
|
||||
bool
|
||||
GetPropertyIC::tryAttachDOMProxyShadowed(JSContext *cx, IonScript *ion,
|
||||
GetPropertyIC::tryAttachDOMProxyShadowed(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
HandleObject obj, void *returnAddr,
|
||||
bool *emitted)
|
||||
{
|
||||
@ -1369,7 +1370,7 @@ GetPropertyIC::tryAttachDOMProxyShadowed(JSContext *cx, IonScript *ion,
|
||||
*emitted = true;
|
||||
|
||||
Label failures;
|
||||
MacroAssembler masm(cx, ion, script_, pc_);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
RepatchStubAppender attacher(*this);
|
||||
|
||||
// Guard on the shape of the object.
|
||||
@ -1399,9 +1400,9 @@ GetPropertyIC::tryAttachDOMProxyShadowed(JSContext *cx, IonScript *ion,
|
||||
}
|
||||
|
||||
bool
|
||||
GetPropertyIC::tryAttachDOMProxyUnshadowed(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
HandlePropertyName name, bool resetNeeded,
|
||||
void *returnAddr, bool *emitted)
|
||||
GetPropertyIC::tryAttachDOMProxyUnshadowed(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
HandleObject obj, HandlePropertyName name,
|
||||
bool resetNeeded, void *returnAddr, bool *emitted)
|
||||
{
|
||||
JS_ASSERT(canAttachStub());
|
||||
JS_ASSERT(!*emitted);
|
||||
@ -1438,7 +1439,7 @@ GetPropertyIC::tryAttachDOMProxyUnshadowed(JSContext *cx, IonScript *ion, Handle
|
||||
}
|
||||
|
||||
Label failures;
|
||||
MacroAssembler masm(cx, ion, script_, pc_);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
RepatchStubAppender attacher(*this);
|
||||
|
||||
// Guard on the shape of the object.
|
||||
@ -1499,7 +1500,7 @@ GetPropertyIC::tryAttachDOMProxyUnshadowed(JSContext *cx, IonScript *ion, Handle
|
||||
}
|
||||
|
||||
bool
|
||||
GetPropertyIC::tryAttachProxy(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
GetPropertyIC::tryAttachProxy(JSContext *cx, JSScript *topScript, IonScript *ion, HandleObject obj,
|
||||
HandlePropertyName name, void *returnAddr,
|
||||
bool *emitted)
|
||||
{
|
||||
@ -1521,13 +1522,13 @@ GetPropertyIC::tryAttachProxy(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
if (shadows == ShadowCheckFailed)
|
||||
return false;
|
||||
if (shadows == Shadows)
|
||||
return tryAttachDOMProxyShadowed(cx, ion, obj, returnAddr, emitted);
|
||||
return tryAttachDOMProxyShadowed(cx, topScript, ion, obj, returnAddr, emitted);
|
||||
|
||||
return tryAttachDOMProxyUnshadowed(cx, ion, obj, name, shadows == DoesntShadowUnique,
|
||||
returnAddr, emitted);
|
||||
return tryAttachDOMProxyUnshadowed(cx, topScript, ion, obj, name,
|
||||
shadows == DoesntShadowUnique, returnAddr, emitted);
|
||||
}
|
||||
|
||||
return tryAttachGenericProxy(cx, ion, obj, name, returnAddr, emitted);
|
||||
return tryAttachGenericProxy(cx, topScript, ion, obj, name, returnAddr, emitted);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1541,8 +1542,8 @@ GenerateProxyClassGuards(MacroAssembler &masm, Register object, Register scratch
|
||||
}
|
||||
|
||||
bool
|
||||
GetPropertyIC::tryAttachGenericProxy(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
HandlePropertyName name, void *returnAddr,
|
||||
GetPropertyIC::tryAttachGenericProxy(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
HandleObject obj, HandlePropertyName name, void *returnAddr,
|
||||
bool *emitted)
|
||||
{
|
||||
JS_ASSERT(canAttachStub());
|
||||
@ -1560,7 +1561,7 @@ GetPropertyIC::tryAttachGenericProxy(JSContext *cx, IonScript *ion, HandleObject
|
||||
*emitted = true;
|
||||
|
||||
Label failures;
|
||||
MacroAssembler masm(cx, ion, script_, pc_);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
RepatchStubAppender attacher(*this);
|
||||
|
||||
Register scratchReg = output().valueReg().scratchReg();
|
||||
@ -1590,8 +1591,8 @@ GetPropertyIC::tryAttachGenericProxy(JSContext *cx, IonScript *ion, HandleObject
|
||||
}
|
||||
|
||||
bool
|
||||
GetPropertyIC::tryAttachArgumentsLength(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
HandlePropertyName name, bool *emitted)
|
||||
GetPropertyIC::tryAttachArgumentsLength(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
HandleObject obj, HandlePropertyName name, bool *emitted)
|
||||
{
|
||||
JS_ASSERT(canAttachStub());
|
||||
JS_ASSERT(!*emitted);
|
||||
@ -1613,7 +1614,7 @@ GetPropertyIC::tryAttachArgumentsLength(JSContext *cx, IonScript *ion, HandleObj
|
||||
JS_ASSERT(!idempotent());
|
||||
|
||||
Label failures;
|
||||
MacroAssembler masm(cx, ion);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
RepatchStubAppender attacher(*this);
|
||||
|
||||
Register tmpReg;
|
||||
@ -1660,7 +1661,7 @@ GetPropertyIC::tryAttachArgumentsLength(JSContext *cx, IonScript *ion, HandleObj
|
||||
}
|
||||
|
||||
bool
|
||||
GetPropertyIC::tryAttachStub(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
GetPropertyIC::tryAttachStub(JSContext *cx, JSScript *topScript, IonScript *ion, HandleObject obj,
|
||||
HandlePropertyName name, void *returnAddr, bool *emitted)
|
||||
{
|
||||
JS_ASSERT(!*emitted);
|
||||
@ -1668,16 +1669,16 @@ GetPropertyIC::tryAttachStub(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
if (!canAttachStub())
|
||||
return true;
|
||||
|
||||
if (!*emitted && !tryAttachArgumentsLength(cx, ion, obj, name, emitted))
|
||||
if (!*emitted && !tryAttachArgumentsLength(cx, topScript, ion, obj, name, emitted))
|
||||
return false;
|
||||
|
||||
if (!*emitted && !tryAttachProxy(cx, ion, obj, name, returnAddr, emitted))
|
||||
if (!*emitted && !tryAttachProxy(cx, topScript, ion, obj, name, returnAddr, emitted))
|
||||
return false;
|
||||
|
||||
if (!*emitted && !tryAttachNative(cx, ion, obj, name, returnAddr, emitted))
|
||||
if (!*emitted && !tryAttachNative(cx, topScript, ion, obj, name, returnAddr, emitted))
|
||||
return false;
|
||||
|
||||
if (!*emitted && !tryAttachTypedArrayLength(cx, ion, obj, name, emitted))
|
||||
if (!*emitted && !tryAttachTypedArrayLength(cx, topScript, ion, obj, name, emitted))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -1707,7 +1708,7 @@ GetPropertyIC::update(JSContext *cx, size_t cacheIndex,
|
||||
// limit. Once we can make calls from within generated stubs, a new call
|
||||
// stub will be generated instead and the previous stubs unlinked.
|
||||
bool emitted = false;
|
||||
if (!cache.tryAttachStub(cx, ion, obj, name, returnAddr, &emitted))
|
||||
if (!cache.tryAttachStub(cx, topScript, ion, obj, name, returnAddr, &emitted))
|
||||
return false;
|
||||
|
||||
if (cache.idempotent() && !emitted) {
|
||||
@ -2005,10 +2006,10 @@ GenerateSetSlot(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &att
|
||||
}
|
||||
|
||||
bool
|
||||
SetPropertyIC::attachSetSlot(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
SetPropertyIC::attachSetSlot(JSContext *cx, JSScript *topScript, IonScript *ion, HandleObject obj,
|
||||
HandleShape shape, bool checkTypeset)
|
||||
{
|
||||
MacroAssembler masm(cx, ion);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
RepatchStubAppender attacher(*this);
|
||||
GenerateSetSlot(cx, masm, attacher, obj, shape, object(), value(), needsTypeBarrier(),
|
||||
checkTypeset);
|
||||
@ -2124,11 +2125,12 @@ EmitCallProxySet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at
|
||||
}
|
||||
|
||||
bool
|
||||
SetPropertyIC::attachGenericProxy(JSContext *cx, IonScript *ion, void *returnAddr)
|
||||
SetPropertyIC::attachGenericProxy(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
void *returnAddr)
|
||||
{
|
||||
JS_ASSERT(!hasGenericProxyStub());
|
||||
|
||||
MacroAssembler masm(cx, ion, script_, pc_);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
RepatchStubAppender attacher(*this);
|
||||
|
||||
Label failures;
|
||||
@ -2179,13 +2181,13 @@ SetPropertyIC::attachGenericProxy(JSContext *cx, IonScript *ion, void *returnAdd
|
||||
}
|
||||
|
||||
bool
|
||||
SetPropertyIC::attachDOMProxyShadowed(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
void *returnAddr)
|
||||
SetPropertyIC::attachDOMProxyShadowed(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
HandleObject obj, void *returnAddr)
|
||||
{
|
||||
JS_ASSERT(IsCacheableDOMProxy(obj));
|
||||
|
||||
Label failures;
|
||||
MacroAssembler masm(cx, ion, script_, pc_);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
RepatchStubAppender attacher(*this);
|
||||
|
||||
// Guard on the shape of the object.
|
||||
@ -2406,13 +2408,13 @@ IsCacheableDOMProxyUnshadowedSetterCall(JSContext *cx, HandleObject obj, HandleP
|
||||
}
|
||||
|
||||
bool
|
||||
SetPropertyIC::attachDOMProxyUnshadowed(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
void *returnAddr)
|
||||
SetPropertyIC::attachDOMProxyUnshadowed(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
HandleObject obj, void *returnAddr)
|
||||
{
|
||||
JS_ASSERT(IsCacheableDOMProxy(obj));
|
||||
|
||||
Label failures;
|
||||
MacroAssembler masm(cx, ion, script_, pc_);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
RepatchStubAppender attacher(*this);
|
||||
|
||||
// Guard on the shape of the object.
|
||||
@ -2461,13 +2463,13 @@ SetPropertyIC::attachDOMProxyUnshadowed(JSContext *cx, IonScript *ion, HandleObj
|
||||
}
|
||||
|
||||
bool
|
||||
SetPropertyIC::attachCallSetter(JSContext *cx, IonScript *ion,
|
||||
SetPropertyIC::attachCallSetter(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
HandleObject obj, HandleObject holder, HandleShape shape,
|
||||
void *returnAddr)
|
||||
{
|
||||
JS_ASSERT(obj->isNative());
|
||||
|
||||
MacroAssembler masm(cx, ion, script_, pc_);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
RepatchStubAppender attacher(*this);
|
||||
|
||||
Label failure;
|
||||
@ -2574,12 +2576,12 @@ GenerateAddSlot(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &att
|
||||
}
|
||||
|
||||
bool
|
||||
SetPropertyIC::attachAddSlot(JSContext *cx, IonScript *ion, JSObject *obj, HandleShape oldShape,
|
||||
bool checkTypeset)
|
||||
SetPropertyIC::attachAddSlot(JSContext *cx, JSScript *topScript, IonScript *ion, JSObject *obj,
|
||||
HandleShape oldShape, bool checkTypeset)
|
||||
{
|
||||
JS_ASSERT_IF(!needsTypeBarrier(), !checkTypeset);
|
||||
|
||||
MacroAssembler masm(cx, ion);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
RepatchStubAppender attacher(*this);
|
||||
GenerateAddSlot(cx, masm, attacher, obj, oldShape, object(), value(), checkTypeset);
|
||||
return linkAndAttachStub(cx, masm, attacher, ion, "adding");
|
||||
@ -2770,21 +2772,21 @@ SetPropertyIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
|
||||
if (shadows == ShadowCheckFailed)
|
||||
return false;
|
||||
if (shadows == Shadows) {
|
||||
if (!cache.attachDOMProxyShadowed(cx, ion, obj, returnAddr))
|
||||
if (!cache.attachDOMProxyShadowed(cx, script, ion, obj, returnAddr))
|
||||
return false;
|
||||
addedSetterStub = true;
|
||||
} else {
|
||||
JS_ASSERT(shadows == DoesntShadow || shadows == DoesntShadowUnique);
|
||||
if (shadows == DoesntShadowUnique)
|
||||
cache.reset();
|
||||
if (!cache.attachDOMProxyUnshadowed(cx, ion, obj, returnAddr))
|
||||
if (!cache.attachDOMProxyUnshadowed(cx, script, ion, obj, returnAddr))
|
||||
return false;
|
||||
addedSetterStub = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!addedSetterStub && !cache.hasGenericProxyStub()) {
|
||||
if (!cache.attachGenericProxy(cx, ion, returnAddr))
|
||||
if (!cache.attachGenericProxy(cx, script, ion, returnAddr))
|
||||
return false;
|
||||
addedSetterStub = true;
|
||||
}
|
||||
@ -2803,13 +2805,13 @@ SetPropertyIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
|
||||
&holder, &shape, &checkTypeset);
|
||||
|
||||
if (!addedSetterStub && canCache == CanAttachSetSlot) {
|
||||
if (!cache.attachSetSlot(cx, ion, obj, shape, checkTypeset))
|
||||
if (!cache.attachSetSlot(cx, script, ion, obj, shape, checkTypeset))
|
||||
return false;
|
||||
addedSetterStub = true;
|
||||
}
|
||||
|
||||
if (!addedSetterStub && canCache == CanAttachCallSetter) {
|
||||
if (!cache.attachCallSetter(cx, ion, obj, holder, shape, returnAddr))
|
||||
if (!cache.attachCallSetter(cx, script, ion, obj, holder, shape, returnAddr))
|
||||
return false;
|
||||
addedSetterStub = true;
|
||||
}
|
||||
@ -2828,7 +2830,7 @@ SetPropertyIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
|
||||
IsPropertyAddInlineable(obj, id, cache.value(), oldSlots, oldShape, cache.needsTypeBarrier(),
|
||||
&checkTypeset))
|
||||
{
|
||||
if (!cache.attachAddSlot(cx, ion, obj, oldShape, checkTypeset))
|
||||
if (!cache.attachAddSlot(cx, script, ion, obj, oldShape, checkTypeset))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2969,7 +2971,7 @@ EqualStringsHelper(JSString *str1, JSString *str2)
|
||||
}
|
||||
|
||||
bool
|
||||
GetElementIC::attachGetProp(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
GetElementIC::attachGetProp(JSContext *cx, JSScript *topScript, IonScript *ion, HandleObject obj,
|
||||
const Value &idval, HandlePropertyName name,
|
||||
void *returnAddr)
|
||||
{
|
||||
@ -2995,7 +2997,7 @@ GetElementIC::attachGetProp(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
JS_ASSERT(idval.toString()->length() == name->length());
|
||||
|
||||
Label failures;
|
||||
MacroAssembler masm(cx, ion);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
|
||||
// Ensure the index is a string.
|
||||
ValueOperand val = index().reg().valueReg();
|
||||
@ -3128,9 +3130,10 @@ GenerateDenseElement(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher
|
||||
}
|
||||
|
||||
bool
|
||||
GetElementIC::attachDenseElement(JSContext *cx, IonScript *ion, JSObject *obj, const Value &idval)
|
||||
GetElementIC::attachDenseElement(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
JSObject *obj, const Value &idval)
|
||||
{
|
||||
MacroAssembler masm(cx, ion);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
RepatchStubAppender attacher(*this);
|
||||
if (!GenerateDenseElement(cx, masm, attacher, obj, idval, object(), index(), output()))
|
||||
return false;
|
||||
@ -3282,10 +3285,10 @@ GenerateGetTypedArrayElement(JSContext *cx, MacroAssembler &masm, IonCache::Stub
|
||||
}
|
||||
|
||||
bool
|
||||
GetElementIC::attachTypedArrayElement(JSContext *cx, IonScript *ion, TypedArrayObject *tarr,
|
||||
const Value &idval)
|
||||
GetElementIC::attachTypedArrayElement(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
TypedArrayObject *tarr, const Value &idval)
|
||||
{
|
||||
MacroAssembler masm(cx, ion);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
RepatchStubAppender attacher(*this);
|
||||
GenerateGetTypedArrayElement(cx, masm, attacher, tarr, idval, object(), index(), output(),
|
||||
allowDoubleResult());
|
||||
@ -3293,12 +3296,13 @@ GetElementIC::attachTypedArrayElement(JSContext *cx, IonScript *ion, TypedArrayO
|
||||
}
|
||||
|
||||
bool
|
||||
GetElementIC::attachArgumentsElement(JSContext *cx, IonScript *ion, JSObject *obj)
|
||||
GetElementIC::attachArgumentsElement(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(obj->is<ArgumentsObject>());
|
||||
|
||||
Label failures;
|
||||
MacroAssembler masm(cx, ion);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
RepatchStubAppender attacher(*this);
|
||||
|
||||
Register tmpReg = output().scratchReg().gpr();
|
||||
@ -3406,7 +3410,8 @@ GetElementIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
|
||||
HandleValue idval, MutableHandleValue res)
|
||||
{
|
||||
void *returnAddr;
|
||||
IonScript *ion = GetTopIonJSScript(cx, &returnAddr)->ionScript();
|
||||
RootedScript topScript(cx, GetTopIonJSScript(cx, &returnAddr));
|
||||
IonScript *ion = topScript->ionScript();
|
||||
GetElementIC &cache = ion->getCache(cacheIndex).toGetElement();
|
||||
RootedScript script(cx);
|
||||
jsbytecode *pc;
|
||||
@ -3438,24 +3443,24 @@ GetElementIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
|
||||
cache.index().reg().type() == MIRType_Int32) &&
|
||||
(cache.output().hasValue() || !cache.output().typedReg().isFloat()))
|
||||
{
|
||||
if (!cache.attachArgumentsElement(cx, ion, obj))
|
||||
if (!cache.attachArgumentsElement(cx, topScript, ion, obj))
|
||||
return false;
|
||||
attachedStub = true;
|
||||
}
|
||||
if (!attachedStub && cache.monitoredResult() && canAttachGetProp(obj, idval, id)) {
|
||||
RootedPropertyName name(cx, JSID_TO_ATOM(id)->asPropertyName());
|
||||
if (!cache.attachGetProp(cx, ion, obj, idval, name, returnAddr))
|
||||
if (!cache.attachGetProp(cx, topScript, ion, obj, idval, name, returnAddr))
|
||||
return false;
|
||||
attachedStub = true;
|
||||
}
|
||||
if (!attachedStub && !cache.hasDenseStub() && canAttachDenseElement(obj, idval)) {
|
||||
if (!cache.attachDenseElement(cx, ion, obj, idval))
|
||||
if (!cache.attachDenseElement(cx, topScript, ion, obj, idval))
|
||||
return false;
|
||||
attachedStub = true;
|
||||
}
|
||||
if (!attachedStub && canAttachTypedArrayElement(obj, idval, cache.output())) {
|
||||
Rooted<TypedArrayObject*> tarr(cx, &obj->as<TypedArrayObject>());
|
||||
if (!cache.attachTypedArrayElement(cx, ion, tarr, idval))
|
||||
if (!cache.attachTypedArrayElement(cx, topScript, ion, tarr, idval))
|
||||
return false;
|
||||
attachedStub = true;
|
||||
}
|
||||
@ -3677,9 +3682,10 @@ GenerateSetDenseElement(JSContext *cx, MacroAssembler &masm, IonCache::StubAttac
|
||||
}
|
||||
|
||||
bool
|
||||
SetElementIC::attachDenseElement(JSContext *cx, IonScript *ion, JSObject *obj, const Value &idval)
|
||||
SetElementIC::attachDenseElement(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
JSObject *obj, const Value &idval)
|
||||
{
|
||||
MacroAssembler masm(cx, ion);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
RepatchStubAppender attacher(*this);
|
||||
if (!GenerateSetDenseElement(cx, masm, attacher, obj, idval,
|
||||
guardHoles(), object(), index(),
|
||||
@ -3780,9 +3786,10 @@ GenerateSetTypedArrayElement(JSContext *cx, MacroAssembler &masm, IonCache::Stub
|
||||
}
|
||||
|
||||
bool
|
||||
SetElementIC::attachTypedArrayElement(JSContext *cx, IonScript *ion, TypedArrayObject *tarr)
|
||||
SetElementIC::attachTypedArrayElement(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
TypedArrayObject *tarr)
|
||||
{
|
||||
MacroAssembler masm(cx, ion);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
RepatchStubAppender attacher(*this);
|
||||
if (!GenerateSetTypedArrayElement(cx, masm, attacher, tarr,
|
||||
object(), index(), value(),
|
||||
@ -3798,19 +3805,20 @@ bool
|
||||
SetElementIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
|
||||
HandleValue idval, HandleValue value)
|
||||
{
|
||||
IonScript *ion = GetTopIonJSScript(cx)->ionScript();
|
||||
RootedScript topScript(cx, GetTopIonJSScript(cx));
|
||||
IonScript *ion = topScript->ionScript();
|
||||
SetElementIC &cache = ion->getCache(cacheIndex).toSetElement();
|
||||
|
||||
bool attachedStub = false;
|
||||
if (cache.canAttachStub()) {
|
||||
if (!cache.hasDenseStub() && IsDenseElementSetInlineable(obj, idval)) {
|
||||
if (!cache.attachDenseElement(cx, ion, obj, idval))
|
||||
if (!cache.attachDenseElement(cx, topScript, ion, obj, idval))
|
||||
return false;
|
||||
attachedStub = true;
|
||||
}
|
||||
if (!attachedStub && IsTypedArrayElementSetInlineable(obj, idval, value)) {
|
||||
TypedArrayObject *tarr = &obj->as<TypedArrayObject>();
|
||||
if (!cache.attachTypedArrayElement(cx, ion, tarr))
|
||||
if (!cache.attachTypedArrayElement(cx, topScript, ion, tarr))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -4015,11 +4023,11 @@ GetElementParIC::update(ForkJoinContext *cx, size_t cacheIndex, HandleObject obj
|
||||
}
|
||||
|
||||
bool
|
||||
BindNameIC::attachGlobal(JSContext *cx, IonScript *ion, JSObject *scopeChain)
|
||||
BindNameIC::attachGlobal(JSContext *cx, JSScript *topScript, IonScript *ion, JSObject *scopeChain)
|
||||
{
|
||||
JS_ASSERT(scopeChain->is<GlobalObject>());
|
||||
|
||||
MacroAssembler masm(cx, ion);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
RepatchStubAppender attacher(*this);
|
||||
|
||||
// Guard on the scope chain.
|
||||
@ -4090,11 +4098,12 @@ GenerateScopeChainGuards(MacroAssembler &masm, JSObject *scopeChain, JSObject *h
|
||||
}
|
||||
|
||||
bool
|
||||
BindNameIC::attachNonGlobal(JSContext *cx, IonScript *ion, JSObject *scopeChain, JSObject *holder)
|
||||
BindNameIC::attachNonGlobal(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
JSObject *scopeChain, JSObject *holder)
|
||||
{
|
||||
JS_ASSERT(IsCacheableNonGlobalScope(scopeChain));
|
||||
|
||||
MacroAssembler masm(cx, ion);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
RepatchStubAppender attacher(*this);
|
||||
|
||||
// Guard on the shape of the scope chain.
|
||||
@ -4153,7 +4162,8 @@ BindNameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain)
|
||||
{
|
||||
AutoFlushCache afc ("BindNameCache", cx->runtime()->jitRuntime());
|
||||
|
||||
IonScript *ion = GetTopIonJSScript(cx)->ionScript();
|
||||
RootedScript topScript(cx, GetTopIonJSScript(cx));
|
||||
IonScript *ion = topScript->ionScript();
|
||||
BindNameIC &cache = ion->getCache(cacheIndex).toBindName();
|
||||
HandlePropertyName name = cache.name();
|
||||
|
||||
@ -4169,10 +4179,10 @@ BindNameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain)
|
||||
// GetPropertyCache.
|
||||
if (cache.canAttachStub()) {
|
||||
if (scopeChain->is<GlobalObject>()) {
|
||||
if (!cache.attachGlobal(cx, ion, scopeChain))
|
||||
if (!cache.attachGlobal(cx, topScript, ion, scopeChain))
|
||||
return nullptr;
|
||||
} else if (IsCacheableScopeChain(scopeChain, holder)) {
|
||||
if (!cache.attachNonGlobal(cx, ion, scopeChain, holder))
|
||||
if (!cache.attachNonGlobal(cx, topScript, ion, scopeChain, holder))
|
||||
return nullptr;
|
||||
} else {
|
||||
IonSpew(IonSpew_InlineCaches, "BINDNAME uncacheable scope chain");
|
||||
@ -4183,11 +4193,11 @@ BindNameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain)
|
||||
}
|
||||
|
||||
bool
|
||||
NameIC::attachReadSlot(JSContext *cx, IonScript *ion, HandleObject scopeChain,
|
||||
NameIC::attachReadSlot(JSContext *cx, JSScript *topScript, IonScript *ion, HandleObject scopeChain,
|
||||
HandleObject holderBase, HandleObject holder,
|
||||
HandleShape shape)
|
||||
{
|
||||
MacroAssembler masm(cx, ion);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
Label failures;
|
||||
RepatchStubAppender attacher(*this);
|
||||
|
||||
@ -4247,10 +4257,10 @@ IsCacheableNameReadSlot(JSContext *cx, HandleObject scopeChain, HandleObject obj
|
||||
}
|
||||
|
||||
bool
|
||||
NameIC::attachCallGetter(JSContext *cx, IonScript *ion, JSObject *obj, JSObject *holder,
|
||||
HandleShape shape, void *returnAddr)
|
||||
NameIC::attachCallGetter(JSContext *cx, JSScript *topScript, IonScript *ion, JSObject *obj,
|
||||
JSObject *holder, HandleShape shape, void *returnAddr)
|
||||
{
|
||||
MacroAssembler masm(cx, ion, script_, pc_);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
|
||||
RepatchStubAppender attacher(*this);
|
||||
if (!GenerateCallGetter(cx, ion, masm, attacher, obj, name(), holder, shape, liveRegs_,
|
||||
@ -4283,7 +4293,8 @@ NameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain,
|
||||
AutoFlushCache afc ("GetNameCache", cx->runtime()->jitRuntime());
|
||||
|
||||
void *returnAddr;
|
||||
IonScript *ion = GetTopIonJSScript(cx, &returnAddr)->ionScript();
|
||||
RootedScript topScript(cx, GetTopIonJSScript(cx, &returnAddr));
|
||||
IonScript *ion = topScript->ionScript();
|
||||
|
||||
NameIC &cache = ion->getCache(cacheIndex).toName();
|
||||
RootedPropertyName name(cx, cache.name());
|
||||
@ -4300,10 +4311,10 @@ 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, holder, shape))
|
||||
if (!cache.attachReadSlot(cx, topScript, ion, scopeChain, obj, holder, shape))
|
||||
return false;
|
||||
} else if (IsCacheableNameCallGetter(scopeChain, obj, holder, shape)) {
|
||||
if (!cache.attachCallGetter(cx, ion, obj, holder, shape, returnAddr))
|
||||
if (!cache.attachCallGetter(cx, topScript, ion, obj, holder, shape, returnAddr))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -4323,10 +4334,10 @@ NameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain,
|
||||
}
|
||||
|
||||
bool
|
||||
CallsiteCloneIC::attach(JSContext *cx, IonScript *ion, HandleFunction original,
|
||||
CallsiteCloneIC::attach(JSContext *cx, JSScript *topScript, IonScript *ion, HandleFunction original,
|
||||
HandleFunction clone)
|
||||
{
|
||||
MacroAssembler masm(cx, ion);
|
||||
MacroAssembler masm(cx, ion, topScript, profilerLeavePc_);
|
||||
RepatchStubAppender attacher(*this);
|
||||
|
||||
// Guard against object identity on the original.
|
||||
@ -4351,7 +4362,8 @@ CallsiteCloneIC::update(JSContext *cx, size_t cacheIndex, HandleObject callee)
|
||||
if (!fun->hasScript() || !fun->nonLazyScript()->shouldCloneAtCallsite())
|
||||
return fun;
|
||||
|
||||
IonScript *ion = GetTopIonJSScript(cx)->ionScript();
|
||||
RootedScript topScript(cx, GetTopIonJSScript(cx));
|
||||
IonScript *ion = topScript->ionScript();
|
||||
CallsiteCloneIC &cache = ion->getCache(cacheIndex).toCallsiteClone();
|
||||
|
||||
RootedFunction clone(cx, CloneFunctionAtCallsite(cx, fun, cache.callScript(), cache.callPc()));
|
||||
@ -4359,7 +4371,7 @@ CallsiteCloneIC::update(JSContext *cx, size_t cacheIndex, HandleObject callee)
|
||||
return nullptr;
|
||||
|
||||
if (cache.canAttachStub()) {
|
||||
if (!cache.attach(cx, ion, fun, clone))
|
||||
if (!cache.attach(cx, topScript, ion, fun, clone))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -168,6 +168,10 @@ class IonCache
|
||||
JSScript *script_;
|
||||
jsbytecode *pc_;
|
||||
|
||||
// Location to use when updating profiler pseudostack when leaving this
|
||||
// IC code to enter a callee.
|
||||
jsbytecode *profilerLeavePc_;
|
||||
|
||||
private:
|
||||
static const size_t MAX_STUBS;
|
||||
void incrementStubCount() {
|
||||
@ -185,7 +189,8 @@ class IonCache
|
||||
stubCount_(0),
|
||||
fallbackLabel_(),
|
||||
script_(nullptr),
|
||||
pc_(nullptr)
|
||||
pc_(nullptr),
|
||||
profilerLeavePc_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@ -201,6 +206,11 @@ class IonCache
|
||||
fallbackLabel_ = fallbackLabel;
|
||||
}
|
||||
|
||||
void setProfilerLeavePC(jsbytecode *pc) {
|
||||
JS_ASSERT(pc != nullptr);
|
||||
profilerLeavePc_ = pc;
|
||||
}
|
||||
|
||||
virtual void emitInitialJump(MacroAssembler &masm, AddCacheState &addState) = 0;
|
||||
virtual void bindInitialJump(MacroAssembler &masm, AddCacheState &addState) = 0;
|
||||
virtual void updateBaseAddress(JitCode *code, MacroAssembler &masm);
|
||||
@ -614,24 +624,24 @@ class GetPropertyIC : public RepatchIonCache
|
||||
}
|
||||
|
||||
// Attach the proper stub, if possible
|
||||
bool tryAttachStub(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
bool tryAttachStub(JSContext *cx, JSScript *topScript, IonScript *ion, HandleObject obj,
|
||||
HandlePropertyName name, void *returnAddr, bool *emitted);
|
||||
bool tryAttachProxy(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
bool tryAttachProxy(JSContext *cx, JSScript *topScript, IonScript *ion, HandleObject obj,
|
||||
HandlePropertyName name, void *returnAddr, bool *emitted);
|
||||
bool tryAttachGenericProxy(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
bool tryAttachGenericProxy(JSContext *cx, JSScript *topScript, 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,
|
||||
HandlePropertyName name, bool resetNeeded,
|
||||
bool tryAttachDOMProxyShadowed(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
HandleObject obj, void *returnAddr, bool *emitted);
|
||||
bool tryAttachDOMProxyUnshadowed(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
HandleObject obj, HandlePropertyName name, bool resetNeeded,
|
||||
void *returnAddr, bool *emitted);
|
||||
bool tryAttachNative(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
bool tryAttachNative(JSContext *cx, JSScript *topScript, IonScript *ion, HandleObject obj,
|
||||
HandlePropertyName name, void *returnAddr, bool *emitted);
|
||||
bool tryAttachTypedArrayLength(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
HandlePropertyName name, bool *emitted);
|
||||
bool tryAttachTypedArrayLength(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
HandleObject obj, HandlePropertyName name, bool *emitted);
|
||||
|
||||
bool tryAttachArgumentsLength(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
HandlePropertyName name, bool *emitted);
|
||||
bool tryAttachArgumentsLength(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
HandleObject obj, HandlePropertyName name, bool *emitted);
|
||||
|
||||
static bool update(JSContext *cx, size_t cacheIndex, HandleObject obj, MutableHandleValue vp);
|
||||
};
|
||||
@ -694,17 +704,17 @@ class SetPropertyIC : public RepatchIonCache
|
||||
CanAttachCallSetter
|
||||
};
|
||||
|
||||
bool attachSetSlot(JSContext *cx, IonScript *ion, HandleObject obj, HandleShape shape,
|
||||
bool checkTypeset);
|
||||
bool attachCallSetter(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
bool attachSetSlot(JSContext *cx, JSScript *topScript, IonScript *ion, HandleObject obj,
|
||||
HandleShape shape, bool checkTypeset);
|
||||
bool attachCallSetter(JSContext *cx, JSScript *topScript, IonScript *ion, HandleObject obj,
|
||||
HandleObject holder, HandleShape shape, void *returnAddr);
|
||||
bool attachAddSlot(JSContext *cx, IonScript *ion, JSObject *obj, HandleShape oldShape,
|
||||
bool checkTypeset);
|
||||
bool attachGenericProxy(JSContext *cx, IonScript *ion, void *returnAddr);
|
||||
bool attachDOMProxyShadowed(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
void *returnAddr);
|
||||
bool attachDOMProxyUnshadowed(JSContext *cx, IonScript *ion, HandleObject obj,
|
||||
void *returnAddr);
|
||||
bool attachAddSlot(JSContext *cx, JSScript *topScript, IonScript *ion, JSObject *obj,
|
||||
HandleShape oldShape, bool checkTypeset);
|
||||
bool attachGenericProxy(JSContext *cx, JSScript *topScript, IonScript *ion, void *returnAddr);
|
||||
bool attachDOMProxyShadowed(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
HandleObject obj, void *returnAddr);
|
||||
bool attachDOMProxyUnshadowed(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
HandleObject obj, void *returnAddr);
|
||||
|
||||
static bool
|
||||
update(JSContext *cx, size_t cacheIndex, HandleObject obj, HandleValue value);
|
||||
@ -788,12 +798,13 @@ 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, void *returnAddr);
|
||||
bool attachDenseElement(JSContext *cx, IonScript *ion, JSObject *obj, const Value &idval);
|
||||
bool attachTypedArrayElement(JSContext *cx, IonScript *ion, TypedArrayObject *tarr,
|
||||
const Value &idval);
|
||||
bool attachArgumentsElement(JSContext *cx, IonScript *ion, JSObject *obj);
|
||||
bool attachGetProp(JSContext *cx, JSScript *topScript, IonScript *ion, HandleObject obj,
|
||||
const Value &idval, HandlePropertyName name, void *returnAddr);
|
||||
bool attachDenseElement(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
JSObject *obj, const Value &idval);
|
||||
bool attachTypedArrayElement(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
TypedArrayObject *tarr, const Value &idval);
|
||||
bool attachArgumentsElement(JSContext *cx, JSScript *topScript, IonScript *ion, JSObject *obj);
|
||||
|
||||
static bool
|
||||
update(JSContext *cx, size_t cacheIndex, HandleObject obj, HandleValue idval,
|
||||
@ -878,8 +889,10 @@ class SetElementIC : public RepatchIonCache
|
||||
hasDenseStub_ = true;
|
||||
}
|
||||
|
||||
bool attachDenseElement(JSContext *cx, IonScript *ion, JSObject *obj, const Value &idval);
|
||||
bool attachTypedArrayElement(JSContext *cx, IonScript *ion, TypedArrayObject *tarr);
|
||||
bool attachDenseElement(JSContext *cx, JSScript *topScript, IonScript *ion, JSObject *obj,
|
||||
const Value &idval);
|
||||
bool attachTypedArrayElement(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
TypedArrayObject *tarr);
|
||||
|
||||
static bool
|
||||
update(JSContext *cx, size_t cacheIndex, HandleObject obj, HandleValue idval,
|
||||
@ -913,8 +926,9 @@ class BindNameIC : public RepatchIonCache
|
||||
return output_;
|
||||
}
|
||||
|
||||
bool attachGlobal(JSContext *cx, IonScript *ion, JSObject *scopeChain);
|
||||
bool attachNonGlobal(JSContext *cx, IonScript *ion, JSObject *scopeChain, JSObject *holder);
|
||||
bool attachGlobal(JSContext *cx, JSScript *topScript, IonScript *ion, JSObject *scopeChain);
|
||||
bool attachNonGlobal(JSContext *cx, JSScript *topScript, IonScript *ion, JSObject *scopeChain,
|
||||
JSObject *holder);
|
||||
|
||||
static JSObject *
|
||||
update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain);
|
||||
@ -959,10 +973,10 @@ class NameIC : public RepatchIonCache
|
||||
return typeOf_;
|
||||
}
|
||||
|
||||
bool attachReadSlot(JSContext *cx, IonScript *ion, HandleObject scopeChain,
|
||||
bool attachReadSlot(JSContext *cx, JSScript *topScript, IonScript *ion, HandleObject scopeChain,
|
||||
HandleObject holderBase, HandleObject holder, HandleShape shape);
|
||||
bool attachCallGetter(JSContext *cx, IonScript *ion, JSObject *obj, JSObject *holder,
|
||||
HandleShape shape, void *returnAddr);
|
||||
bool attachCallGetter(JSContext *cx, JSScript *topScript, IonScript *ion, JSObject *obj,
|
||||
JSObject *holder, HandleShape shape, void *returnAddr);
|
||||
|
||||
static bool
|
||||
update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain, MutableHandleValue vp);
|
||||
@ -1000,7 +1014,8 @@ class CallsiteCloneIC : public RepatchIonCache
|
||||
return output_;
|
||||
}
|
||||
|
||||
bool attach(JSContext *cx, IonScript *ion, HandleFunction original, HandleFunction clone);
|
||||
bool attach(JSContext *cx, JSScript *topScript, IonScript *ion,
|
||||
HandleFunction original, HandleFunction clone);
|
||||
|
||||
static JSObject *update(JSContext *cx, size_t cacheIndex, HandleObject callee);
|
||||
};
|
||||
|
@ -378,13 +378,34 @@ class MDefinition : public MNode
|
||||
const BytecodeSite &trackedSite() const {
|
||||
return trackedSite_;
|
||||
}
|
||||
jsbytecode *trackedPc() {
|
||||
jsbytecode *trackedPc() const {
|
||||
return trackedSite_.pc();
|
||||
}
|
||||
InlineScriptTree *trackedTree() {
|
||||
InlineScriptTree *trackedTree() const {
|
||||
return trackedSite_.tree();
|
||||
}
|
||||
|
||||
JSScript *profilerLeaveScript() const {
|
||||
return trackedTree()->outermostCaller()->script();
|
||||
}
|
||||
|
||||
jsbytecode *profilerLeavePc() const {
|
||||
// If this is in a top-level function, use the pc directly.
|
||||
if (trackedTree()->isOutermostCaller())
|
||||
return trackedPc();
|
||||
|
||||
// Walk up the InlineScriptTree chain to find the top-most callPC
|
||||
InlineScriptTree *curTree = trackedTree();
|
||||
InlineScriptTree *callerTree = curTree->caller();
|
||||
while (!callerTree->isOutermostCaller()) {
|
||||
curTree = callerTree;
|
||||
callerTree = curTree->caller();
|
||||
}
|
||||
|
||||
// Return the callPc of the topmost inlined script.
|
||||
return curTree->callerPc();
|
||||
}
|
||||
|
||||
// Return the range of this value, *before* any bailout checks. Contrast
|
||||
// this with the type() method, and the Range constructor which takes an
|
||||
// MDefinition*, which describe the value *after* any bailout checks.
|
||||
|
Loading…
Reference in New Issue
Block a user