Bug 1062869 part 5 - Add MaybeReadFallback class to record the fallback method. r=shu

This commit is contained in:
Nicolas B. Pierron 2014-09-23 19:42:34 +02:00
parent cfcd56d28b
commit e1b1b57de3
4 changed files with 51 additions and 21 deletions

View File

@ -2211,6 +2211,7 @@ InlineFrameIterator::dump() const
}
SnapshotIterator si = snapshotIterator();
MaybeReadFallback fallback(UndefinedValue());
fprintf(stderr, " slots: %u\n", si.numAllocations() - 1);
for (unsigned i = 0; i < si.numAllocations() - 1; i++) {
if (isFunction) {
@ -2223,7 +2224,7 @@ InlineFrameIterator::dump() const
else {
if (i - 2 == callee()->nargs() && numActualArgs() > callee()->nargs()) {
DumpOp d(callee()->nargs());
unaliasedForEachActual(GetJSContextFromJitCode(), d, ReadFrame_Overflown);
unaliasedForEachActual(GetJSContextFromJitCode(), d, ReadFrame_Overflown, fallback);
}
fprintf(stderr, " slot %d: ", int(i - 2 - callee()->nargs()));
@ -2231,7 +2232,7 @@ InlineFrameIterator::dump() const
} else
fprintf(stderr, " slot %u: ", i);
#ifdef DEBUG
js_DumpValue(si.maybeRead());
js_DumpValue(si.maybeRead(fallback));
#else
fprintf(stderr, "?\n");
#endif

View File

@ -294,6 +294,33 @@ class RInstructionResults
void trace(JSTracer *trc);
};
struct MaybeReadFallback
{
JSContext *maybeCx;
JitActivation *activation;
JitFrameIterator *frame;
const Value unreadablePlaceholder;
MaybeReadFallback(const Value &placeholder = UndefinedValue())
: maybeCx(nullptr),
activation(nullptr),
frame(nullptr),
unreadablePlaceholder(placeholder)
{
}
MaybeReadFallback(JSContext *cx, JitActivation *activation, JitFrameIterator *frame)
: maybeCx(cx),
activation(activation),
frame(frame),
unreadablePlaceholder(UndefinedValue())
{
}
bool canRecoverResults() { return maybeCx; }
};
class RResumePoint;
// Reads frame information in snapshot-encoding order (that is, outermost frame
@ -425,13 +452,15 @@ class SnapshotIterator
Value read() {
return allocationValue(readAllocation());
}
Value maybeRead(const Value &placeholder = UndefinedValue(), bool silentFailure = false) {
Value maybeRead(MaybeReadFallback &fallback) {
RValueAllocation a = readAllocation();
if (allocationReadable(a))
return allocationValue(a);
if (!silentFailure)
if (fallback.canRecoverResults())
warnUnreadableAllocation();
return placeholder;
return fallback.unreadablePlaceholder;
}
void readCommonFrameSlots(Value *scopeChain, Value *rval) {
@ -449,8 +478,7 @@ class SnapshotIterator
template <class Op>
void readFunctionFrameArgs(Op &op, ArgumentsObject **argsObj, Value *thisv,
unsigned start, unsigned end, JSScript *script,
const Value &unreadablePlaceholder = UndefinedValue(),
bool silentFailure = false)
MaybeReadFallback &fallback)
{
// Assumes that the common frame arguments have already been read.
if (script->argumentsHasVarBinding()) {
@ -478,7 +506,7 @@ class SnapshotIterator
// We are not always able to read values from the snapshots, some values
// such as non-gc things may still be live in registers and cause an
// error while reading the machine state.
Value v = maybeRead(unreadablePlaceholder, silentFailure);
Value v = maybeRead(fallback);
op(v);
}
}
@ -489,7 +517,8 @@ class SnapshotIterator
skip();
}
Value s = maybeRead(/* placeholder = */ UndefinedValue(), true);
MaybeReadFallback fallback(UndefinedValue());
Value s = maybeRead(fallback);
while (moreAllocations())
skip();
@ -566,8 +595,7 @@ class InlineFrameIterator
JSObject **scopeChain, Value *rval,
ArgumentsObject **argsObj, Value *thisv,
ReadFrameArgsBehavior behavior,
const Value &unreadablePlaceholder = UndefinedValue(),
bool silentFailure = false) const
MaybeReadFallback &fallback) const
{
SnapshotIterator s(si_);
@ -586,10 +614,8 @@ class InlineFrameIterator
// Get the non overflown arguments, which are taken from the inlined
// frame, because it will have the updated value when JSOP_SETARG is
// done.
if (behavior != ReadFrame_Overflown) {
s.readFunctionFrameArgs(argOp, argsObj, thisv, 0, nformal, script(),
unreadablePlaceholder, silentFailure);
}
if (behavior != ReadFrame_Overflown)
s.readFunctionFrameArgs(argOp, argsObj, thisv, 0, nformal, script(), fallback);
if (behavior != ReadFrame_Formals) {
if (more()) {
@ -618,7 +644,7 @@ class InlineFrameIterator
parent_s.readCommonFrameSlots(nullptr, nullptr);
parent_s.readFunctionFrameArgs(argOp, nullptr, nullptr,
nformal, nactual, it.script(),
unreadablePlaceholder, silentFailure);
fallback);
} else {
// There is no parent frame to this inlined frame, we can read
// from the frame's Value vector directly.
@ -637,16 +663,17 @@ class InlineFrameIterator
// recovering slots.
//
// FIXME bug 1029963.
localOp(s.maybeRead(unreadablePlaceholder, silentFailure));
localOp(s.maybeRead(fallback));
}
}
template <class Op>
void unaliasedForEachActual(ThreadSafeContext *cx, Op op,
ReadFrameArgsBehavior behavior) const
ReadFrameArgsBehavior behavior,
MaybeReadFallback &fallback) const
{
Nop nop;
readFrameArgsAndLocals(cx, op, nop, nullptr, nullptr, nullptr, nullptr, behavior);
readFrameArgsAndLocals(cx, op, nop, nullptr, nullptr, nullptr, nullptr, behavior, fallback);
}
JSScript *script() const {

View File

@ -38,9 +38,10 @@ RematerializedFrame::RematerializedFrame(ThreadSafeContext *cx, uint8_t *top,
script_(iter.script())
{
CopyValueToRematerializedFrame op(slots_);
MaybeReadFallback fallback(MagicValue(JS_OPTIMIZED_OUT));
iter.readFrameArgsAndLocals(cx, op, op, &scopeChain_, &returnValue_,
&argsObj_, &thisValue_, ReadFrame_Actuals,
MagicValue(JS_OPTIMIZED_OUT), /* silentFailure = */ true);
fallback);
}
/* static */ RematerializedFrame *

View File

@ -349,7 +349,8 @@ FrameIter::unaliasedForEachActual(JSContext *cx, Op op)
return;
case JIT:
if (data_.jitFrames_.isIonJS()) {
ionInlineFrames_.unaliasedForEachActual(cx, op, jit::ReadFrame_Actuals);
jit::MaybeReadFallback recover(cx, activation()->asJit(), &data_.jitFrames_);
ionInlineFrames_.unaliasedForEachActual(cx, op, jit::ReadFrame_Actuals, recover);
} else {
JS_ASSERT(data_.jitFrames_.isBaselineJS());
data_.jitFrames_.unaliasedForEachActual(op, jit::ReadFrame_Actuals);