#431: M1388354 M1388014

This commit is contained in:
Cameron Kaiser 2017-10-02 06:39:30 -07:00
parent 16f8592aa9
commit da843afa12
6 changed files with 74 additions and 60 deletions

View File

@ -200,8 +200,10 @@ LRecoverInfo::New(MIRGenerator* gen, MResumePoint* mir)
return recoverInfo; return recoverInfo;
} }
// de-virtualise MResumePoint::getOperand calls.
template <typename Node>
bool bool
LRecoverInfo::appendOperands(MNode* ins) LRecoverInfo::appendOperands(Node* ins)
{ {
for (size_t i = 0, end = ins->numOperands(); i < end; i++) { for (size_t i = 0, end = ins->numOperands(); i < end; i++) {
MDefinition* def = ins->getOperand(i); MDefinition* def = ins->getOperand(i);

View File

@ -1098,7 +1098,8 @@ class LRecoverInfo : public TempObject
// Fill the instruction vector such as all instructions needed for the // Fill the instruction vector such as all instructions needed for the
// recovery are pushed before the current instruction. // recovery are pushed before the current instruction.
bool appendOperands(MNode* ins); template <typename Node>
bool appendOperands(Node* ins);
bool appendDefinition(MDefinition* def); bool appendDefinition(MDefinition* def);
bool appendResumePoint(MResumePoint* rp); bool appendResumePoint(MResumePoint* rp);
public: public:
@ -1132,37 +1133,50 @@ class LRecoverInfo : public TempObject
MNode** it_; MNode** it_;
MNode** end_; MNode** end_;
size_t op_; size_t op_;
size_t opEnd_;
MResumePoint* rp_;
MNode* node_;
public: public:
explicit OperandIter(LRecoverInfo* recoverInfo) explicit OperandIter(LRecoverInfo* recoverInfo)
: it_(recoverInfo->begin()), end_(recoverInfo->end()), op_(0) : it_(recoverInfo->begin()), end_(recoverInfo->end()),
op_(0), opEnd_(0), rp_(nullptr), node_(nullptr)
{ {
settle(); settle();
} }
void settle() { void settle() {
while ((*it_)->numOperands() == 0) { opEnd_ = (*it_)->numOperands();
while (opEnd_ == 0) {
++it_; ++it_;
op_ = 0; op_ = 0;
opEnd_ = (*it_)->numOperands();
} }
node_ = *it_;
if (node_->isResumePoint())
rp_ = node_->toResumePoint();
} }
MDefinition* operator*() { MDefinition* operator*() {
return (*it_)->getOperand(op_); if (rp_) // de-virtualize MResumePoint::getOperand calls.
return rp_->getOperand(op_);
return node_->getOperand(op_);
} }
MDefinition* operator ->() { MDefinition* operator ->() {
return (*it_)->getOperand(op_); if (rp_) // de-virtualize MResumePoint::getOperand calls.
return rp_->getOperand(op_);
return node_->getOperand(op_);
} }
OperandIter& operator ++() { OperandIter& operator ++() {
++op_; ++op_;
if (op_ == (*it_)->numOperands()) { if (op_ != opEnd_)
op_ = 0; return *this;
++it_; op_ = 0;
} ++it_;
node_ = rp_ = nullptr;
if (!*this) if (!*this)
settle(); settle();
return *this; return *this;
} }

View File

@ -381,20 +381,10 @@ RValueAllocation::write(CompactBufferWriter& writer) const
HashNumber HashNumber
RValueAllocation::hash() const { RValueAllocation::hash() const {
CompactBufferWriter writer;
write(writer);
// We should never oom because the compact buffer writer has 32 inlined
// bytes, and in the worse case scenario, only encode 12 bytes
// (12 == mode + signed + signed + pad).
MOZ_ASSERT(!writer.oom());
MOZ_ASSERT(writer.length() <= 12);
HashNumber res = 0; HashNumber res = 0;
for (size_t i = 0; i < writer.length(); i++) { res = HashNumber(mode_);
res = ((res << 8) | (res >> (sizeof(res) - 1))); res = arg1_.index + (res << 6) + (res << 16) - res;
res ^= writer.buffer()[i]; res = arg2_.index + (res << 6) + (res << 16) - res;
}
return res; return res;
} }
@ -461,27 +451,6 @@ RValueAllocation::dump(GenericPrinter& out) const
out.printf(")"); out.printf(")");
} }
bool
RValueAllocation::equalPayloads(PayloadType type, Payload lhs, Payload rhs)
{
switch (type) {
case PAYLOAD_NONE:
return true;
case PAYLOAD_INDEX:
return lhs.index == rhs.index;
case PAYLOAD_STACK_OFFSET:
return lhs.stackOffset == rhs.stackOffset;
case PAYLOAD_GPR:
return lhs.gpr == rhs.gpr;
case PAYLOAD_FPU:
return lhs.fpu == rhs.fpu;
case PAYLOAD_PACKED_TAG:
return lhs.type == rhs.type;
}
return false;
}
SnapshotReader::SnapshotReader(const uint8_t* snapshots, uint32_t offset, SnapshotReader::SnapshotReader(const uint8_t* snapshots, uint32_t offset,
uint32_t RVATableSize, uint32_t listSize) uint32_t RVATableSize, uint32_t listSize)
: reader_(snapshots + offset, snapshots + listSize), : reader_(snapshots + offset, snapshots + listSize),

View File

@ -127,6 +127,11 @@ class RValueAllocation
Register gpr; Register gpr;
FloatRegisterBits fpu; FloatRegisterBits fpu;
JSValueType type; JSValueType type;
Payload() : index(0) {
static_assert(sizeof(index) == sizeof(Payload),
"All Payload bits are initialized.");
}
}; };
Payload arg1_; Payload arg1_;
@ -181,17 +186,23 @@ class RValueAllocation
: mode_(mode), : mode_(mode),
arg1_(a1) arg1_(a1)
{ {
arg2_.index = 0;
} }
explicit RValueAllocation(Mode mode) explicit RValueAllocation(Mode mode)
: mode_(mode) : mode_(mode)
{ {
arg1_.index = 0;
arg2_.index = 0;
} }
public: public:
RValueAllocation() RValueAllocation()
: mode_(INVALID) : mode_(INVALID)
{ } {
arg1_.index = 0;
arg2_.index = 0;
}
// DOUBLE_REG // DOUBLE_REG
static RValueAllocation Double(FloatRegister reg) { static RValueAllocation Double(FloatRegister reg) {
@ -340,12 +351,14 @@ class RValueAllocation
public: public:
bool operator==(const RValueAllocation& rhs) const { bool operator==(const RValueAllocation& rhs) const {
if (mode_ != rhs.mode_) // Note, this equality compares the verbatim content of the payload,
return false; // which is made possible because we ensure that the payload content is
// fully initialized during the creation.
const Layout& layout = layoutFromMode(mode()); static_assert(sizeof(int32_t) == sizeof(Payload),
return equalPayloads(layout.type1, arg1_, rhs.arg1_) && "All Payload bits are compared.");
equalPayloads(layout.type2, arg2_, rhs.arg2_); return mode_ == rhs.mode_ &&
arg1_.index == rhs.arg1_.index &&
arg2_.index == rhs.arg2_.index;
} }
HashNumber hash() const; HashNumber hash() const;

View File

@ -3023,6 +3023,20 @@ js::ToPrimitiveSlow(JSContext* cx, JSType preferredType, MutableHandleValue vp)
return OrdinaryToPrimitive(cx, obj, preferredType, vp); return OrdinaryToPrimitive(cx, obj, preferredType, vp);
} }
/* ES6 draft rev 28 (2014 Oct 14) 7.1.14 */
bool
js::ToPropertyKeySlow(JSContext* cx, Value argument, MutableHandleId result)
{
MOZ_ASSERT(argument.isObject());
// Steps 1-2.
RootedValue key(cx, argument);
if (!ToPrimitiveSlow(cx, JSTYPE_STRING, &key))
return false;
// Steps 3-4.
return ValueToId<CanGC>(cx, key, result);
}
/* * */ /* * */

View File

@ -569,17 +569,19 @@ HasObjectValueOf(JSObject* obj, JSContext* cx)
return IsNativeFunction(v, obj_valueOf); return IsNativeFunction(v, obj_valueOf);
} }
extern bool
ToPropertyKeySlow(JSContext* cx, Value argument, MutableHandleId result);
/* ES6 draft rev 28 (2014 Oct 14) 7.1.14 */ /* ES6 draft rev 28 (2014 Oct 14) 7.1.14 */
inline bool MOZ_ALWAYS_INLINE bool
ToPropertyKey(JSContext* cx, Value argument, MutableHandleId result) ToPropertyKey(JSContext* cx, Value argument, MutableHandleId result)
{ {
// Steps 1-2. if (MOZ_LIKELY(argument.isPrimitive())) {
RootedValue key(cx, argument); RootedValue key(cx, argument);
if (!ToPrimitive(cx, JSTYPE_STRING, &key)) return ValueToId<CanGC>(cx, key, result);
return false; }
// Steps 3-4. return ToPropertyKeySlow(cx, argument, result);
return ValueToId<CanGC>(cx, key, result);
} }
/* /*