зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1073033 part 2.0 - Snapshot: Add Recover instruction with default value. r=bbouvier
This commit is contained in:
Родитель
ad80860b57
Коммит
a820b1f0ec
|
@ -356,6 +356,18 @@ class SnapshotIterator
|
|||
IonScript *ionScript_;
|
||||
RInstructionResults *instructionResults_;
|
||||
|
||||
enum ReadMethod {
|
||||
// Read the normal value.
|
||||
RM_Normal = 1 << 0,
|
||||
|
||||
// Read the default value, or the normal value if there is no default.
|
||||
RM_AlwaysDefault = 1 << 1,
|
||||
|
||||
// Try to read the normal value if it is readable, otherwise default to
|
||||
// the Default value.
|
||||
RM_NormalOrDefault = RM_Normal | RM_AlwaysDefault,
|
||||
};
|
||||
|
||||
private:
|
||||
// Read a spilled register from the machine state.
|
||||
bool hasRegister(Register reg) const {
|
||||
|
@ -383,8 +395,8 @@ class SnapshotIterator
|
|||
}
|
||||
Value fromInstructionResult(uint32_t index) const;
|
||||
|
||||
Value allocationValue(const RValueAllocation &a);
|
||||
bool allocationReadable(const RValueAllocation &a);
|
||||
Value allocationValue(const RValueAllocation &a, ReadMethod rm = RM_Normal);
|
||||
bool allocationReadable(const RValueAllocation &a, ReadMethod rm = RM_Normal);
|
||||
void writeAllocationValuePayload(const RValueAllocation &a, Value v);
|
||||
void warnUnreadableAllocation();
|
||||
|
||||
|
@ -482,6 +494,14 @@ class SnapshotIterator
|
|||
return allocationValue(readAllocation());
|
||||
}
|
||||
|
||||
// Read the |Normal| value unless it is not available and that the snapshot
|
||||
// provides a |Default| value. This is useful to avoid invalidations of the
|
||||
// frame while we are only interested in a few properties which are provided
|
||||
// by the |Default| value.
|
||||
Value readWithDefault() {
|
||||
return allocationValue(readAllocation(), RM_NormalOrDefault);
|
||||
}
|
||||
|
||||
Value maybeRead(MaybeReadFallback &fallback) {
|
||||
RValueAllocation a = readAllocation();
|
||||
if (allocationReadable(a))
|
||||
|
|
|
@ -1749,7 +1749,7 @@ FromTypedPayload(JSValueType type, uintptr_t payload)
|
|||
}
|
||||
|
||||
bool
|
||||
SnapshotIterator::allocationReadable(const RValueAllocation &alloc)
|
||||
SnapshotIterator::allocationReadable(const RValueAllocation &alloc, ReadMethod rm)
|
||||
{
|
||||
switch (alloc.mode()) {
|
||||
case RValueAllocation::DOUBLE_REG:
|
||||
|
@ -1776,6 +1776,8 @@ SnapshotIterator::allocationReadable(const RValueAllocation &alloc)
|
|||
|
||||
case RValueAllocation::RECOVER_INSTRUCTION:
|
||||
return hasInstructionResult(alloc.index());
|
||||
case RValueAllocation::RI_WITH_DEFAULT_CST:
|
||||
return rm & RM_AlwaysDefault || hasInstructionResult(alloc.index());
|
||||
|
||||
default:
|
||||
return true;
|
||||
|
@ -1783,7 +1785,7 @@ SnapshotIterator::allocationReadable(const RValueAllocation &alloc)
|
|||
}
|
||||
|
||||
Value
|
||||
SnapshotIterator::allocationValue(const RValueAllocation &alloc)
|
||||
SnapshotIterator::allocationValue(const RValueAllocation &alloc, ReadMethod rm)
|
||||
{
|
||||
switch (alloc.mode()) {
|
||||
case RValueAllocation::CONSTANT:
|
||||
|
@ -1887,6 +1889,12 @@ SnapshotIterator::allocationValue(const RValueAllocation &alloc)
|
|||
case RValueAllocation::RECOVER_INSTRUCTION:
|
||||
return fromInstructionResult(alloc.index());
|
||||
|
||||
case RValueAllocation::RI_WITH_DEFAULT_CST:
|
||||
if (rm & RM_Normal && hasInstructionResult(alloc.index()))
|
||||
return fromInstructionResult(alloc.index());
|
||||
MOZ_ASSERT(rm & RM_AlwaysDefault);
|
||||
return ionScript_->getConstant(alloc.index2());
|
||||
|
||||
default:
|
||||
MOZ_CRASH("huh?");
|
||||
}
|
||||
|
@ -1956,6 +1964,12 @@ SnapshotIterator::writeAllocationValuePayload(const RValueAllocation &alloc, Val
|
|||
MOZ_CRASH("Recover instructions are handled by the JitActivation.");
|
||||
break;
|
||||
|
||||
case RValueAllocation::RI_WITH_DEFAULT_CST:
|
||||
// Assume that we are always going to be writing on the default value
|
||||
// while tracing.
|
||||
ionScript_->getConstant(alloc.index2()) = v;
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("huh?");
|
||||
}
|
||||
|
@ -1965,10 +1979,10 @@ void
|
|||
SnapshotIterator::traceAllocation(JSTracer *trc)
|
||||
{
|
||||
RValueAllocation alloc = readAllocation();
|
||||
if (!allocationReadable(alloc))
|
||||
if (!allocationReadable(alloc, RM_AlwaysDefault))
|
||||
return;
|
||||
|
||||
Value v = allocationValue(alloc);
|
||||
Value v = allocationValue(alloc, RM_AlwaysDefault);
|
||||
if (!v.isMarkable())
|
||||
return;
|
||||
|
||||
|
@ -2313,8 +2327,12 @@ InlineFrameIterator::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();
|
||||
// This value should correspond to the function which is being inlined.
|
||||
// The value must be readable to iterate over the inline frame. Most of
|
||||
// the time, these functions are stored as JSFunction constants,
|
||||
// register which are holding the JSFunction pointer, or recover
|
||||
// instruction with Default value.
|
||||
Value funval = si_.readWithDefault();
|
||||
|
||||
// Skip extra value allocations.
|
||||
while (si_.moreAllocations())
|
||||
|
|
|
@ -79,6 +79,11 @@ using namespace js::jit;
|
|||
// RECOVER_INSTRUCTION [INDEX]
|
||||
// Index into the list of recovered instruction results.
|
||||
//
|
||||
// RI_WITH_DEFAULT_CST [INDEX] [INDEX]
|
||||
// The first payload is the index into the list of recovered
|
||||
// instruction results. The second payload is the index in the
|
||||
// constant pool.
|
||||
//
|
||||
// TYPED_REG [PACKED_TAG, GPR_REG]:
|
||||
// Value with statically known type, which payload is stored in a
|
||||
// register.
|
||||
|
@ -231,6 +236,14 @@ RValueAllocation::layoutFromMode(Mode mode)
|
|||
};
|
||||
return layout;
|
||||
}
|
||||
case RI_WITH_DEFAULT_CST: {
|
||||
static const RValueAllocation::Layout layout = {
|
||||
PAYLOAD_INDEX,
|
||||
PAYLOAD_INDEX,
|
||||
"instruction with default"
|
||||
};
|
||||
return layout;
|
||||
}
|
||||
|
||||
default: {
|
||||
static const RValueAllocation::Layout regLayout = {
|
||||
|
|
|
@ -54,7 +54,10 @@ class RValueAllocation
|
|||
UNTYPED_REG = 0x06,
|
||||
UNTYPED_STACK = 0x07,
|
||||
#endif
|
||||
|
||||
// Recover instructions.
|
||||
RECOVER_INSTRUCTION = 0x0a,
|
||||
RI_WITH_DEFAULT_CST = 0x0b,
|
||||
|
||||
// The JSValueType is packed in the Mode.
|
||||
TYPED_REG_MIN = 0x10,
|
||||
|
@ -260,6 +263,11 @@ class RValueAllocation
|
|||
static RValueAllocation RecoverInstruction(uint32_t index) {
|
||||
return RValueAllocation(RECOVER_INSTRUCTION, payloadOfIndex(index));
|
||||
}
|
||||
static RValueAllocation RecoverInstruction(uint32_t riIndex, uint32_t cstIndex) {
|
||||
return RValueAllocation(RI_WITH_DEFAULT_CST,
|
||||
payloadOfIndex(riIndex),
|
||||
payloadOfIndex(cstIndex));
|
||||
}
|
||||
|
||||
void writeHeader(CompactBufferWriter &writer, JSValueType type, uint32_t regCode) const;
|
||||
public:
|
||||
|
@ -293,6 +301,10 @@ class RValueAllocation
|
|||
return arg1_.type;
|
||||
}
|
||||
|
||||
uint32_t index2() const {
|
||||
MOZ_ASSERT(layoutFromMode(mode()).type2 == PAYLOAD_INDEX);
|
||||
return arg2_.index;
|
||||
}
|
||||
int32_t stackOffset2() const {
|
||||
MOZ_ASSERT(layoutFromMode(mode()).type2 == PAYLOAD_STACK_OFFSET);
|
||||
return arg2_.stackOffset;
|
||||
|
|
Загрузка…
Ссылка в новой задаче