From da843afa12968ccad3d8f9dc22aa5df593a9e62a Mon Sep 17 00:00:00 2001 From: Cameron Kaiser Date: Mon, 2 Oct 2017 06:39:30 -0700 Subject: [PATCH] #431: M1388354 M1388014 --- js/src/jit/LIR.cpp | 4 +++- js/src/jit/LIR.h | 34 ++++++++++++++++++++++++---------- js/src/jit/Snapshots.cpp | 37 +++---------------------------------- js/src/jit/Snapshots.h | 27 ++++++++++++++++++++------- js/src/jsobj.cpp | 14 ++++++++++++++ js/src/jsobjinlines.h | 18 ++++++++++-------- 6 files changed, 74 insertions(+), 60 deletions(-) diff --git a/js/src/jit/LIR.cpp b/js/src/jit/LIR.cpp index 6d72352ab..55b78ff4d 100644 --- a/js/src/jit/LIR.cpp +++ b/js/src/jit/LIR.cpp @@ -200,8 +200,10 @@ LRecoverInfo::New(MIRGenerator* gen, MResumePoint* mir) return recoverInfo; } +// de-virtualise MResumePoint::getOperand calls. +template bool -LRecoverInfo::appendOperands(MNode* ins) +LRecoverInfo::appendOperands(Node* ins) { for (size_t i = 0, end = ins->numOperands(); i < end; i++) { MDefinition* def = ins->getOperand(i); diff --git a/js/src/jit/LIR.h b/js/src/jit/LIR.h index ed209a8b0..893c4955a 100644 --- a/js/src/jit/LIR.h +++ b/js/src/jit/LIR.h @@ -1098,7 +1098,8 @@ class LRecoverInfo : public TempObject // Fill the instruction vector such as all instructions needed for the // recovery are pushed before the current instruction. - bool appendOperands(MNode* ins); + template + bool appendOperands(Node* ins); bool appendDefinition(MDefinition* def); bool appendResumePoint(MResumePoint* rp); public: @@ -1132,37 +1133,50 @@ class LRecoverInfo : public TempObject MNode** it_; MNode** end_; size_t op_; + size_t opEnd_; + MResumePoint* rp_; + MNode* node_; public: 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(); } void settle() { - while ((*it_)->numOperands() == 0) { + opEnd_ = (*it_)->numOperands(); + while (opEnd_ == 0) { ++it_; op_ = 0; + opEnd_ = (*it_)->numOperands(); } + node_ = *it_; + if (node_->isResumePoint()) + rp_ = node_->toResumePoint(); } MDefinition* operator*() { - return (*it_)->getOperand(op_); + if (rp_) // de-virtualize MResumePoint::getOperand calls. + return rp_->getOperand(op_); + return node_->getOperand(op_); } MDefinition* operator ->() { - return (*it_)->getOperand(op_); + if (rp_) // de-virtualize MResumePoint::getOperand calls. + return rp_->getOperand(op_); + return node_->getOperand(op_); } OperandIter& operator ++() { ++op_; - if (op_ == (*it_)->numOperands()) { - op_ = 0; - ++it_; - } + if (op_ != opEnd_) + return *this; + op_ = 0; + ++it_; + node_ = rp_ = nullptr; if (!*this) settle(); - return *this; } diff --git a/js/src/jit/Snapshots.cpp b/js/src/jit/Snapshots.cpp index 9923e41fc..04f136b91 100644 --- a/js/src/jit/Snapshots.cpp +++ b/js/src/jit/Snapshots.cpp @@ -381,20 +381,10 @@ RValueAllocation::write(CompactBufferWriter& writer) const HashNumber 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; - for (size_t i = 0; i < writer.length(); i++) { - res = ((res << 8) | (res >> (sizeof(res) - 1))); - res ^= writer.buffer()[i]; - } + res = HashNumber(mode_); + res = arg1_.index + (res << 6) + (res << 16) - res; + res = arg2_.index + (res << 6) + (res << 16) - res; return res; } @@ -461,27 +451,6 @@ RValueAllocation::dump(GenericPrinter& out) const 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, uint32_t RVATableSize, uint32_t listSize) : reader_(snapshots + offset, snapshots + listSize), diff --git a/js/src/jit/Snapshots.h b/js/src/jit/Snapshots.h index 834e1fd5b..a1c037def 100644 --- a/js/src/jit/Snapshots.h +++ b/js/src/jit/Snapshots.h @@ -127,6 +127,11 @@ class RValueAllocation Register gpr; FloatRegisterBits fpu; JSValueType type; + + Payload() : index(0) { + static_assert(sizeof(index) == sizeof(Payload), + "All Payload bits are initialized."); + } }; Payload arg1_; @@ -181,17 +186,23 @@ class RValueAllocation : mode_(mode), arg1_(a1) { + arg2_.index = 0; } explicit RValueAllocation(Mode mode) : mode_(mode) { + arg1_.index = 0; + arg2_.index = 0; } public: RValueAllocation() : mode_(INVALID) - { } + { + arg1_.index = 0; + arg2_.index = 0; + } // DOUBLE_REG static RValueAllocation Double(FloatRegister reg) { @@ -340,12 +351,14 @@ class RValueAllocation public: bool operator==(const RValueAllocation& rhs) const { - if (mode_ != rhs.mode_) - return false; - - const Layout& layout = layoutFromMode(mode()); - return equalPayloads(layout.type1, arg1_, rhs.arg1_) && - equalPayloads(layout.type2, arg2_, rhs.arg2_); + // Note, this equality compares the verbatim content of the payload, + // which is made possible because we ensure that the payload content is + // fully initialized during the creation. + static_assert(sizeof(int32_t) == sizeof(Payload), + "All Payload bits are compared."); + return mode_ == rhs.mode_ && + arg1_.index == rhs.arg1_.index && + arg2_.index == rhs.arg2_.index; } HashNumber hash() const; diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 41ad7756e..fc8085715 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -3023,6 +3023,20 @@ js::ToPrimitiveSlow(JSContext* cx, JSType preferredType, MutableHandleValue 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(cx, key, result); +} /* * */ diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h index eca5aa0d6..e515ecb12 100644 --- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -569,17 +569,19 @@ HasObjectValueOf(JSObject* obj, JSContext* cx) return IsNativeFunction(v, obj_valueOf); } +extern bool +ToPropertyKeySlow(JSContext* cx, Value argument, MutableHandleId result); + /* ES6 draft rev 28 (2014 Oct 14) 7.1.14 */ -inline bool +MOZ_ALWAYS_INLINE bool ToPropertyKey(JSContext* cx, Value argument, MutableHandleId result) { - // Steps 1-2. - RootedValue key(cx, argument); - if (!ToPrimitive(cx, JSTYPE_STRING, &key)) - return false; - - // Steps 3-4. - return ValueToId(cx, key, result); + if (MOZ_LIKELY(argument.isPrimitive())) { + RootedValue key(cx, argument); + return ValueToId(cx, key, result); + } + + return ToPropertyKeySlow(cx, argument, result); } /*