diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index e2dc2dc36df..fd24e5576d6 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -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 &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, DataPtrinfo().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); diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index c47c3861f61..56004018379 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -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); diff --git a/js/src/jit/CompileInfo.h b/js/src/jit/CompileInfo.h index de077a793e0..39a3e8a94c5 100644 --- a/js/src/jit/CompileInfo.h +++ b/js/src/jit/CompileInfo.h @@ -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_; } diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index 6083da8c8ef..cf1e589e620 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -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()); 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 tarr(cx, &obj->as()); - 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(); - 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()); - 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()) { - 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; } diff --git a/js/src/jit/IonCaches.h b/js/src/jit/IonCaches.h index 62127570250..820fd1db2dd 100644 --- a/js/src/jit/IonCaches.h +++ b/js/src/jit/IonCaches.h @@ -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); }; diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 72b91d897f3..530afb6398f 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -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.