mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1070962 part 4 - JitFrameIterator use BailoutData when it starts on a bailout frame. r=jandem
This commit is contained in:
parent
bf282ccb9b
commit
85d9fdb3b3
@ -2702,9 +2702,16 @@ InvalidateActivation(FreeOp *fop, const JitActivationIterator &activations, bool
|
||||
break;
|
||||
case JitFrame_BaselineJS:
|
||||
case JitFrame_IonJS:
|
||||
case JitFrame_Bailout:
|
||||
{
|
||||
MOZ_ASSERT(it.isScripted());
|
||||
const char *type = it.isIonJS() ? "Optimized" : "Baseline";
|
||||
const char *type = "Unknown";
|
||||
if (it.isIonJS())
|
||||
type = "Optimized";
|
||||
else if (it.isBaselineJS())
|
||||
type = "Baseline";
|
||||
else if (it.isBailoutJS())
|
||||
type = "Bailing";
|
||||
JitSpew(JitSpew_IonInvalidate, "#%d %s JS frame @ %p, %s:%d (fun: %p, script: %p, pc %p)",
|
||||
frameno, type, it.fp(), it.script()->filename(), it.script()->lineno(),
|
||||
it.maybeCallee(), (JSScript *)it.script(), it.returnAddressToFp());
|
||||
|
@ -102,6 +102,10 @@ JitFrameIterator::JitFrameIterator(ThreadSafeContext *cx)
|
||||
cachedSafepointIndex_(nullptr),
|
||||
activation_(cx->perThreadData->activation()->asJit())
|
||||
{
|
||||
if (activation_->bailoutData()) {
|
||||
current_ = activation_->bailoutData()->fp();
|
||||
type_ = JitFrame_Bailout;
|
||||
}
|
||||
}
|
||||
|
||||
JitFrameIterator::JitFrameIterator(const ActivationIterator &activations)
|
||||
@ -115,6 +119,10 @@ JitFrameIterator::JitFrameIterator(const ActivationIterator &activations)
|
||||
cachedSafepointIndex_(nullptr),
|
||||
activation_(activations->asJit())
|
||||
{
|
||||
if (activation_->bailoutData()) {
|
||||
current_ = activation_->bailoutData()->fp();
|
||||
type_ = JitFrame_Bailout;
|
||||
}
|
||||
}
|
||||
|
||||
IonBailoutIterator *
|
||||
@ -275,6 +283,7 @@ SizeOfFramePrefix(FrameType type)
|
||||
return IonEntryFrameLayout::Size();
|
||||
case JitFrame_BaselineJS:
|
||||
case JitFrame_IonJS:
|
||||
case JitFrame_Bailout:
|
||||
case JitFrame_Unwound_IonJS:
|
||||
return IonJSFrameLayout::Size();
|
||||
case JitFrame_BaselineStub:
|
||||
@ -339,6 +348,8 @@ JitFrameIterator::operator++()
|
||||
uintptr_t *
|
||||
JitFrameIterator::spillBase() const
|
||||
{
|
||||
MOZ_ASSERT(isIonJS());
|
||||
|
||||
// Get the base address to where safepoint registers are spilled.
|
||||
// Out-of-line calls do not unwind the extra padding space used to
|
||||
// aggregate bailout tables, so we use frameSize instead of frameLocals,
|
||||
@ -349,6 +360,12 @@ JitFrameIterator::spillBase() const
|
||||
MachineState
|
||||
JitFrameIterator::machineState() const
|
||||
{
|
||||
MOZ_ASSERT(isIonScripted());
|
||||
|
||||
// The MachineState is used by GCs for marking call-sites.
|
||||
if (MOZ_UNLIKELY(isBailoutJS()))
|
||||
return activation_->bailoutData()->machineState();
|
||||
|
||||
SafepointReader reader(ionScript(), safepoint());
|
||||
uintptr_t *spill = spillBase();
|
||||
|
||||
@ -1532,7 +1549,7 @@ SnapshotIterator::SnapshotIterator(IonScript *ionScript, SnapshotOffset snapshot
|
||||
|
||||
SnapshotIterator::SnapshotIterator(const JitFrameIterator &iter)
|
||||
: snapshot_(iter.ionScript()->snapshots(),
|
||||
iter.osiIndex()->snapshotOffset(),
|
||||
iter.snapshotOffset(),
|
||||
iter.ionScript()->snapshotsRVATableSize(),
|
||||
iter.ionScript()->snapshotsListSize()),
|
||||
recover_(snapshot_,
|
||||
@ -1916,10 +1933,22 @@ SnapshotIterator::maybeReadAllocByIndex(size_t index)
|
||||
return s;
|
||||
}
|
||||
|
||||
IonJSFrameLayout *
|
||||
JitFrameIterator::jsFrame() const
|
||||
{
|
||||
MOZ_ASSERT(isScripted());
|
||||
if (isBailoutJS())
|
||||
return activation_->bailoutData()->jsFrame();
|
||||
|
||||
return (IonJSFrameLayout *) fp();
|
||||
}
|
||||
|
||||
IonScript *
|
||||
JitFrameIterator::ionScript() const
|
||||
{
|
||||
MOZ_ASSERT(type() == JitFrame_IonJS);
|
||||
MOZ_ASSERT(isIonScripted());
|
||||
if (isBailoutJS())
|
||||
return activation_->bailoutData()->ionScript();
|
||||
|
||||
IonScript *ionScript = nullptr;
|
||||
if (checkInvalidation(&ionScript))
|
||||
@ -1930,7 +1959,7 @@ JitFrameIterator::ionScript() const
|
||||
IonScript *
|
||||
JitFrameIterator::ionScriptFromCalleeToken() const
|
||||
{
|
||||
MOZ_ASSERT(type() == JitFrame_IonJS);
|
||||
MOZ_ASSERT(isIonJS());
|
||||
MOZ_ASSERT(!checkInvalidation());
|
||||
|
||||
switch (mode_) {
|
||||
@ -1946,14 +1975,25 @@ JitFrameIterator::ionScriptFromCalleeToken() const
|
||||
const SafepointIndex *
|
||||
JitFrameIterator::safepoint() const
|
||||
{
|
||||
MOZ_ASSERT(isIonJS());
|
||||
if (!cachedSafepointIndex_)
|
||||
cachedSafepointIndex_ = ionScript()->getSafepointIndex(returnAddressToFp());
|
||||
return cachedSafepointIndex_;
|
||||
}
|
||||
|
||||
SnapshotOffset
|
||||
JitFrameIterator::snapshotOffset() const
|
||||
{
|
||||
MOZ_ASSERT(isIonScripted());
|
||||
if (isBailoutJS())
|
||||
return activation_->bailoutData()->snapshotOffset();
|
||||
return osiIndex()->snapshotOffset();
|
||||
}
|
||||
|
||||
const OsiIndex *
|
||||
JitFrameIterator::osiIndex() const
|
||||
{
|
||||
MOZ_ASSERT(isIonJS());
|
||||
SafepointReader reader(ionScript(), safepoint());
|
||||
return ionScript()->getOsiIndex(reader.osiReturnPointOffset());
|
||||
}
|
||||
@ -2335,6 +2375,7 @@ JitFrameIterator::dump() const
|
||||
fprintf(stderr, " Baseline stub frame\n");
|
||||
fprintf(stderr, " Frame size: %u\n", unsigned(current()->prevFrameLocalSize()));
|
||||
break;
|
||||
case JitFrame_Bailout:
|
||||
case JitFrame_IonJS:
|
||||
{
|
||||
InlineFrameIterator frames(GetJSContextFromJitCode(), this);
|
||||
|
@ -57,7 +57,13 @@ enum FrameType
|
||||
// An exit frame is necessary for transitioning from a JS frame into C++.
|
||||
// From within C++, an exit frame is always the last frame in any
|
||||
// JitActivation.
|
||||
JitFrame_Exit
|
||||
JitFrame_Exit,
|
||||
|
||||
// A bailout frame is a special IonJS jit frame after a bailout, and before
|
||||
// the reconstruction of the BaselineJS frame. From within C++, a bailout
|
||||
// frame is always the last frame in a JitActivation iff the bailout frame
|
||||
// information is recorded on the JitActivation.
|
||||
JitFrame_Bailout
|
||||
};
|
||||
|
||||
enum ReadFrameArgsBehavior {
|
||||
@ -127,10 +133,9 @@ class JitFrameIterator
|
||||
|
||||
inline uint8_t *returnAddress() const;
|
||||
|
||||
IonJSFrameLayout *jsFrame() const {
|
||||
MOZ_ASSERT(isScripted());
|
||||
return (IonJSFrameLayout *) fp();
|
||||
}
|
||||
// Return the pointer of the JitFrame, the iterator is assumed to be settled
|
||||
// on a scripted frame.
|
||||
IonJSFrameLayout *jsFrame() const;
|
||||
|
||||
// Returns true iff this exit frame was created using EnsureExitFrame.
|
||||
inline bool isFakeExitFrame() const;
|
||||
@ -143,14 +148,20 @@ class JitFrameIterator
|
||||
bool checkInvalidation() const;
|
||||
|
||||
bool isScripted() const {
|
||||
return type_ == JitFrame_BaselineJS || type_ == JitFrame_IonJS;
|
||||
return type_ == JitFrame_BaselineJS || type_ == JitFrame_IonJS || type_ == JitFrame_Bailout;
|
||||
}
|
||||
bool isBaselineJS() const {
|
||||
return type_ == JitFrame_BaselineJS;
|
||||
}
|
||||
bool isIonScripted() const {
|
||||
return type_ == JitFrame_IonJS || type_ == JitFrame_Bailout;
|
||||
}
|
||||
bool isIonJS() const {
|
||||
return type_ == JitFrame_IonJS;
|
||||
}
|
||||
bool isBailoutJS() const {
|
||||
return type_ == JitFrame_Bailout;
|
||||
}
|
||||
bool isBaselineStub() const {
|
||||
return type_ == JitFrame_BaselineStub;
|
||||
}
|
||||
@ -216,6 +227,10 @@ class JitFrameIterator
|
||||
// overhead.
|
||||
const OsiIndex *osiIndex() const;
|
||||
|
||||
// Returns the Snapshot offset associated with this JS frame. Incurs a
|
||||
// lookup overhead.
|
||||
SnapshotOffset snapshotOffset() const;
|
||||
|
||||
uintptr_t *spillBase() const;
|
||||
MachineState machineState() const;
|
||||
|
||||
|
@ -351,6 +351,15 @@ FrameIter::unaliasedForEachActual(JSContext *cx, Op op)
|
||||
if (data_.jitFrames_.isIonJS()) {
|
||||
jit::MaybeReadFallback recover(cx, activation()->asJit(), &data_.jitFrames_);
|
||||
ionInlineFrames_.unaliasedForEachActual(cx, op, jit::ReadFrame_Actuals, recover);
|
||||
} else if (data_.jitFrames_.isBailoutJS()) {
|
||||
// :TODO: (Bug 1070962) If we are introspecting the frame which is
|
||||
// being bailed, then we might be in the middle of recovering
|
||||
// instructions. Stacking computeInstructionResults implies that we
|
||||
// might be recovering result twice. In the mean time, to avoid
|
||||
// that, we just return Undefined values for instruction results
|
||||
// which are not yet recovered.
|
||||
jit::MaybeReadFallback fallback;
|
||||
ionInlineFrames_.unaliasedForEachActual(cx, op, jit::ReadFrame_Actuals, fallback);
|
||||
} else {
|
||||
MOZ_ASSERT(data_.jitFrames_.isBaselineJS());
|
||||
data_.jitFrames_.unaliasedForEachActual(op, jit::ReadFrame_Actuals);
|
||||
|
@ -679,17 +679,17 @@ FrameIter::FrameIter(JSContext *cx, ContextOption contextOption,
|
||||
FrameIter::FrameIter(const FrameIter &other)
|
||||
: data_(other.data_),
|
||||
ionInlineFrames_(other.data_.cx_,
|
||||
data_.jitFrames_.isIonJS() ? &other.ionInlineFrames_ : nullptr)
|
||||
data_.jitFrames_.isIonScripted() ? &other.ionInlineFrames_ : nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
FrameIter::FrameIter(const Data &data)
|
||||
: data_(data),
|
||||
ionInlineFrames_(data.cx_, data_.jitFrames_.isIonJS() ? &data_.jitFrames_ : nullptr)
|
||||
ionInlineFrames_(data.cx_, data_.jitFrames_.isIonScripted() ? &data_.jitFrames_ : nullptr)
|
||||
{
|
||||
MOZ_ASSERT(data.cx_);
|
||||
|
||||
if (data_.jitFrames_.isIonJS()) {
|
||||
if (data_.jitFrames_.isIonScripted()) {
|
||||
while (ionInlineFrames_.frameNo() != data.ionInlineFrameNo_)
|
||||
++ionInlineFrames_;
|
||||
}
|
||||
@ -698,7 +698,7 @@ FrameIter::FrameIter(const Data &data)
|
||||
void
|
||||
FrameIter::nextJitFrame()
|
||||
{
|
||||
if (data_.jitFrames_.isIonJS()) {
|
||||
if (data_.jitFrames_.isIonScripted()) {
|
||||
ionInlineFrames_.resetOn(&data_.jitFrames_);
|
||||
data_.pc_ = ionInlineFrames_.pc();
|
||||
} else {
|
||||
@ -712,7 +712,7 @@ FrameIter::popJitFrame()
|
||||
{
|
||||
MOZ_ASSERT(data_.state_ == JIT);
|
||||
|
||||
if (data_.jitFrames_.isIonJS() && ionInlineFrames_.more()) {
|
||||
if (data_.jitFrames_.isIonScripted() && ionInlineFrames_.more()) {
|
||||
++ionInlineFrames_;
|
||||
data_.pc_ = ionInlineFrames_.pc();
|
||||
return;
|
||||
@ -789,7 +789,7 @@ FrameIter::copyData() const
|
||||
{
|
||||
Data *data = data_.cx_->new_<Data>(data_);
|
||||
MOZ_ASSERT(data_.state_ != ASMJS);
|
||||
if (data && data_.jitFrames_.isIonJS())
|
||||
if (data && data_.jitFrames_.isIonScripted())
|
||||
data->ionInlineFrameNo_ = ionInlineFrames_.frameNo();
|
||||
return data;
|
||||
}
|
||||
@ -997,7 +997,7 @@ FrameIter::isConstructing() const
|
||||
case ASMJS:
|
||||
break;
|
||||
case JIT:
|
||||
if (data_.jitFrames_.isIonJS())
|
||||
if (data_.jitFrames_.isIonScripted())
|
||||
return ionInlineFrames_.isConstructing();
|
||||
MOZ_ASSERT(data_.jitFrames_.isBaselineJS());
|
||||
return data_.jitFrames_.isConstructing();
|
||||
@ -1026,7 +1026,7 @@ FrameIter::hasUsableAbstractFramePtr() const
|
||||
if (data_.jitFrames_.isBaselineJS())
|
||||
return true;
|
||||
|
||||
MOZ_ASSERT(data_.jitFrames_.isIonJS());
|
||||
MOZ_ASSERT(data_.jitFrames_.isIonScripted());
|
||||
return !!activation()->asJit()->lookupRematerializedFrame(data_.jitFrames_.fp(),
|
||||
ionInlineFrames_.frameNo());
|
||||
break;
|
||||
@ -1048,7 +1048,7 @@ FrameIter::abstractFramePtr() const
|
||||
if (data_.jitFrames_.isBaselineJS())
|
||||
return data_.jitFrames_.baselineFrame();
|
||||
|
||||
MOZ_ASSERT(data_.jitFrames_.isIonJS());
|
||||
MOZ_ASSERT(data_.jitFrames_.isIonScripted());
|
||||
return activation()->asJit()->lookupRematerializedFrame(data_.jitFrames_.fp(),
|
||||
ionInlineFrames_.frameNo());
|
||||
break;
|
||||
@ -1120,7 +1120,7 @@ FrameIter::callee() const
|
||||
case JIT:
|
||||
if (data_.jitFrames_.isBaselineJS())
|
||||
return data_.jitFrames_.callee();
|
||||
MOZ_ASSERT(data_.jitFrames_.isIonJS());
|
||||
MOZ_ASSERT(data_.jitFrames_.isIonScripted());
|
||||
return ionInlineFrames_.callee();
|
||||
}
|
||||
MOZ_CRASH("Unexpected state");
|
||||
@ -1153,7 +1153,7 @@ FrameIter::numActualArgs() const
|
||||
MOZ_ASSERT(isFunctionFrame());
|
||||
return interpFrame()->numActualArgs();
|
||||
case JIT:
|
||||
if (data_.jitFrames_.isIonJS())
|
||||
if (data_.jitFrames_.isIonScripted())
|
||||
return ionInlineFrames_.numActualArgs();
|
||||
|
||||
MOZ_ASSERT(data_.jitFrames_.isBaselineJS());
|
||||
@ -1182,7 +1182,7 @@ FrameIter::scopeChain() const
|
||||
case ASMJS:
|
||||
break;
|
||||
case JIT:
|
||||
if (data_.jitFrames_.isIonJS())
|
||||
if (data_.jitFrames_.isIonScripted())
|
||||
return ionInlineFrames_.scopeChain();
|
||||
return data_.jitFrames_.baselineFrame()->scopeChain();
|
||||
case INTERP:
|
||||
@ -1237,7 +1237,7 @@ FrameIter::thisv(JSContext *cx)
|
||||
case ASMJS:
|
||||
break;
|
||||
case JIT:
|
||||
if (data_.jitFrames_.isIonJS()) {
|
||||
if (data_.jitFrames_.isIonScripted()) {
|
||||
jit::MaybeReadFallback recover(cx, activation()->asJit(), &data_.jitFrames_);
|
||||
return ionInlineFrames_.thisValue(recover);
|
||||
}
|
||||
@ -1293,7 +1293,7 @@ FrameIter::numFrameSlots() const
|
||||
case ASMJS:
|
||||
break;
|
||||
case JIT: {
|
||||
if (data_.jitFrames_.isIonJS()) {
|
||||
if (data_.jitFrames_.isIonScripted()) {
|
||||
return ionInlineFrames_.snapshotIterator().numAllocations() -
|
||||
ionInlineFrames_.script()->nfixed();
|
||||
}
|
||||
@ -1315,7 +1315,7 @@ FrameIter::frameSlotValue(size_t index) const
|
||||
case ASMJS:
|
||||
break;
|
||||
case JIT:
|
||||
if (data_.jitFrames_.isIonJS()) {
|
||||
if (data_.jitFrames_.isIonScripted()) {
|
||||
jit::SnapshotIterator si(ionInlineFrames_.snapshotIterator());
|
||||
index += ionInlineFrames_.script()->nfixed();
|
||||
return si.maybeReadAllocByIndex(index);
|
||||
@ -1514,7 +1514,7 @@ jit::JitActivation::getRematerializedFrame(ThreadSafeContext *cx, const T &iter,
|
||||
// Only allow rematerializing from the same thread.
|
||||
MOZ_ASSERT(cx->perThreadData == cx_->perThreadData);
|
||||
MOZ_ASSERT(iter.activation() == this);
|
||||
MOZ_ASSERT(iter.isIonJS());
|
||||
MOZ_ASSERT(iter.isIonScripted());
|
||||
|
||||
if (!rematerializedFrames_) {
|
||||
rematerializedFrames_ = cx->new_<RematerializedFrameTable>(cx);
|
||||
|
@ -1429,6 +1429,9 @@ class JitActivation : public Activation
|
||||
RegisterBailoutIterator(JitActivation &activation, IonBailoutIterator *iter);
|
||||
~RegisterBailoutIterator();
|
||||
};
|
||||
|
||||
// Return the bailout information if it is registered.
|
||||
const IonBailoutIterator *bailoutData() const { return ionBailoutIterator_; }
|
||||
};
|
||||
|
||||
// A filtering of the ActivationIterator to only stop at JitActivations.
|
||||
|
Loading…
Reference in New Issue
Block a user