mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-13 21:35:39 +00:00
Bug 991720 part 3 - Enforce recovery of stores before reading object values. r=h4writer
This commit is contained in:
parent
669929b8ef
commit
b2cbcdb3ff
@ -393,6 +393,9 @@ class SnapshotIterator
|
||||
bool hasInstructionResult(uint32_t index) const {
|
||||
return instructionResults_;
|
||||
}
|
||||
bool hasInstructionResults() const {
|
||||
return instructionResults_;
|
||||
}
|
||||
Value fromInstructionResult(uint32_t index) const;
|
||||
|
||||
Value allocationValue(const RValueAllocation &a, ReadMethod rm = RM_Normal);
|
||||
|
@ -1751,6 +1751,14 @@ FromTypedPayload(JSValueType type, uintptr_t payload)
|
||||
bool
|
||||
SnapshotIterator::allocationReadable(const RValueAllocation &alloc, ReadMethod rm)
|
||||
{
|
||||
// If we have to recover stores, and if we are not interested in the
|
||||
// default value of the instruction, then we have to check if the recover
|
||||
// instruction results are available.
|
||||
if (alloc.needSideEffect() && !(rm & RM_AlwaysDefault)) {
|
||||
if (!hasInstructionResults())
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (alloc.mode()) {
|
||||
case RValueAllocation::DOUBLE_REG:
|
||||
return hasRegister(alloc.fpuReg());
|
||||
|
@ -101,6 +101,15 @@ MIRType MIRTypeFromValue(const js::Value &vp)
|
||||
*/ \
|
||||
_(RecoveredOnBailout) \
|
||||
\
|
||||
/* Some instructions might represent an object, but the memory of these
|
||||
* objects might be incomplete if we have not recovered all the stores which
|
||||
* were supposed to happen before. This flag is used to annotate
|
||||
* instructions which might return a pointer to a memory area which is not
|
||||
* yet fully initialized. This flag is used to ensure that stores are
|
||||
* executed before returning the value.
|
||||
*/ \
|
||||
_(IncompleteObject) \
|
||||
\
|
||||
/* The current instruction got discarded from the MIR Graph. This is useful
|
||||
* when we want to iterate over resume points and instructions, while
|
||||
* handling instructions which are discarded without reporting to the
|
||||
|
@ -313,7 +313,7 @@ RValueAllocation
|
||||
RValueAllocation::read(CompactBufferReader &reader)
|
||||
{
|
||||
uint8_t mode = reader.readByte();
|
||||
const Layout &layout = layoutFromMode(Mode(mode));
|
||||
const Layout &layout = layoutFromMode(Mode(mode & MODE_MASK));
|
||||
Payload arg1, arg2;
|
||||
|
||||
readPayload(reader, layout.type1, &mode, &arg1);
|
||||
|
@ -69,6 +69,17 @@ class RValueAllocation
|
||||
TYPED_STACK_MAX = 0x2f,
|
||||
TYPED_STACK = TYPED_STACK_MIN,
|
||||
|
||||
// This mask can be used with any other valid mode. When this flag is
|
||||
// set on the mode, this inform the snapshot iterator that even if the
|
||||
// allocation is readable, the content of if might be incomplete unless
|
||||
// all side-effects are executed.
|
||||
RECOVER_SIDE_EFFECT_MASK = 0x80,
|
||||
|
||||
// This mask represents the set of bits which can be used to encode a
|
||||
// value in a snapshot. The mode is used to determine how to interpret
|
||||
// the union of values and how to pack the value in memory.
|
||||
MODE_MASK = 0x17f,
|
||||
|
||||
INVALID = 0x100,
|
||||
};
|
||||
|
||||
@ -269,6 +280,11 @@ class RValueAllocation
|
||||
payloadOfIndex(cstIndex));
|
||||
}
|
||||
|
||||
void setNeedSideEffect() {
|
||||
MOZ_ASSERT(!needSideEffect() && mode_ != INVALID);
|
||||
mode_ = Mode(mode_ | RECOVER_SIDE_EFFECT_MASK);
|
||||
}
|
||||
|
||||
void writeHeader(CompactBufferWriter &writer, JSValueType type, uint32_t regCode) const;
|
||||
public:
|
||||
static RValueAllocation read(CompactBufferReader &reader);
|
||||
@ -276,7 +292,10 @@ class RValueAllocation
|
||||
|
||||
public:
|
||||
Mode mode() const {
|
||||
return mode_;
|
||||
return Mode(mode_ & MODE_MASK);
|
||||
}
|
||||
bool needSideEffect() const {
|
||||
return mode_ & RECOVER_SIDE_EFFECT_MASK;
|
||||
}
|
||||
|
||||
uint32_t index() const {
|
||||
|
@ -399,6 +399,12 @@ CodeGeneratorShared::encodeAllocation(LSnapshot *snapshot, MDefinition *mir,
|
||||
}
|
||||
}
|
||||
|
||||
// This set an extra bit as part of the RValueAllocation, such that we know
|
||||
// that recover instruction have to be executed without wrapping the
|
||||
// instruction in a no-op recover instruction.
|
||||
if (mir->isIncompleteObject())
|
||||
alloc.setNeedSideEffect();
|
||||
|
||||
snapshots_.add(alloc);
|
||||
*allocIndex += mir->isRecoveredOnBailout() ? 0 : 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user