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:
Kannan Vijayan 2014-05-01 15:45:37 -04:00
parent cb05abe1d6
commit 766eb08622
6 changed files with 221 additions and 144 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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_;
}

View File

@ -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;
}

View File

@ -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);
};

View File

@ -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.