Bug 989930 - Convert from reading frames to reading instructions. r=h4writer

This commit is contained in:
Nicolas B. Pierron 2014-04-08 07:21:19 -07:00
Родитель cc25031e47
Коммит 69a01a96c8
5 изменённых файлов: 93 добавлений и 39 удалений

Просмотреть файл

@ -10,6 +10,7 @@
#include "jit/BaselineJIT.h"
#include "jit/CompileInfo.h"
#include "jit/IonSpewer.h"
#include "jit/Recover.h"
#include "vm/ArgumentsObject.h"
#include "jsscriptinlines.h"
@ -1348,6 +1349,8 @@ jit::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, IonBailoutIt
jsbytecode *topCallerPC = nullptr;
while (true) {
MOZ_ASSERT(snapIter.instruction()->isResumePoint());
#if JS_TRACE_LOGGING
if (frameNo > 0) {
TraceLogging::defaultLogger()->log(TraceLogging::SCRIPT_START, scr);
@ -1383,7 +1386,6 @@ jit::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, IonBailoutIt
callerPC = callPC;
fun = nextCallee;
scr = fun->existingScript();
snapIter.nextFrame();
// Save top caller info for adjusting SPS frames later.
if (!topCaller) {
@ -1393,6 +1395,8 @@ jit::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, IonBailoutIt
}
frameNo++;
snapIter.nextInstruction();
}
IonSpew(IonSpew_BaselineBailouts, " Done restoring frames");

Просмотреть файл

@ -289,7 +289,7 @@ class SnapshotIterator
return snapshot_.readAllocation();
}
Value skip() {
readAllocation();
snapshot_.skipAllocation();
return UndefinedValue();
}
@ -319,17 +319,30 @@ class SnapshotIterator
}
public:
// Handle iterating over frames of the snapshots.
inline void nextFrame() {
JS_ASSERT(snapshot_.numAllocationsRead() == numAllocations());
recover_.nextFrame();
// Read the next instruction available and get ready to either skip it or
// evaluate it.
inline void nextInstruction() {
MOZ_ASSERT(snapshot_.numAllocationsRead() == numAllocations());
recover_.nextInstruction();
snapshot_.resetNumAllocationsRead();
}
inline bool moreFrames() const {
return recover_.moreFrames();
// Skip an Instruction by walking to the next instruction and by skipping
// all the allocations corresponding to this instruction.
void skipInstruction();
inline bool moreInstructions() const {
return recover_.moreInstructions();
}
inline uint32_t frameCount() const {
return recover_.frameCount();
public:
// Handle iterating over frames of the snapshots.
void nextFrame();
inline bool moreFrames() const {
// The last instruction is recovering the innermost frame, so as long as
// there is more instruction there is necesseray more frames.
return moreInstructions();
}
public:

Просмотреть файл

@ -1517,6 +1517,24 @@ SnapshotIterator::pcOffset() const
return resumePoint()->pcOffset();
}
void
SnapshotIterator::skipInstruction()
{
MOZ_ASSERT(snapshot_.numAllocationsRead() == 0);
size_t numOperands = instruction()->numOperands();
for (size_t i = 0; i < numOperands; i++)
skip();
nextInstruction();
}
void
SnapshotIterator::nextFrame()
{
nextInstruction();
while (!instruction()->isResumePoint())
skipInstruction();
}
IonScript *
IonFrameIterator::ionScript() const
{
@ -1573,9 +1591,15 @@ InlineFrameIteratorMaybeGC<allowGC>::findNextFrame()
si_ = start_;
// Read the initial frame.
// Read the initial frame out of the C stack.
callee_ = frame_->maybeCallee();
script_ = frame_->script();
// Settle on the outermost frame without evaluating any instructions before
// looking for a pc.
if (!si_.instruction()->isResumePoint())
si_.nextFrame();
pc_ = script_->offsetToPC(si_.pcOffset());
#ifdef DEBUG
numActualArgs_ = 0xbadbad;
@ -1613,6 +1637,7 @@ InlineFrameIteratorMaybeGC<allowGC>::findNextFrame()
for (unsigned j = 0; j < skipCount; j++)
si_.skip();
// The JSFunction is a constant, otherwise we would not have inlined it.
Value funval = si_.read();
// Skip extra value allocations.

Просмотреть файл

@ -482,9 +482,9 @@ static const uint32_t RECOVER_RESUMEAFTER_SHIFT = 0;
static const uint32_t RECOVER_RESUMEAFTER_BITS = 1;
static const uint32_t RECOVER_RESUMEAFTER_MASK = COMPUTE_MASK_(RECOVER_RESUMEAFTER);
static const uint32_t RECOVER_FRAMECOUNT_SHIFT = COMPUTE_SHIFT_AFTER_(RECOVER_RESUMEAFTER);
static const uint32_t RECOVER_FRAMECOUNT_BITS = 32 - RECOVER_FRAMECOUNT_SHIFT;
static const uint32_t RECOVER_FRAMECOUNT_MASK = COMPUTE_MASK_(RECOVER_FRAMECOUNT);
static const uint32_t RECOVER_RINSCOUNT_SHIFT = COMPUTE_SHIFT_AFTER_(RECOVER_RESUMEAFTER);
static const uint32_t RECOVER_RINSCOUNT_BITS = 32 - RECOVER_RINSCOUNT_SHIFT;
static const uint32_t RECOVER_RINSCOUNT_MASK = COMPUTE_MASK_(RECOVER_RINSCOUNT);
#undef COMPUTE_MASK_
#undef COMPUTE_SHIFT_AFTER_
@ -531,13 +531,18 @@ SnapshotReader::spewBailingFrom() const
}
#endif
uint32_t
SnapshotReader::readAllocationIndex()
{
allocRead_++;
return reader_.readUnsigned();
}
RValueAllocation
SnapshotReader::readAllocation()
{
IonSpew(IonSpew_Snapshots, "Reading slot %u", allocRead_);
allocRead_++;
uint32_t offset = reader_.readUnsigned() * ALLOCATION_TABLE_ALIGNMENT;
uint32_t offset = readAllocationIndex() * ALLOCATION_TABLE_ALIGNMENT;
allocReader_.seek(allocTable_, offset);
return RValueAllocation::read(allocReader_);
}
@ -553,14 +558,14 @@ SnapshotWriter::init()
RecoverReader::RecoverReader(SnapshotReader &snapshot, const uint8_t *recovers, uint32_t size)
: reader_(nullptr, nullptr),
frameCount_(0),
framesRead_(0)
numInstructions_(0),
numInstructionsRead_(0)
{
if (!recovers)
return;
reader_ = CompactBufferReader(recovers + snapshot.recoverOffset(), recovers + size);
readRecoverHeader();
readFrame();
readInstruction();
}
void
@ -568,20 +573,20 @@ RecoverReader::readRecoverHeader()
{
uint32_t bits = reader_.readUnsigned();
frameCount_ = (bits & RECOVER_FRAMECOUNT_MASK) >> RECOVER_FRAMECOUNT_SHIFT;
numInstructions_ = (bits & RECOVER_RINSCOUNT_MASK) >> RECOVER_RINSCOUNT_SHIFT;
resumeAfter_ = (bits & RECOVER_RESUMEAFTER_MASK) >> RECOVER_RESUMEAFTER_SHIFT;
JS_ASSERT(frameCount_);
MOZ_ASSERT(numInstructions_);
IonSpew(IonSpew_Snapshots, "Read recover header with frameCount %u (ra: %d)",
frameCount_, resumeAfter_);
IonSpew(IonSpew_Snapshots, "Read recover header with instructionCount %u (ra: %d)",
numInstructions_, resumeAfter_);
}
void
RecoverReader::readFrame()
RecoverReader::readInstruction()
{
JS_ASSERT(moreFrames());
MOZ_ASSERT(moreInstructions());
RInstruction::readRecoverData(reader_, &rawData_);
framesRead_++;
numInstructionsRead_++;
}
SnapshotOffset
@ -667,10 +672,10 @@ RecoverWriter::startRecover(uint32_t frameCount, bool resumeAfter)
frameCount);
MOZ_ASSERT(!(uint32_t(resumeAfter) &~ RECOVER_RESUMEAFTER_MASK));
MOZ_ASSERT(frameCount < uint32_t(1 << RECOVER_FRAMECOUNT_BITS));
MOZ_ASSERT(frameCount < uint32_t(1 << RECOVER_RINSCOUNT_BITS));
uint32_t bits =
(uint32_t(resumeAfter) << RECOVER_RESUMEAFTER_SHIFT) |
(frameCount << RECOVER_FRAMECOUNT_SHIFT);
(frameCount << RECOVER_RINSCOUNT_SHIFT);
RecoverOffset recoverOffset = writer_.length();
writer_.writeUnsigned(bits);

Просмотреть файл

@ -419,12 +419,16 @@ class SnapshotReader
private:
void readSnapshotHeader();
uint32_t readAllocationIndex();
public:
SnapshotReader(const uint8_t *snapshots, uint32_t offset,
uint32_t RVATableSize, uint32_t listSize);
RValueAllocation readAllocation();
void skipAllocation() {
readAllocationIndex();
}
BailoutKind bailoutKind() const {
return bailoutKind_;
@ -448,8 +452,14 @@ class RecoverReader
{
CompactBufferReader reader_;
uint32_t frameCount_;
uint32_t framesRead_; // Number of frame headers that have been read.
// Number of encoded instructions.
uint32_t numInstructions_;
// Number of instruction read.
uint32_t numInstructionsRead_;
// True if we need to resume after the Resume Point instruction of the
// innermost frame.
bool resumeAfter_;
// Space is reserved as part of the RecoverReader to avoid allocations of
@ -458,19 +468,16 @@ class RecoverReader
private:
void readRecoverHeader();
void readFrame();
void readInstruction();
public:
RecoverReader(SnapshotReader &snapshot, const uint8_t *recovers, uint32_t size);
bool moreFrames() const {
return framesRead_ < frameCount_;
bool moreInstructions() const {
return numInstructionsRead_ < numInstructions_;
}
void nextFrame() {
readFrame();
}
uint32_t frameCount() const {
return frameCount_;
void nextInstruction() {
readInstruction();
}
const RInstruction *instruction() const {