Bug 1062869 part 3 - Add vector of Ion recover info. r=h4writer

This commit is contained in:
Nicolas B. Pierron 2014-09-18 18:28:54 +02:00
parent 789e90ae9e
commit af0dca85b8
5 changed files with 84 additions and 2 deletions

View File

@ -1344,6 +1344,7 @@ jit::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, IonBailoutIt
JitSpew(JitSpew_BaselineBailouts, " Incoming frame ptr = %p", builder.startFrame());
RInstructionResults instructionResults;
activation->maybeTakeIonFrameRecovery(iter.jsFrame(), &instructionResults);
SnapshotIterator snapIter(iter);
if (!snapIter.initInstructionResults(cx, &instructionResults))

View File

@ -1284,6 +1284,7 @@ MarkJitActivation(JSTracer *trc, const JitActivationIterator &activations)
#endif
activation->markRematerializedFrames(trc);
activation->markIonRecovery(trc);
for (JitFrameIterator frames(activations); !frames.done(); ++frames) {
switch (frames.type()) {
@ -1503,6 +1504,12 @@ RInstructionResults::operator [](size_t index)
return results_.get()[index];
}
void
RInstructionResults::trace(JSTracer *trc)
{
gc::MarkValueRange(trc, len_, results_.get(), "ion-recover-results");
}
SnapshotIterator::SnapshotIterator(IonScript *ionScript, SnapshotOffset snapshotOffset,
IonJSFrameLayout *fp, const MachineState &machine)

View File

@ -292,6 +292,8 @@ class RInstructionResults
IonJSFrameLayout *frame() const;
HeapValue& operator[](size_t index);
void trace(JSTracer *trc);
};
class RResumePoint;

View File

@ -1401,7 +1401,8 @@ js::CheckLocalUnaliased(MaybeCheckAliasing checkAliasing, JSScript *script, uint
jit::JitActivation::JitActivation(JSContext *cx, bool active)
: Activation(cx, Jit),
active_(active),
rematerializedFrames_(nullptr)
rematerializedFrames_(nullptr),
ionRecovery_(cx)
{
if (active) {
prevJitTop_ = cx->mainThread().jitTop;
@ -1416,7 +1417,8 @@ jit::JitActivation::JitActivation(JSContext *cx, bool active)
jit::JitActivation::JitActivation(ForkJoinContext *cx)
: Activation(cx, Jit),
active_(true),
rematerializedFrames_(nullptr)
rematerializedFrames_(nullptr),
ionRecovery_(cx)
{
prevJitTop_ = cx->perThreadData->jitTop;
prevJitJSContext_ = cx->perThreadData->jitJSContext;
@ -1431,6 +1433,8 @@ jit::JitActivation::~JitActivation()
}
clearRematerializedFrames();
// All reocvered value are taken from activation during the bailout.
MOZ_ASSERT(ionRecovery_.empty());
js_delete(rematerializedFrames_);
}
@ -1545,6 +1549,50 @@ jit::JitActivation::markRematerializedFrames(JSTracer *trc)
RematerializedFrame::MarkInVector(trc, e.front().value());
}
bool
jit::JitActivation::registerIonFrameRecovery(IonJSFrameLayout *fp, RInstructionResults&& results)
{
#ifdef DEBUG
// Check that there is no entry in the vector yet.
RInstructionResults *tmp = maybeIonFrameRecovery(fp);
MOZ_ASSERT_IF(tmp, tmp->isInitialized());
#endif
if (!ionRecovery_.append(mozilla::Move(results)))
return false;
return true;
}
jit::RInstructionResults *
jit::JitActivation::maybeIonFrameRecovery(IonJSFrameLayout *fp)
{
for (RInstructionResults *it = ionRecovery_.begin(); it != ionRecovery_.end(); ) {
if (it->frame() == fp)
return it;
}
return nullptr;
}
void
jit::JitActivation::maybeTakeIonFrameRecovery(IonJSFrameLayout *fp, RInstructionResults *results)
{
RInstructionResults *elem = maybeIonFrameRecovery(fp);
if (!elem)
return;
*results = mozilla::Move(*elem);
ionRecovery_.erase(elem);
}
void
jit::JitActivation::markIonRecovery(JSTracer *trc)
{
for (RInstructionResults *it = ionRecovery_.begin(); it != ionRecovery_.end(); it++)
it->trace(trc);
}
AsmJSActivation::AsmJSActivation(JSContext *cx, AsmJSModule &module)
: Activation(cx, AsmJS),
module_(module),

View File

@ -1318,6 +1318,16 @@ class JitActivation : public Activation
typedef HashMap<uint8_t *, RematerializedFrameVector> RematerializedFrameTable;
RematerializedFrameTable *rematerializedFrames_;
// This vector is used to remember the outcome of the evaluation of recover
// instructions.
//
// RInstructionResults are appended into this vector when Snapshot values
// have to be read, or when the evaluation has to run before some mutating
// code. Each RInstructionResults belongs to one frame which has to bailout
// as soon as we get back to it.
typedef Vector<RInstructionResults, 1> IonRecoveryMap;
IonRecoveryMap ionRecovery_;
void clearRematerializedFrames();
#ifdef CHECK_OSIPOINT_REGISTERS
@ -1392,6 +1402,20 @@ class JitActivation : public Activation
void removeRematerializedFrame(uint8_t *top);
void markRematerializedFrames(JSTracer *trc);
// Register the results of on Ion frame recovery.
bool registerIonFrameRecovery(IonJSFrameLayout *fp, RInstructionResults&& results);
// Return the pointer to the Ion frame recovery, if it is already registered.
RInstructionResults *maybeIonFrameRecovery(IonJSFrameLayout *fp);
// If an Ion frame recovery exists for the |fp| frame exists on the
// activation, then move its content to the |results| argument, and remove
// it from the activation.
void maybeTakeIonFrameRecovery(IonJSFrameLayout *fp, RInstructionResults *results);
void markIonRecovery(JSTracer *trc);
};
// A filtering of the ActivationIterator to only stop at JitActivations.