mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-05 05:30:29 +00:00
Bug 1083866 - Mark bailout frames. r=jandem
This commit is contained in:
parent
5d27f2526f
commit
3ae82445bd
@ -56,6 +56,12 @@ ReadFrameSlot(IonJSFrameLayout *fp, int32_t slot)
|
||||
return *(uintptr_t *)((char *)fp + OffsetOfFrameSlot(slot));
|
||||
}
|
||||
|
||||
static inline void
|
||||
WriteFrameSlot(IonJSFrameLayout *fp, int32_t slot, uintptr_t value)
|
||||
{
|
||||
*(uintptr_t *)((char *)fp + OffsetOfFrameSlot(slot)) = value;
|
||||
}
|
||||
|
||||
static inline double
|
||||
ReadFrameDoubleSlot(IonJSFrameLayout *fp, int32_t slot)
|
||||
{
|
||||
@ -972,6 +978,42 @@ MarkIonJSFrame(JSTracer *trc, const JitFrameIterator &frame)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
MarkBailoutFrame(JSTracer *trc, const JitFrameIterator &frame)
|
||||
{
|
||||
IonJSFrameLayout *layout = (IonJSFrameLayout *)frame.fp();
|
||||
|
||||
layout->replaceCalleeToken(MarkCalleeToken(trc, layout->calleeToken()));
|
||||
|
||||
// We have to mark the list of actual arguments, as only formal arguments
|
||||
// are represented in the Snapshot.
|
||||
MarkFrameAndActualArguments(trc, frame);
|
||||
|
||||
// Under a bailout, do not have a Safepoint to only iterate over GC-things.
|
||||
// Thus we use a SnapshotIterator to trace all the locations which would be
|
||||
// used to reconstruct the Baseline frame.
|
||||
//
|
||||
// Note that at the time where this function is called, we have not yet
|
||||
// started to reconstruct baseline frames.
|
||||
|
||||
// The vector of recover instructions is already traced as part of the
|
||||
// JitActivation.
|
||||
SnapshotIterator snapIter(frame);
|
||||
|
||||
// For each instruction, we read the allocations without evaluating the
|
||||
// recover instruction, nor reconstructing the frame. We are only looking at
|
||||
// tracing readable allocations.
|
||||
while (true) {
|
||||
while (snapIter.moreAllocations())
|
||||
snapIter.traceAllocation(trc);
|
||||
|
||||
if (!snapIter.moreInstructions())
|
||||
break;
|
||||
snapIter.nextInstruction();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
template <typename T>
|
||||
void
|
||||
@ -1306,6 +1348,9 @@ MarkJitActivation(JSTracer *trc, const JitActivationIterator &activations)
|
||||
case JitFrame_IonJS:
|
||||
MarkIonJSFrame(trc, frames);
|
||||
break;
|
||||
case JitFrame_Bailout:
|
||||
MarkBailoutFrame(trc, frames);
|
||||
break;
|
||||
case JitFrame_Unwound_IonJS:
|
||||
MOZ_CRASH("invalid");
|
||||
case JitFrame_Rectifier:
|
||||
@ -1752,6 +1797,87 @@ SnapshotIterator::allocationValue(const RValueAllocation &alloc)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SnapshotIterator::writeAllocationValuePayload(const RValueAllocation &alloc, Value v)
|
||||
{
|
||||
switch (alloc.mode()) {
|
||||
case RValueAllocation::CONSTANT:
|
||||
ionScript_->getConstant(alloc.index()) = v;
|
||||
break;
|
||||
|
||||
case RValueAllocation::CST_UNDEFINED:
|
||||
case RValueAllocation::CST_NULL:
|
||||
case RValueAllocation::DOUBLE_REG:
|
||||
case RValueAllocation::FLOAT32_REG:
|
||||
case RValueAllocation::FLOAT32_STACK:
|
||||
MOZ_CRASH("Not a GC thing: Unexpected write");
|
||||
break;
|
||||
|
||||
case RValueAllocation::TYPED_REG:
|
||||
machine_.write(alloc.reg2(), *v.payloadUIntPtr());
|
||||
break;
|
||||
|
||||
case RValueAllocation::TYPED_STACK:
|
||||
switch (alloc.knownType()) {
|
||||
default:
|
||||
MOZ_CRASH("Not a GC thing: Unexpected write");
|
||||
break;
|
||||
case JSVAL_TYPE_STRING:
|
||||
case JSVAL_TYPE_SYMBOL:
|
||||
case JSVAL_TYPE_OBJECT:
|
||||
WriteFrameSlot(fp_, alloc.stackOffset2(), *v.payloadUIntPtr());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
#if defined(JS_NUNBOX32)
|
||||
case RValueAllocation::UNTYPED_REG_REG:
|
||||
case RValueAllocation::UNTYPED_STACK_REG:
|
||||
machine_.write(alloc.reg2(), *v.payloadUIntPtr());
|
||||
break;
|
||||
|
||||
case RValueAllocation::UNTYPED_REG_STACK:
|
||||
case RValueAllocation::UNTYPED_STACK_STACK:
|
||||
WriteFrameSlot(fp_, alloc.stackOffset2(), *v.payloadUIntPtr());
|
||||
break;
|
||||
#elif defined(JS_PUNBOX64)
|
||||
case RValueAllocation::UNTYPED_REG:
|
||||
machine_.write(alloc.reg(), *v.payloadUIntPtr());
|
||||
break;
|
||||
|
||||
case RValueAllocation::UNTYPED_STACK:
|
||||
WriteFrameSlot(fp_, alloc.stackOffset(), *v.payloadUIntPtr());
|
||||
break;
|
||||
#endif
|
||||
|
||||
case RValueAllocation::RECOVER_INSTRUCTION:
|
||||
MOZ_CRASH("Recover instructions are handled by the JitActivation.");
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("huh?");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SnapshotIterator::traceAllocation(JSTracer *trc)
|
||||
{
|
||||
RValueAllocation alloc = readAllocation();
|
||||
if (!allocationReadable(alloc))
|
||||
return;
|
||||
|
||||
Value v = allocationValue(alloc);
|
||||
if (!v.isMarkable())
|
||||
return;
|
||||
|
||||
Value copy = v;
|
||||
gc::MarkValueRoot(trc, &v, "ion-typed-reg");
|
||||
if (v != copy) {
|
||||
MOZ_ASSERT(SameType(v, copy));
|
||||
writeAllocationValuePayload(alloc, v);
|
||||
}
|
||||
}
|
||||
|
||||
const RResumePoint *
|
||||
SnapshotIterator::resumePoint() const
|
||||
{
|
||||
|
@ -388,6 +388,7 @@ class SnapshotIterator
|
||||
|
||||
Value allocationValue(const RValueAllocation &a);
|
||||
bool allocationReadable(const RValueAllocation &a);
|
||||
void writeAllocationValuePayload(const RValueAllocation &a, Value v);
|
||||
void warnUnreadableAllocation();
|
||||
|
||||
public:
|
||||
@ -502,6 +503,8 @@ class SnapshotIterator
|
||||
return fallback.unreadablePlaceholder();
|
||||
}
|
||||
|
||||
void traceAllocation(JSTracer *trc);
|
||||
|
||||
void readCommonFrameSlots(Value *scopeChain, Value *rval) {
|
||||
if (scopeChain)
|
||||
*scopeChain = read();
|
||||
|
Loading…
x
Reference in New Issue
Block a user