Changeset 98912 in webkit
- Timestamp:
- Oct 31, 2011 4:50:57 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r98909 r98912 1 2011-10-31 Filip Pizlo <fpizlo@apple.com> 2 3 DFG OSR exits should add to value profiles 4 https://bugs.webkit.org/show_bug.cgi?id=71202 5 6 Reviewed by Oliver Hunt. 7 8 Value profiles now have an extra special slot not used by the old JIT's 9 profiling, which is reserved for OSR exits. 10 11 The DFG's OSR exit code now knows which register, node index, and value 12 profiling site was responsible for the (possibly flawed) information that 13 led to the OSR failure. This is somewhat opportunistic and imperfect; 14 if there's a lot of control flow between the value profiling site and the 15 OSR failure point, then this mechanism simply gives up. It also gives up 16 if the OSR failure is caused by either known deficiencies in the DFG 17 (like that we always assume that the index in a strict charCodeAt access 18 is within bounds) or where the OSR failure would be catalogues and 19 profiled through other means (like slow case counters). 20 21 This patch also adds the notion of a JSValueRegs, which is either a 22 single register in JSVALUE64 or a pair in JSVALUE32_64. We should 23 probably move the 32_64 DFG towards using this, since it often makes it 24 easier to share code between 64 and 32_64. 25 26 Also fixed a number of pathologies that this uncovered. op_method_check 27 didn't have a value profiling site on the slow path. GetById should not 28 always force OSR exit if it never executed in the old JIT; we may be 29 able to infer its type if it's a array or string length get. Finally, 30 these changes benefit from a slight tweak to optimization delay 31 heuristics (profile fullness is now 0.35 instead of 0.25). 32 33 3.8% speed-up on Kraken, mostly due to ~35% on both stanford-crypto-aes 34 and imaging-darkroom. 35 36 * bytecode/ValueProfile.cpp: 37 (JSC::ValueProfile::computeStatistics): 38 (JSC::ValueProfile::computeUpdatedPrediction): 39 * bytecode/ValueProfile.h: 40 (JSC::ValueProfile::ValueProfile): 41 (JSC::ValueProfile::specFailBucket): 42 (JSC::ValueProfile::numberOfSamples): 43 (JSC::ValueProfile::isLive): 44 (JSC::ValueProfile::numberOfInt32s): 45 (JSC::ValueProfile::numberOfDoubles): 46 (JSC::ValueProfile::numberOfCells): 47 (JSC::ValueProfile::numberOfObjects): 48 (JSC::ValueProfile::numberOfFinalObjects): 49 (JSC::ValueProfile::numberOfStrings): 50 (JSC::ValueProfile::numberOfArrays): 51 (JSC::ValueProfile::numberOfBooleans): 52 (JSC::ValueProfile::dump): 53 * dfg/DFGAbstractState.cpp: 54 (JSC::DFG::AbstractState::execute): 55 * dfg/DFGByteCodeParser.cpp: 56 (JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit): 57 (JSC::DFG::ByteCodeParser::getPrediction): 58 (JSC::DFG::ByteCodeParser::parseBlock): 59 * dfg/DFGGPRInfo.h: 60 (JSC::DFG::JSValueRegs::JSValueRegs): 61 (JSC::DFG::JSValueRegs::operator!): 62 (JSC::DFG::JSValueRegs::gpr): 63 (JSC::DFG::JSValueSource::JSValueSource): 64 (JSC::DFG::JSValueSource::unboxedCell): 65 (JSC::DFG::JSValueSource::operator!): 66 (JSC::DFG::JSValueSource::isAddress): 67 (JSC::DFG::JSValueSource::offset): 68 (JSC::DFG::JSValueSource::base): 69 (JSC::DFG::JSValueSource::gpr): 70 (JSC::DFG::JSValueSource::asAddress): 71 (JSC::DFG::JSValueSource::notAddress): 72 (JSC::DFG::JSValueRegs::tagGPR): 73 (JSC::DFG::JSValueRegs::payloadGPR): 74 (JSC::DFG::JSValueSource::tagGPR): 75 (JSC::DFG::JSValueSource::payloadGPR): 76 (JSC::DFG::JSValueSource::hasKnownTag): 77 (JSC::DFG::JSValueSource::tag): 78 * dfg/DFGGenerationInfo.h: 79 (JSC::DFG::GenerationInfo::jsValueRegs): 80 * dfg/DFGGraph.h: 81 (JSC::DFG::Graph::valueProfileFor): 82 * dfg/DFGJITCodeGenerator.h: 83 (JSC::JSValueOperand::jsValueRegs): 84 * dfg/DFGJITCompiler.cpp: 85 (JSC::DFG::JITCompiler::exitSpeculativeWithOSR): 86 * dfg/DFGJITCompiler.h: 87 (JSC::DFG::JITCompiler::valueProfileFor): 88 * dfg/DFGJITCompiler32_64.cpp: 89 (JSC::DFG::JITCompiler::exitSpeculativeWithOSR): 90 * dfg/DFGPropagator.cpp: 91 (JSC::DFG::Propagator::propagateNodePredictions): 92 * dfg/DFGSpeculativeJIT.cpp: 93 (JSC::DFG::OSRExit::OSRExit): 94 (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality): 95 (JSC::DFG::SpeculativeJIT::checkArgumentTypes): 96 (JSC::DFG::SpeculativeJIT::compileGetCharCodeAt): 97 (JSC::DFG::SpeculativeJIT::compileGetByValOnString): 98 (JSC::DFG::SpeculativeJIT::compilePutByValForByteArray): 99 (JSC::DFG::SpeculativeJIT::compileGetByValOnByteArray): 100 * dfg/DFGSpeculativeJIT.h: 101 (JSC::DFG::SpeculativeJIT::speculationCheck): 102 (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution): 103 * dfg/DFGSpeculativeJIT32_64.cpp: 104 (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal): 105 (JSC::DFG::SpeculativeJIT::fillSpeculateDouble): 106 (JSC::DFG::SpeculativeJIT::fillSpeculateCell): 107 (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean): 108 (JSC::DFG::SpeculativeJIT::compileObjectEquality): 109 (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot): 110 (JSC::DFG::SpeculativeJIT::compileLogicalNot): 111 (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch): 112 (JSC::DFG::SpeculativeJIT::compile): 113 * dfg/DFGSpeculativeJIT64.cpp: 114 (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal): 115 (JSC::DFG::SpeculativeJIT::fillSpeculateDouble): 116 (JSC::DFG::SpeculativeJIT::fillSpeculateCell): 117 (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean): 118 (JSC::DFG::SpeculativeJIT::compileObjectEquality): 119 (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot): 120 (JSC::DFG::SpeculativeJIT::compileLogicalNot): 121 (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch): 122 (JSC::DFG::SpeculativeJIT::emitBranch): 123 (JSC::DFG::SpeculativeJIT::compile): 124 * jit/JITPropertyAccess.cpp: 125 (JSC::JIT::emitSlow_op_method_check): 126 * jit/JITPropertyAccess32_64.cpp: 127 (JSC::JIT::emitSlow_op_method_check): 128 * runtime/Heuristics.cpp: 129 (JSC::Heuristics::initializeHeuristics): 130 * runtime/JSValue.h: 131 1 132 2011-10-31 Sam Weinig <sam@webkit.org> 2 133 -
trunk/Source/JavaScriptCore/bytecode/ValueProfile.cpp
r97294 r98912 60 60 void ValueProfile::computeStatistics(Statistics& statistics) const 61 61 { 62 for (unsigned i = 0; i < numberOfBuckets; ++i) {62 for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { 63 63 JSValue value = JSValue::decode(m_buckets[i]); 64 64 if (!value) … … 80 80 PredictedType ValueProfile::computeUpdatedPrediction() 81 81 { 82 for (unsigned i = 0; i < numberOfBuckets; ++i) {82 for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { 83 83 JSValue value = JSValue::decode(m_buckets[i]); 84 84 if (!value) -
trunk/Source/JavaScriptCore/bytecode/ValueProfile.h
r97294 r98912 41 41 static const unsigned logNumberOfBuckets = 3; // 8 buckets 42 42 static const unsigned numberOfBuckets = 1 << logNumberOfBuckets; 43 static const unsigned numberOfSpecFailBuckets = 1; 43 44 static const unsigned bucketIndexMask = numberOfBuckets - 1; 44 static const unsigned certainty = numberOfBuckets * numberOfBuckets; 45 static const unsigned totalNumberOfBuckets = numberOfBuckets + numberOfSpecFailBuckets; 46 static const unsigned certainty = totalNumberOfBuckets * totalNumberOfBuckets; 45 47 static const unsigned majority = certainty / 2; 46 48 … … 50 52 , m_numberOfSamplesInPrediction(0) 51 53 { 52 for (unsigned i = 0; i < numberOfBuckets; ++i)54 for (unsigned i = 0; i < totalNumberOfBuckets; ++i) 53 55 m_buckets[i] = JSValue::encode(JSValue()); 56 } 57 58 EncodedJSValue* specFailBucket(unsigned i) 59 { 60 ASSERT(numberOfBuckets + i < totalNumberOfBuckets); 61 return m_buckets + numberOfBuckets + i; 54 62 } 55 63 … … 68 76 { 69 77 unsigned result = 0; 70 for (unsigned i = 0; i < numberOfBuckets; ++i) {78 for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { 71 79 if (!!JSValue::decode(m_buckets[i])) 72 80 result++; … … 82 90 bool isLive() const 83 91 { 84 for (unsigned i = 0; i < numberOfBuckets; ++i) {92 for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { 85 93 if (!!JSValue::decode(m_buckets[i])) 86 94 return true; … … 99 107 { 100 108 unsigned result = 0; 101 for (unsigned i = 0; i < numberOfBuckets; ++i) {109 for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { 102 110 if (JSValue::decode(m_buckets[i]).isInt32()) 103 111 result++; … … 109 117 { 110 118 unsigned result = 0; 111 for (unsigned i = 0; i < numberOfBuckets; ++i) {119 for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { 112 120 if (JSValue::decode(m_buckets[i]).isDouble()) 113 121 result++; … … 119 127 { 120 128 unsigned result = 0; 121 for (unsigned i = 0; i < numberOfBuckets; ++i) {129 for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { 122 130 if (!!classInfo(i)) 123 131 result++; … … 129 137 { 130 138 unsigned result = 0; 131 for (unsigned i = 0; i < numberOfBuckets; ++i) {139 for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { 132 140 const ClassInfo* ci = classInfo(i); 133 141 if (!!ci && ci->isSubClassOf(&JSObject::s_info)) … … 140 148 { 141 149 unsigned result = 0; 142 for (unsigned i = 0; i < numberOfBuckets; ++i) {150 for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { 143 151 if (classInfo(i) == &JSFinalObject::s_info) 144 152 result++; … … 150 158 { 151 159 unsigned result = 0; 152 for (unsigned i = 0; i < numberOfBuckets; ++i) {160 for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { 153 161 if (classInfo(i) == &JSString::s_info) 154 162 result++; … … 160 168 { 161 169 unsigned result = 0; 162 for (unsigned i = 0; i < numberOfBuckets; ++i) {170 for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { 163 171 if (classInfo(i) == &JSArray::s_info) 164 172 result++; … … 170 178 { 171 179 unsigned result = 0; 172 for (unsigned i = 0; i < numberOfBuckets; ++i) {180 for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { 173 181 if (JSValue::decode(m_buckets[i]).isBoolean()) 174 182 result++; … … 238 246 predictionToString(m_prediction), m_numberOfSamplesInPrediction); 239 247 bool first = true; 240 for (unsigned i = 0; i < numberOfBuckets; ++i) {248 for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { 241 249 JSValue value = JSValue::decode(m_buckets[i]); 242 250 if (!!value) { … … 285 293 unsigned m_numberOfSamplesInPrediction; 286 294 287 EncodedJSValue m_buckets[ numberOfBuckets];295 EncodedJSValue m_buckets[totalNumberOfBuckets]; 288 296 }; 289 297 -
trunk/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
r98214 r98912 552 552 case GetById: 553 553 case GetMethod: 554 if (!node.prediction()) { 555 m_isValid = false; 556 break; 557 } 554 558 forNode(node.child1()).filter(PredictCell); 555 559 clobberStructures(nodeIndex); -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r98831 r98912 595 595 return call; 596 596 } 597 598 PredictedType getPrediction (NodeIndex nodeIndex, unsigned bytecodeIndex)597 598 PredictedType getPredictionWithoutOSRExit(NodeIndex nodeIndex, unsigned bytecodeIndex) 599 599 { 600 600 UNUSED_PARAM(nodeIndex); … … 607 607 #endif 608 608 609 return prediction; 610 } 611 612 PredictedType getPrediction(NodeIndex nodeIndex, unsigned bytecodeIndex) 613 { 614 PredictedType prediction = getPredictionWithoutOSRExit(nodeIndex, bytecodeIndex); 615 609 616 if (prediction == PredictNone) { 610 617 // We have no information about what values this node generates. Give up … … 614 621 615 622 return prediction; 623 } 624 625 PredictedType getPredictionWithoutOSRExit() 626 { 627 return getPredictionWithoutOSRExit(m_graph.size(), m_currentIndex); 616 628 } 617 629 … … 1652 1664 } 1653 1665 case op_get_by_id: { 1654 PredictedType prediction = getPrediction ();1666 PredictedType prediction = getPredictionWithoutOSRExit(); 1655 1667 1656 1668 NodeIndex base = get(currentInstruction[2].u.operand); … … 1719 1731 if (offset != notFound) { 1720 1732 ASSERT(structureSet.size()); 1733 1734 // The implementation of GetByOffset does not know to terminate speculative 1735 // execution if it doesn't have a prediction, so we do it manually. 1736 if (prediction == PredictNone) 1737 addToGraph(ForceOSRExit); 1738 1721 1739 addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(structureSet)), base); 1722 1740 set(currentInstruction[1].u.operand, addToGraph(GetByOffset, OpInfo(m_graph.m_storageAccessData.size()), OpInfo(prediction), addToGraph(GetPropertyStorage, base))); -
trunk/Source/JavaScriptCore/dfg/DFGGPRInfo.h
r95902 r98912 37 37 #define InvalidGPRReg ((GPRReg)-1) 38 38 39 #if USE(JSVALUE64) 40 class JSValueRegs { 41 public: 42 JSValueRegs() 43 : m_gpr(InvalidGPRReg) 44 { 45 } 46 47 explicit JSValueRegs(GPRReg gpr) 48 : m_gpr(gpr) 49 { 50 } 51 52 bool operator!() const { return m_gpr == InvalidGPRReg; } 53 54 GPRReg gpr() const { return m_gpr; } 55 56 private: 57 GPRReg m_gpr; 58 }; 59 60 class JSValueSource { 61 public: 62 JSValueSource() 63 : m_offset(notAddress()) 64 , m_base(InvalidGPRReg) 65 { 66 } 67 68 JSValueSource(JSValueRegs regs) 69 : m_offset(notAddress()) 70 , m_base(regs.gpr()) 71 { 72 } 73 74 explicit JSValueSource(GPRReg gpr) 75 : m_offset(notAddress()) 76 , m_base(gpr) 77 { 78 } 79 80 JSValueSource(MacroAssembler::Address address) 81 : m_offset(address.offset) 82 , m_base(address.base) 83 { 84 ASSERT(m_offset != notAddress()); 85 ASSERT(m_base != InvalidGPRReg); 86 } 87 88 static JSValueSource unboxedCell(GPRReg payloadGPR) 89 { 90 return JSValueSource(payloadGPR); 91 } 92 93 bool operator!() const { return m_base == InvalidGPRReg; } 94 95 bool isAddress() const { return m_offset != notAddress(); } 96 97 int32_t offset() const 98 { 99 ASSERT(isAddress()); 100 return m_offset; 101 } 102 103 GPRReg base() const 104 { 105 ASSERT(isAddress()); 106 return m_base; 107 } 108 109 GPRReg gpr() const 110 { 111 ASSERT(!isAddress()); 112 return m_base; 113 } 114 115 MacroAssembler::Address asAddress() const { return MacroAssembler::Address(base(), offset()); } 116 117 private: 118 static inline int32_t notAddress() { return 0x80000000; } 119 120 int32_t m_offset; 121 GPRReg m_base; 122 }; 123 #endif 124 125 #if USE(JSVALUE32_64) 126 class JSValueRegs { 127 public: 128 JSValueRegs() 129 : m_tagGPR(static_cast<int8_t>(InvalidGPRReg)) 130 , m_payloadGPR(static_cast<int8_t>(InvalidGPRReg)) 131 { 132 } 133 134 JSValueRegs(GPRReg tagGPR, GPRReg payloadGPR) 135 : m_tagGPR(tagGPR) 136 , m_payloadGPR(payloadGPR) 137 { 138 ASSERT((static_cast<GPRReg>(m_tagGPR) == InvalidGPRReg) == (static_cast<GPRReg>(payloadGPR) == InvalidGPRReg)); 139 } 140 141 bool operator!() const { return static_cast<GPRReg>(m_tagGPR) == InvalidGPRReg; } 142 143 GPRReg tagGPR() const { return static_cast<GPRReg>(m_tagGPR); } 144 GPRReg payloadGPR() const { return static_cast<GPRReg>(m_payloadGPR); } 145 146 private: 147 int8_t m_tagGPR; 148 int8_t m_payloadGPR; 149 }; 150 151 class JSValueSource { 152 public: 153 JSValueSource() 154 : m_offset(notAddress()) 155 , m_baseOrTag(static_cast<int8_t>(InvalidGPRReg)) 156 , m_payload(static_cast<int8_t>(InvalidGPRReg)) 157 , m_tagType(0) 158 { 159 } 160 161 JSValueSource(JSValueRegs regs) 162 : m_offset(notAddress()) 163 , m_baseOrTag(regs.tagGPR()) 164 , m_payload(regs.payloadGPR()) 165 , m_tagType(0) 166 { 167 } 168 169 JSValueSource(GPRReg tagGPR, GPRReg payloadGPR) 170 : m_offset(notAddress()) 171 , m_baseOrTag(static_cast<int8_t>(tagGPR)) 172 , m_payload(static_cast<int8_t>(payloadGPR)) 173 , m_tagType(0) 174 { 175 } 176 177 JSValueSource(MacroAssembler::Address address) 178 : m_offset(address.offset) 179 , m_baseOrTag(static_cast<int8_t>(address.base)) 180 , m_payload(static_cast<int8_t>(InvalidGPRReg)) 181 , m_tagType(0) 182 { 183 ASSERT(m_offset != notAddress()); 184 ASSERT(static_cast<GPRReg>(m_baseOrTag) != InvalidGPRReg); 185 } 186 187 static JSValueSource unboxedCell(GPRReg payloadGPR) 188 { 189 JSValueSource result; 190 result.m_offset = notAddress(); 191 result.m_baseOrTag = static_cast<int8_t>(InvalidGPRReg); 192 result.m_payload = static_cast<int8_t>(payloadGPR); 193 result.m_tagType = static_cast<int8_t>(JSValue::CellTag); 194 return result; 195 } 196 197 bool operator!() const { return static_cast<GPRReg>(m_baseOrTag) == InvalidGPRReg && static_cast<GPRReg>(m_payload) == InvalidGPRReg; } 198 199 bool isAddress() const 200 { 201 ASSERT(!!*this); 202 return m_offset != notAddress(); 203 } 204 205 int32_t offset() const 206 { 207 ASSERT(isAddress()); 208 return m_offset; 209 } 210 211 GPRReg base() const 212 { 213 ASSERT(isAddress()); 214 return static_cast<GPRReg>(m_baseOrTag); 215 } 216 217 GPRReg tagGPR() const 218 { 219 ASSERT(!isAddress() && m_baseOrTag != InvalidGPRReg); 220 return static_cast<GPRReg>(m_baseOrTag); 221 } 222 223 GPRReg payloadGPR() const 224 { 225 ASSERT(!isAddress()); 226 return static_cast<GPRReg>(m_payload); 227 } 228 229 bool hasKnownTag() const 230 { 231 ASSERT(!!*this); 232 ASSERT(!isAddress()); 233 return static_cast<GPRReg>(m_baseOrTag) == InvalidGPRReg; 234 } 235 236 uint32_t tag() const 237 { 238 return static_cast<int32_t>(m_tagType); 239 } 240 241 MacroAssembler::Address asAddress(unsigned additionalOffset = 0) const { return MacroAssembler::Address(base(), offset() + additionalOffset); } 242 243 private: 244 static inline int32_t notAddress() { return 0x80000000; } 245 246 int32_t m_offset; 247 int8_t m_baseOrTag; 248 int8_t m_payload; 249 int8_t m_tagType; // Contains the low bits of the tag. 250 }; 251 #endif 252 39 253 #if CPU(X86) 40 254 -
trunk/Source/JavaScriptCore/dfg/DFGGenerationInfo.h
r98291 r98912 340 340 GPRReg gpr() { ASSERT(m_registerFormat && m_registerFormat != DataFormatDouble); return u.gpr; } 341 341 FPRReg fpr() { ASSERT(m_registerFormat == DataFormatDouble); return u.fpr; } 342 JSValueRegs jsValueRegs() { ASSERT(m_registerFormat & DataFormatJS); return JSValueRegs(u.gpr); } 342 343 #elif USE(JSVALUE32_64) 343 344 GPRReg gpr() { ASSERT(!(m_registerFormat & DataFormatJS) && m_registerFormat != DataFormatDouble); return u.gpr; } … … 345 346 GPRReg payloadGPR() { ASSERT(m_registerFormat & DataFormatJS); return u.v.payloadGPR; } 346 347 FPRReg fpr() { ASSERT(m_registerFormat == DataFormatDouble || m_registerFormat == DataFormatJSDouble); return u.fpr; } 348 JSValueRegs jsValueRegs() { ASSERT(m_registerFormat & DataFormatJS); return JSValueRegs(u.v.tagGPR, u.v.payloadGPR); } 347 349 #endif 348 350 -
trunk/Source/JavaScriptCore/dfg/DFGGraph.h
r98179 r98912 220 220 return &m_structureTransitionData.last(); 221 221 } 222 223 ValueProfile* valueProfileFor(NodeIndex nodeIndex, CodeBlock* profiledBlock) 224 { 225 if (nodeIndex == NoNode) 226 return 0; 227 228 Node& node = at(nodeIndex); 229 230 switch (node.op) { 231 case GetLocal: { 232 if (!operandIsArgument(node.local())) 233 return 0; 234 int argument = node.local() + m_arguments.size() + RegisterFile::CallFrameHeaderSize; 235 if (node.variableAccessData() != at(m_arguments[argument]).variableAccessData()) 236 return 0; 237 return profiledBlock->valueProfileForArgument(argument); 238 } 239 240 // Nodes derives from calls need special handling because the value profile is 241 // associated with the op_call_put_result instruction. 242 case Call: 243 case Construct: 244 case ArrayPop: 245 case ArrayPush: { 246 ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_construct)); 247 return profiledBlock->valueProfileForBytecodeOffset(node.codeOrigin.bytecodeIndex + OPCODE_LENGTH(op_call)); 248 } 249 250 default: 251 if (node.hasHeapPrediction()) 252 return profiledBlock->valueProfileForBytecodeOffset(node.codeOrigin.bytecodeIndex); 253 return 0; 254 } 255 } 222 256 223 257 Vector< OwnPtr<BasicBlock> , 8> m_blocks; -
trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.h
r98878 r98912 1890 1890 return m_gprOrInvalid; 1891 1891 } 1892 JSValueRegs jsValueRegs() 1893 { 1894 return JSValueRegs(gpr()); 1895 } 1892 1896 #elif USE(JSVALUE32_64) 1893 1897 bool isDouble() { return m_isDouble; } … … 1911 1915 ASSERT(!m_isDouble); 1912 1916 return m_register.pair.payloadGPR; 1917 } 1918 1919 JSValueRegs jsValueRegs() 1920 { 1921 return JSValueRegs(tagGPR(), payloadGPR()); 1913 1922 } 1914 1923 -
trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
r98831 r98912 99 99 emitCount(counter); 100 100 #endif 101 101 102 102 // 2) Perform speculation recovery. This only comes into play when an operation 103 103 // starts mutating state before verifying the speculation it has already made. … … 122 122 } 123 123 124 // 3) Figure out how many scratch slots we'll need. We need one for every GPR/FPR 124 // 3) Refine some value profile, if appropriate. 125 126 if (!!exit.m_jsValueSource && !!exit.m_valueProfile) { 127 if (exit.m_jsValueSource.isAddress()) { 128 // We can't be sure that we have a spare register. So use the tagTypeNumberRegister, 129 // since we know how to restore it. 130 loadPtr(Address(exit.m_jsValueSource.asAddress()), GPRInfo::tagTypeNumberRegister); 131 storePtr(GPRInfo::tagTypeNumberRegister, exit.m_valueProfile->specFailBucket(0)); 132 move(TrustedImmPtr(bitwise_cast<void*>(TagTypeNumber)), GPRInfo::tagTypeNumberRegister); 133 } else 134 storePtr(exit.m_jsValueSource.gpr(), exit.m_valueProfile->specFailBucket(0)); 135 } 136 137 // 4) Figure out how many scratch slots we'll need. We need one for every GPR/FPR 125 138 // whose destination is now occupied by a DFG virtual register, and we need 126 139 // one for every displaced virtual register if there are more than … … 218 231 // between when something is computed and when it is stored. 219 232 220 // 4) Perform all reboxing of integers.233 // 5) Perform all reboxing of integers. 221 234 222 235 if (haveUnboxedInt32s) { … … 239 252 } 240 253 241 // 5) Dump all non-poisoned GPRs. For poisoned GPRs, save them into the scratch storage.254 // 6) Dump all non-poisoned GPRs. For poisoned GPRs, save them into the scratch storage. 242 255 // Note that GPRs do not have a fast change (like haveFPRs) because we expect that 243 256 // most OSR failure points will have at least one GPR that needs to be dumped. … … 263 276 264 277 if (haveFPRs) { 265 // 6) Box all doubles (relies on there being more GPRs than FPRs)278 // 7) Box all doubles (relies on there being more GPRs than FPRs) 266 279 267 280 for (int index = 0; index < exit.numberOfRecoveries(); ++index) { … … 274 287 } 275 288 276 // 7) Dump all doubles into the register file, or to the scratch storage if289 // 8) Dump all doubles into the register file, or to the scratch storage if 277 290 // the destination virtual register is poisoned. 278 291 … … 291 304 ASSERT(scratchIndex == numberOfPoisonedVirtualRegisters); 292 305 293 // 8) Reshuffle displaced virtual registers. Optimize for the case that306 // 9) Reshuffle displaced virtual registers. Optimize for the case that 294 307 // the number of displaced virtual registers is not more than the number 295 308 // of available physical registers. … … 407 420 } 408 421 409 // 9) Dump all poisoned virtual registers.422 // 10) Dump all poisoned virtual registers. 410 423 411 424 scratchIndex = 0; … … 431 444 ASSERT(scratchIndex == numberOfPoisonedVirtualRegisters); 432 445 433 // 1 0) Dump all constants. Optimize for Undefined, since that's a constant we see446 // 11) Dump all constants. Optimize for Undefined, since that's a constant we see 434 447 // often. 435 448 … … 449 462 } 450 463 451 // 1 1) Adjust the old JIT's execute counter. Since we are exiting OSR, we know464 // 12) Adjust the old JIT's execute counter. Since we are exiting OSR, we know 452 465 // that all new calls into this code will go to the new JIT, so the execute 453 466 // counter only affects call frames that performed OSR exit and call frames … … 512 525 doneAdjusting.link(this); 513 526 514 // 1 2) Load the result of the last bytecode operation into regT0.527 // 13) Load the result of the last bytecode operation into regT0. 515 528 516 529 if (exit.m_lastSetOperand != std::numeric_limits<int>::max()) 517 530 loadPtr(addressFor((VirtualRegister)exit.m_lastSetOperand), GPRInfo::cachedResultRegister); 518 531 519 // 1 3) Fix call frame(s).532 // 14) Fix call frame(s). 520 533 521 534 ASSERT(codeBlock()->alternative()->getJITType() == JITCode::BaselineJIT); … … 553 566 addPtr(Imm32(exit.m_codeOrigin.inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister); 554 567 555 // 1 4) Jump into the corresponding baseline JIT code.568 // 15) Jump into the corresponding baseline JIT code. 556 569 557 570 CodeBlock* baselineCodeBlock = baselineCodeBlockFor(exit.m_codeOrigin); -
trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h
r98405 r98912 425 425 } 426 426 427 ValueProfile* valueProfileFor(NodeIndex nodeIndex) 428 { 429 if (nodeIndex == NoNode) 430 return 0; 431 432 return m_graph.valueProfileFor(nodeIndex, baselineCodeBlockFor(m_graph[nodeIndex].codeOrigin)); 433 } 434 427 435 private: 428 436 // Internal implementation to compile. -
trunk/Source/JavaScriptCore/dfg/DFGJITCompiler32_64.cpp
r98831 r98912 92 92 } 93 93 94 // 3) Figure out how many scratch slots we'll need. We need one for every GPR/FPR 94 // 3) Refine some value profile, if appropriate. 95 96 if (!!exit.m_jsValueSource && !!exit.m_valueProfile) { 97 if (exit.m_jsValueSource.isAddress()) { 98 // Save a register so we can use it. 99 GPRReg scratch = GPRInfo::regT0; 100 if (scratch == exit.m_jsValueSource.base()) 101 scratch = GPRInfo::regT1; 102 EncodedJSValue* scratchBuffer = static_cast<EncodedJSValue*>(globalData()->scratchBufferForSize(sizeof(uint32_t))); 103 store32(scratch, scratchBuffer); 104 load32(exit.m_jsValueSource.asAddress(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), scratch); 105 store32(scratch, &bitwise_cast<EncodedValueDescriptor*>(exit.m_valueProfile->specFailBucket(0))->asBits.tag); 106 load32(exit.m_jsValueSource.asAddress(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), scratch); 107 store32(scratch, &bitwise_cast<EncodedValueDescriptor*>(exit.m_valueProfile->specFailBucket(0))->asBits.payload); 108 load32(scratchBuffer, scratch); 109 } else if (exit.m_jsValueSource.hasKnownTag()) { 110 store32(Imm32(exit.m_jsValueSource.tag()), &bitwise_cast<EncodedValueDescriptor*>(exit.m_valueProfile->specFailBucket(0))->asBits.tag); 111 store32(exit.m_jsValueSource.payloadGPR(), &bitwise_cast<EncodedValueDescriptor*>(exit.m_valueProfile->specFailBucket(0))->asBits.payload); 112 } else { 113 store32(exit.m_jsValueSource.tagGPR(), &bitwise_cast<EncodedValueDescriptor*>(exit.m_valueProfile->specFailBucket(0))->asBits.tag); 114 store32(exit.m_jsValueSource.payloadGPR(), &bitwise_cast<EncodedValueDescriptor*>(exit.m_valueProfile->specFailBucket(0))->asBits.payload); 115 } 116 } 117 118 // 4) Figure out how many scratch slots we'll need. We need one for every GPR/FPR 95 119 // whose destination is now occupied by a DFG virtual register, and we need 96 120 // one for every displaced virtual register if there are more than … … 180 204 // between when something is computed and when it is stored. 181 205 182 // 4) Perform all reboxing of integers and cells, except for those in registers.206 // 5) Perform all reboxing of integers and cells, except for those in registers. 183 207 184 208 if (haveUnboxedInt32InRegisterFile || haveUnboxedCellInRegisterFile || haveUnboxedBooleanInRegisterFile) { … … 204 228 } 205 229 206 // 5) Dump all non-poisoned GPRs. For poisoned GPRs, save them into the scratch storage.230 // 6) Dump all non-poisoned GPRs. For poisoned GPRs, save them into the scratch storage. 207 231 // Note that GPRs do not have a fast change (like haveFPRs) because we expect that 208 232 // most OSR failure points will have at least one GPR that needs to be dumped. … … 261 285 262 286 if (haveFPRs) { 263 // 6) Box all doubles (relies on there being more GPRs than FPRs)287 // 7) Box all doubles (relies on there being more GPRs than FPRs) 264 288 // For JSValue32_64, no need to box doubles. 265 289 266 // 7) Dump all doubles into the register file, or to the scratch storage if290 // 8) Dump all doubles into the register file, or to the scratch storage if 267 291 // the destination virtual register is poisoned. 268 292 … … 280 304 ASSERT(scratchIndex == numberOfPoisonedVirtualRegisters); 281 305 282 // 8) Reshuffle displaced virtual registers. Optimize for the case that306 // 9) Reshuffle displaced virtual registers. Optimize for the case that 283 307 // the number of displaced virtual registers is not more than the number 284 308 // of available physical registers. … … 351 375 } 352 376 353 // 9) Dump all poisoned virtual registers.377 // 10) Dump all poisoned virtual registers. 354 378 355 379 scratchIndex = 0; … … 380 404 ASSERT(scratchIndex == numberOfPoisonedVirtualRegisters); 381 405 382 // 1 0) Dump all constants. Optimize for Undefined, since that's a constant we see406 // 11) Dump all constants. Optimize for Undefined, since that's a constant we see 383 407 // often. 384 408 … … 403 427 } 404 428 405 // 1 1) Adjust the old JIT's execute counter. Since we are exiting OSR, we know429 // 12) Adjust the old JIT's execute counter. Since we are exiting OSR, we know 406 430 // that all new calls into this code will go to the new JIT, so the execute 407 431 // counter only affects call frames that performed OSR exit and call frames … … 466 490 doneAdjusting.link(this); 467 491 468 // 1 2) Load the result of the last bytecode operation into regT0.492 // 13) Load the result of the last bytecode operation into regT0. 469 493 470 494 if (exit.m_lastSetOperand != std::numeric_limits<int>::max()) { … … 473 497 } 474 498 475 // 1 3) Fix call frame (s).499 // 14) Fix call frame (s). 476 500 477 501 ASSERT(codeBlock()->alternative()->getJITType() == JITCode::BaselineJIT); … … 513 537 addPtr(Imm32(exit.m_codeOrigin.inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister); 514 538 515 // 1 4) Jump into the corresponding baseline JIT code.539 // 15) Jump into the corresponding baseline JIT code. 516 540 517 541 CodeBlock* baselineCodeBlock = baselineCodeBlockFor(exit.m_codeOrigin); -
trunk/Source/JavaScriptCore/dfg/DFGPropagator.cpp
r98179 r98912 441 441 } 442 442 443 case GetById: 443 case GetById: { 444 if (node.getHeapPrediction()) 445 changed |= mergePrediction(node.getHeapPrediction()); 446 else if (m_codeBlock->identifier(node.identifierNumber()) == m_globalData.propertyNames->length) { 447 // If there is no prediction from value profiles, check if we might be 448 // able to infer the type ourselves. 449 bool isArray = isArrayPrediction(m_graph[node.child1()].prediction()); 450 bool isString = isStringPrediction(m_graph[node.child1()].prediction()); 451 bool isByteArray = m_graph[node.child1()].shouldSpeculateByteArray(); 452 if (isArray || isString || isByteArray) 453 changed |= mergePrediction(PredictInt32); 454 } 455 break; 456 } 457 444 458 case GetMethod: 445 459 case GetByVal: { -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r98674 r98912 116 116 #endif 117 117 118 OSRExit::OSRExit(MacroAssembler::Jump check, SpeculativeJIT* jit, unsigned recoveryIndex) 119 : m_check(check) 118 OSRExit::OSRExit(JSValueSource jsValueSource, ValueProfile* valueProfile, MacroAssembler::Jump check, SpeculativeJIT* jit, unsigned recoveryIndex) 119 : m_jsValueSource(jsValueSource) 120 , m_valueProfile(valueProfile) 121 , m_check(check) 120 122 , m_nodeIndex(jit->m_compileIndex) 121 123 , m_codeOrigin(jit->m_codeOriginForOSR) … … 180 182 181 183 if (!predictionCheck(m_state.forNode(node.child1()).m_type)) 182 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(vptr)));184 speculationCheck(JSValueSource::unboxedCell(op1GPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(vptr))); 183 185 if (!predictionCheck(m_state.forNode(node.child2()).m_type)) 184 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR), MacroAssembler::TrustedImmPtr(vptr)));186 speculationCheck(JSValueSource::unboxedCell(op2GPR), node.child2(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR), MacroAssembler::TrustedImmPtr(vptr))); 185 187 186 188 addBranch(m_jit.branchPtr(condition, op1GPR, op2GPR), taken); … … 393 395 #if USE(JSVALUE64) 394 396 if (isInt32Prediction(predictedType)) 395 speculationCheck( m_jit.branchPtr(MacroAssembler::Below, JITCompiler::addressFor(virtualRegister), GPRInfo::tagTypeNumberRegister));397 speculationCheck(JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::Below, JITCompiler::addressFor(virtualRegister), GPRInfo::tagTypeNumberRegister)); 396 398 else if (isArrayPrediction(predictedType)) { 397 399 GPRTemporary temp(this); 398 400 m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr()); 399 speculationCheck( m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));400 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));401 speculationCheck(JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister)); 402 speculationCheck(JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr))); 401 403 } else if (isByteArrayPrediction(predictedType)) { 402 404 GPRTemporary temp(this); 403 405 m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr()); 404 speculationCheck( m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));405 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));406 speculationCheck(JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister)); 407 speculationCheck(JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr))); 406 408 } else if (isBooleanPrediction(predictedType)) { 407 409 GPRTemporary temp(this); 408 410 m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr()); 409 411 m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), temp.gpr()); 410 speculationCheck( m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), TrustedImm32(static_cast<int32_t>(~1))));412 speculationCheck(JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), TrustedImm32(static_cast<int32_t>(~1)))); 411 413 } 412 414 #else 413 415 if (isInt32Prediction(predictedType)) 414 speculationCheck( m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag)));416 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag))); 415 417 else if (isArrayPrediction(predictedType)) { 416 418 GPRTemporary temp(this); 417 419 m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr()); 418 speculationCheck( m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));420 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag))); 419 421 m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr()); 420 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));422 speculationCheck(JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr))); 421 423 } else if (isByteArrayPrediction(predictedType)) { 422 424 GPRTemporary temp(this); 423 425 m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr()); 424 speculationCheck( m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));426 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag))); 425 427 m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr()); 426 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));428 speculationCheck(JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr))); 427 429 } else if (isBooleanPrediction(predictedType)) 428 speculationCheck( m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::BooleanTag)));430 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::BooleanTag))); 429 431 #endif 430 432 } … … 587 589 588 590 if (!isStringPrediction(m_state.forNode(node.child1()).m_type)) 589 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(stringReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));591 speculationCheck(JSValueSource::unboxedCell(stringReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(stringReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr))); 590 592 591 593 // unsigned comparison so we can filter out negative indices and indices that are too large 592 speculationCheck( m_jit.branch32(MacroAssembler::AboveOrEqual, indexReg, MacroAssembler::Address(stringReg, JSString::offsetOfLength())));594 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, indexReg, MacroAssembler::Address(stringReg, JSString::offsetOfLength()))); 593 595 594 596 GPRTemporary scratch(this); … … 598 600 599 601 // Speculate that we're not accessing a rope 600 speculationCheck( m_jit.branchTest32(MacroAssembler::Zero, scratchReg));602 speculationCheck(JSValueRegs(), NoNode, m_jit.branchTest32(MacroAssembler::Zero, scratchReg)); 601 603 602 604 // Load the character into scratchReg … … 627 629 628 630 if (!isStringPrediction(m_state.forNode(node.child1()).m_type)) 629 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));631 speculationCheck(JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr))); 630 632 631 633 // unsigned comparison so we can filter out negative indices and indices that are too large 632 speculationCheck( m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSString::offsetOfLength())));634 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSString::offsetOfLength()))); 633 635 634 636 GPRTemporary scratch(this); … … 638 640 639 641 // Speculate that we're not accessing a rope 640 speculationCheck( m_jit.branchTest32(MacroAssembler::Zero, scratchReg));642 speculationCheck(JSValueRegs(), NoNode, m_jit.branchTest32(MacroAssembler::Zero, scratchReg)); 641 643 642 644 // Load the character into scratchReg … … 653 655 654 656 // We only support ascii characters 655 speculationCheck( m_jit.branch32(MacroAssembler::AboveOrEqual, scratchReg, TrustedImm32(0x100)));657 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, scratchReg, TrustedImm32(0x100))); 656 658 657 659 // 8 bit string values don't need the isASCII check. … … 662 664 m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.globalData()->smallStrings.singleCharacterStrings()), smallStringsReg); 663 665 m_jit.loadPtr(MacroAssembler::BaseIndex(smallStringsReg, scratchReg, MacroAssembler::ScalePtr, 0), scratchReg); 664 speculationCheck( m_jit.branchTest32(MacroAssembler::Zero, scratchReg));666 speculationCheck(JSValueRegs(), NoNode, m_jit.branchTest32(MacroAssembler::Zero, scratchReg)); 665 667 cellResult(scratchReg, m_compileIndex); 666 668 } … … 729 731 730 732 if (!isByteArrayPrediction(m_state.forNode(baseIndex).m_type)) 731 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));733 speculationCheck(JSValueSource::unboxedCell(base), baseIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr))); 732 734 GPRTemporary value; 733 735 GPRReg valueGPR; … … 736 738 JSValue jsValue = valueOfJSConstant(valueIndex); 737 739 if (!jsValue.isNumber()) { 738 terminateSpeculativeExecution( );740 terminateSpeculativeExecution(JSValueRegs(), NoNode); 739 741 noResult(m_compileIndex); 740 742 return; … … 797 799 798 800 if (!isByteArrayPrediction(m_state.forNode(node.child1()).m_type)) 799 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));801 speculationCheck(JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr))); 800 802 801 803 // Load the character into scratchReg … … 805 807 806 808 // unsigned comparison so we can filter out negative indices and indices that are too large 807 speculationCheck( m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ByteArray::offsetOfSize())));809 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ByteArray::offsetOfSize()))); 808 810 809 811 m_jit.load8(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesOne, ByteArray::offsetOfData()), storageReg); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r98291 r98912 339 339 // going into baseline code. 340 340 struct OSRExit { 341 OSRExit(MacroAssembler::Jump, SpeculativeJIT*, unsigned recoveryIndex = 0); 341 OSRExit(JSValueSource, ValueProfile*, MacroAssembler::Jump, SpeculativeJIT*, unsigned recoveryIndex = 0); 342 343 JSValueSource m_jsValueSource; 344 ValueProfile* m_valueProfile; 342 345 343 346 MacroAssembler::Jump m_check; … … 506 509 507 510 // Add a speculation check without additional recovery. 508 void speculationCheck( MacroAssembler::Jump jumpToFail)511 void speculationCheck(JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::Jump jumpToFail) 509 512 { 510 513 if (!m_compileOkay) 511 514 return; 512 m_osrExits.append(OSRExit(j umpToFail, this));515 m_osrExits.append(OSRExit(jsValueSource, m_jit.valueProfileFor(nodeIndex), jumpToFail, this)); 513 516 } 514 517 // Add a speculation check with additional recovery. 515 void speculationCheck( MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)518 void speculationCheck(JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery) 516 519 { 517 520 if (!m_compileOkay) 518 521 return; 519 522 m_speculationRecoveryList.append(recovery); 520 m_osrExits.append(OSRExit(j umpToFail, this, m_speculationRecoveryList.size()));523 m_osrExits.append(OSRExit(jsValueSource, m_jit.valueProfileFor(nodeIndex), jumpToFail, this, m_speculationRecoveryList.size())); 521 524 } 522 525 523 526 // Called when we statically determine that a speculation will fail. 524 void terminateSpeculativeExecution( )527 void terminateSpeculativeExecution(JSValueRegs jsValueRegs, NodeIndex nodeIndex) 525 528 { 526 529 #if DFG_ENABLE(DEBUG_VERBOSE) … … 529 532 if (!m_compileOkay) 530 533 return; 531 speculationCheck( m_jit.jump());534 speculationCheck(jsValueRegs, nodeIndex, m_jit.jump()); 532 535 m_compileOkay = false; 533 536 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r98291 r98912 69 69 return gpr; 70 70 } 71 terminateSpeculativeExecution( );71 terminateSpeculativeExecution(JSValueRegs(), NoNode); 72 72 returnFormat = DataFormatInteger; 73 73 return allocate(); … … 81 81 // If we know this was spilled as an integer we can fill without checking. 82 82 if (spillFormat != DataFormatJSInteger) 83 speculationCheck( m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag)));83 speculationCheck(JSValueSource(JITCompiler::addressFor(virtualRegister)), nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag))); 84 84 85 85 m_jit.load32(JITCompiler::payloadFor(virtualRegister), gpr); … … 97 97 m_gprs.lock(payloadGPR); 98 98 if (info.registerFormat() != DataFormatJSInteger) 99 speculationCheck( m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::Int32Tag)));99 speculationCheck(JSValueRegs(tagGPR, payloadGPR), nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::Int32Tag))); 100 100 m_gprs.unlock(tagGPR); 101 101 m_gprs.release(tagGPR); … … 121 121 case DataFormatJSCell: 122 122 case DataFormatJSBoolean: { 123 terminateSpeculativeExecution( );123 terminateSpeculativeExecution(JSValueRegs(), NoNode); 124 124 returnFormat = DataFormatInteger; 125 125 return allocate(); … … 172 172 return fpr; 173 173 } else { 174 terminateSpeculativeExecution( );174 terminateSpeculativeExecution(JSValueRegs(), NoNode); 175 175 return fprAllocate(); 176 176 } … … 188 188 FPRReg fpr = fprAllocate(); 189 189 JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag)); 190 speculationCheck( m_jit.branch32(MacroAssembler::AboveOrEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::LowestTag)));190 speculationCheck(JSValueSource(JITCompiler::addressFor(virtualRegister)), nodeIndex, m_jit.branch32(MacroAssembler::AboveOrEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::LowestTag))); 191 191 m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr); 192 192 JITCompiler::Jump hasUnboxedDouble = m_jit.jump(); … … 210 210 211 211 case DataFormatCell: 212 terminateSpeculativeExecution( );212 terminateSpeculativeExecution(JSValueRegs(), NoNode); 213 213 return fprAllocate(); 214 214 … … 229 229 FPRTemporary scratch(this); 230 230 JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, tagGPR, TrustedImm32(JSValue::Int32Tag)); 231 speculationCheck( m_jit.branch32(MacroAssembler::AboveOrEqual, tagGPR, TrustedImm32(JSValue::LowestTag)));231 speculationCheck(JSValueRegs(tagGPR, payloadGPR), nodeIndex, m_jit.branch32(MacroAssembler::AboveOrEqual, tagGPR, TrustedImm32(JSValue::LowestTag))); 232 232 unboxDouble(tagGPR, payloadGPR, fpr, scratch.fpr()); 233 233 hasUnboxedDouble = m_jit.jump(); … … 292 292 return gpr; 293 293 } 294 terminateSpeculativeExecution( );294 terminateSpeculativeExecution(JSValueRegs(), NoNode); 295 295 return gpr; 296 296 } … … 298 298 m_jit.load32(JITCompiler::tagFor(virtualRegister), gpr); 299 299 if (info.spillFormat() != DataFormatJSCell) 300 speculationCheck( m_jit.branch32(MacroAssembler::NotEqual, gpr, TrustedImm32(JSValue::CellTag)));300 speculationCheck(JSValueSource(JITCompiler::addressFor(virtualRegister)), nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, gpr, TrustedImm32(JSValue::CellTag))); 301 301 m_jit.load32(JITCompiler::payloadFor(virtualRegister), gpr); 302 302 m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled); … … 318 318 m_gprs.lock(payloadGPR); 319 319 if (info.spillFormat() != DataFormatJSCell) 320 speculationCheck( m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::CellTag)));320 speculationCheck(JSValueRegs(tagGPR, payloadGPR), nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::CellTag))); 321 321 m_gprs.unlock(tagGPR); 322 322 m_gprs.release(tagGPR); … … 333 333 case DataFormatJSBoolean: 334 334 case DataFormatBoolean: { 335 terminateSpeculativeExecution( );335 terminateSpeculativeExecution(JSValueRegs(), NoNode); 336 336 return allocate(); 337 337 } … … 366 366 return gpr; 367 367 } 368 terminateSpeculativeExecution( );368 terminateSpeculativeExecution(JSValueRegs(), NoNode); 369 369 return gpr; 370 370 } … … 373 373 374 374 if (info.spillFormat() != DataFormatJSBoolean) 375 speculationCheck( m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::BooleanTag)));375 speculationCheck(JSValueSource(JITCompiler::addressFor(virtualRegister)), nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::BooleanTag))); 376 376 377 377 m_jit.load32(JITCompiler::payloadFor(virtualRegister), gpr); … … 393 393 m_gprs.lock(payloadGPR); 394 394 if (info.registerFormat() != DataFormatJSBoolean) 395 speculationCheck( m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::BooleanTag)));395 speculationCheck(JSValueRegs(tagGPR, payloadGPR), nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::BooleanTag))); 396 396 397 397 m_gprs.unlock(tagGPR); … … 409 409 case DataFormatJSCell: 410 410 case DataFormatCell: { 411 terminateSpeculativeExecution( );411 terminateSpeculativeExecution(JSValueRegs(), NoNode); 412 412 return allocate(); 413 413 } … … 450 450 451 451 if (!predictionCheck(m_state.forNode(node.child1()).m_type)) 452 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(vptr)));452 speculationCheck(JSValueSource::unboxedCell(op1GPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(vptr))); 453 453 if (!predictionCheck(m_state.forNode(node.child2()).m_type)) 454 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR), MacroAssembler::TrustedImmPtr(vptr)));454 speculationCheck(JSValueSource::unboxedCell(op2GPR), node.child2(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR), MacroAssembler::TrustedImmPtr(vptr))); 455 455 456 456 MacroAssembler::Jump falseCase = m_jit.branchPtr(MacroAssembler::NotEqual, op1GPR, op2GPR); … … 535 535 MacroAssembler::Jump notCell = m_jit.branch32(MacroAssembler::NotEqual, valueTagGPR, TrustedImm32(JSValue::CellTag)); 536 536 if (needSpeculationCheck) 537 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valuePayloadGPR), MacroAssembler::TrustedImmPtr(vptr)));537 speculationCheck(JSValueRegs(valueTagGPR, valuePayloadGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valuePayloadGPR), MacroAssembler::TrustedImmPtr(vptr))); 538 538 m_jit.move(TrustedImm32(0), resultPayloadGPR); 539 539 MacroAssembler::Jump done = m_jit.jump(); … … 545 545 m_jit.move(valueTagGPR, resultPayloadGPR); 546 546 m_jit.or32(TrustedImm32(1), resultPayloadGPR); 547 speculationCheck( m_jit.branch32(MacroAssembler::NotEqual, resultPayloadGPR, TrustedImm32(JSValue::NullTag)));547 speculationCheck(JSValueRegs(valueTagGPR, valuePayloadGPR), nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, resultPayloadGPR, TrustedImm32(JSValue::NullTag))); 548 548 } 549 549 m_jit.move(TrustedImm32(1), resultPayloadGPR); … … 592 592 JSValueOperand value(this, node.child1()); 593 593 GPRTemporary resultPayload(this, value, false); 594 speculationCheck( m_jit.branch32(JITCompiler::NotEqual, value.tagGPR(), TrustedImm32(JSValue::BooleanTag)));594 speculationCheck(JSValueRegs(value.tagGPR(), value.payloadGPR()), node.child1(), m_jit.branch32(JITCompiler::NotEqual, value.tagGPR(), TrustedImm32(JSValue::BooleanTag))); 595 595 m_jit.move(value.payloadGPR(), resultPayload.gpr()); 596 596 m_jit.xor32(TrustedImm32(1), resultPayload.gpr()); … … 636 636 MacroAssembler::Jump notCell = m_jit.branch32(MacroAssembler::NotEqual, valueTagGPR, TrustedImm32(JSValue::CellTag)); 637 637 if (needSpeculationCheck) 638 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valuePayloadGPR), MacroAssembler::TrustedImmPtr(vptr)));638 speculationCheck(JSValueRegs(valueTagGPR, valuePayloadGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valuePayloadGPR), MacroAssembler::TrustedImmPtr(vptr))); 639 639 addBranch(m_jit.jump(), taken); 640 640 … … 645 645 m_jit.move(valueTagGPR, scratchGPR); 646 646 m_jit.or32(TrustedImm32(1), scratchGPR); 647 speculationCheck( m_jit.branch32(MacroAssembler::NotEqual, scratchGPR, TrustedImm32(JSValue::NullTag)));647 speculationCheck(JSValueRegs(valueTagGPR, valuePayloadGPR), nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, scratchGPR, TrustedImm32(JSValue::NullTag))); 648 648 } 649 649 … … 748 748 // If we have no prediction for this local, then don't attempt to compile. 749 749 if (prediction == PredictNone) { 750 terminateSpeculativeExecution( );750 terminateSpeculativeExecution(JSValueRegs(), NoNode); 751 751 break; 752 752 } … … 826 826 GPRReg cellGPR = cell.gpr(); 827 827 if (!isArrayPrediction(m_state.forNode(node.child1()).m_type)) 828 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));828 speculationCheck(JSValueSource::unboxedCell(cellGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr))); 829 829 m_jit.storePtr(cellGPR, JITCompiler::payloadFor(node.local())); 830 830 noResult(m_compileIndex); … … 833 833 GPRReg cellGPR = cell.gpr(); 834 834 if (!isByteArrayPrediction(m_state.forNode(node.child1()).m_type)) 835 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));835 speculationCheck(JSValueSource::unboxedCell(cellGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr))); 836 836 m_jit.storePtr(cellGPR, JITCompiler::payloadFor(node.local())); 837 837 noResult(m_compileIndex); … … 939 939 940 940 // Test the operand is positive. 941 speculationCheck( m_jit.branch32(MacroAssembler::LessThan, op1.gpr(), TrustedImm32(0)));941 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, op1.gpr(), TrustedImm32(0))); 942 942 943 943 m_jit.move(op1.gpr(), result.gpr()); … … 987 987 m_jit.add32(Imm32(imm1), result.gpr()); 988 988 } else 989 speculationCheck( m_jit.branchAdd32(MacroAssembler::Overflow, op2.gpr(), Imm32(imm1), result.gpr()));989 speculationCheck(JSValueRegs(), NoNode, m_jit.branchAdd32(MacroAssembler::Overflow, op2.gpr(), Imm32(imm1), result.gpr())); 990 990 991 991 integerResult(result.gpr(), m_compileIndex); … … 1002 1002 m_jit.add32(Imm32(imm2), result.gpr()); 1003 1003 } else 1004 speculationCheck( m_jit.branchAdd32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));1004 speculationCheck(JSValueRegs(), NoNode, m_jit.branchAdd32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr())); 1005 1005 1006 1006 integerResult(result.gpr(), m_compileIndex); … … 1027 1027 1028 1028 if (gpr1 == gprResult) 1029 speculationCheck( check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr2));1029 speculationCheck(JSValueRegs(), NoNode, check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr2)); 1030 1030 else if (gpr2 == gprResult) 1031 speculationCheck( check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr1));1031 speculationCheck(JSValueRegs(), NoNode, check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr1)); 1032 1032 else 1033 speculationCheck( check);1033 speculationCheck(JSValueRegs(), NoNode, check); 1034 1034 } 1035 1035 … … 1067 1067 m_jit.sub32(Imm32(imm2), result.gpr()); 1068 1068 } else 1069 speculationCheck( m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));1069 speculationCheck(JSValueRegs(), NoNode, m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr())); 1070 1070 1071 1071 integerResult(result.gpr(), m_compileIndex); … … 1081 1081 m_jit.sub32(op2.gpr(), result.gpr()); 1082 1082 } else 1083 speculationCheck( m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), op2.gpr(), result.gpr()));1083 speculationCheck(JSValueRegs(), NoNode, m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), op2.gpr(), result.gpr())); 1084 1084 1085 1085 integerResult(result.gpr(), m_compileIndex); … … 1116 1116 // domain. 1117 1117 1118 speculationCheck( m_jit.branchMul32(MacroAssembler::Overflow, reg1, reg2, result.gpr()));1118 speculationCheck(JSValueRegs(), NoNode, m_jit.branchMul32(MacroAssembler::Overflow, reg1, reg2, result.gpr())); 1119 1119 1120 1120 // Check for negative zero, if the users of this node care about such things. 1121 1121 if (!nodeCanIgnoreNegativeZero(node.arithNodeFlags())) { 1122 1122 MacroAssembler::Jump resultNonZero = m_jit.branchTest32(MacroAssembler::NonZero, result.gpr()); 1123 speculationCheck( m_jit.branch32(MacroAssembler::LessThan, reg1, TrustedImm32(0)));1124 speculationCheck( m_jit.branch32(MacroAssembler::LessThan, reg2, TrustedImm32(0)));1123 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, reg1, TrustedImm32(0))); 1124 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, reg2, TrustedImm32(0))); 1125 1125 resultNonZero.link(&m_jit); 1126 1126 } … … 1152 1152 GPRReg op2GPR = op2.gpr(); 1153 1153 1154 speculationCheck( m_jit.branchTest32(JITCompiler::Zero, op2GPR));1154 speculationCheck(JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::Zero, op2GPR)); 1155 1155 1156 1156 // If the user cares about negative zero, then speculate that we're not about … … 1158 1158 if (!nodeCanIgnoreNegativeZero(node.arithNodeFlags())) { 1159 1159 MacroAssembler::Jump numeratorNonZero = m_jit.branchTest32(MacroAssembler::NonZero, op1GPR); 1160 speculationCheck( m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0)));1160 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0))); 1161 1161 numeratorNonZero.link(&m_jit); 1162 1162 } … … 1178 1178 // Check that there was no remainder. If there had been, then we'd be obligated to 1179 1179 // produce a double result instead. 1180 speculationCheck( m_jit.branchTest32(JITCompiler::NonZero, edx.gpr()));1180 speculationCheck(JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::NonZero, edx.gpr())); 1181 1181 1182 1182 integerResult(eax.gpr(), m_compileIndex); … … 1222 1222 GPRReg op2Gpr = op2.gpr(); 1223 1223 1224 speculationCheck( m_jit.branchTest32(JITCompiler::Zero, op2Gpr));1224 speculationCheck(JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::Zero, op2Gpr)); 1225 1225 1226 1226 GPRReg temp2 = InvalidGPRReg; … … 1252 1252 m_jit.add32(scratch.gpr(), result.gpr()); 1253 1253 m_jit.xor32(scratch.gpr(), result.gpr()); 1254 speculationCheck( m_jit.branch32(MacroAssembler::Equal, result.gpr(), MacroAssembler::TrustedImm32(1 << 31)));1254 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Equal, result.gpr(), MacroAssembler::TrustedImm32(1 << 31))); 1255 1255 integerResult(result.gpr(), m_compileIndex); 1256 1256 break; … … 1439 1439 // If we have predicted the base to be type array, we can skip the check. 1440 1440 if (!isArrayPrediction(m_state.forNode(node.child1()).m_type)) 1441 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));1442 speculationCheck( m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));1441 speculationCheck(JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr))); 1442 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset()))); 1443 1443 1444 1444 // FIXME: In cases where there are subsequent by_val accesses to the same base it might help to cache … … 1446 1446 // then we'll need to allocate a new temporary for result. 1447 1447 m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag.gpr()); 1448 speculationCheck( m_jit.branch32(MacroAssembler::Equal, resultTag.gpr(), TrustedImm32(JSValue::EmptyValueTag)));1448 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Equal, resultTag.gpr(), TrustedImm32(JSValue::EmptyValueTag))); 1449 1449 m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), storageReg); 1450 1450 … … 1497 1497 // If we have predicted the base to be type array, we can skip the check. 1498 1498 if (!isArrayPrediction(m_state.forNode(node.child1()).m_type)) 1499 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));1499 speculationCheck(JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr))); 1500 1500 1501 1501 base.use(); … … 1585 1585 1586 1586 if (!isArrayPrediction(m_state.forNode(node.child1()).m_type)) 1587 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));1587 speculationCheck(JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr))); 1588 1588 1589 1589 m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), storageGPR); … … 1591 1591 1592 1592 // Refuse to handle bizarre lengths. 1593 speculationCheck( m_jit.branch32(MacroAssembler::Above, storageLengthGPR, TrustedImm32(0x7ffffffe)));1593 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Above, storageLengthGPR, TrustedImm32(0x7ffffffe))); 1594 1594 1595 1595 MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(baseGPR, JSArray::vectorLengthOffset())); … … 1631 1631 1632 1632 if (!isArrayPrediction(m_state.forNode(node.child1()).m_type)) 1633 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));1633 speculationCheck(JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr))); 1634 1634 1635 1635 m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), storageGPR); … … 1752 1752 // We expect that throw statements are rare and are intended to exit the code block 1753 1753 // anyway, so we just OSR back to the old JIT for now. 1754 terminateSpeculativeExecution( );1754 terminateSpeculativeExecution(JSValueRegs(), NoNode); 1755 1755 break; 1756 1756 } … … 1898 1898 m_jit.move(thisValueTagGPR, scratchGPR); 1899 1899 m_jit.or32(TrustedImm32(1), scratchGPR); 1900 speculationCheck(m_jit.branch32(MacroAssembler::NotEqual, scratchGPR, TrustedImm32(JSValue::NullTag))); 1900 // This is hard. It would be better to save the value, but we can't quite do it, 1901 // since this operation does not otherwise get the payload. 1902 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, scratchGPR, TrustedImm32(JSValue::NullTag))); 1901 1903 1902 1904 m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.codeBlock()->globalObject()), scratchGPR); … … 1912 1914 1913 1915 if (!isObjectPrediction(m_state.forNode(node.child1()).m_type)) 1914 speculationCheck( m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(thisValueGPR), JITCompiler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));1916 speculationCheck(JSValueSource::unboxedCell(thisValueGPR), node.child1(), m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(thisValueGPR), JITCompiler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr))); 1915 1917 1916 1918 m_jit.move(thisValueGPR, resultGPR); … … 1957 1959 if (at(node.child1()).shouldSpeculateFinalObject()) { 1958 1960 if (!isFinalObjectPrediction(m_state.forNode(node.child1()).m_type)) 1959 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(protoGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsFinalObjectVPtr)));1961 speculationCheck(JSValueSource::unboxedCell(protoGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(protoGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsFinalObjectVPtr))); 1960 1962 } else { 1961 1963 m_jit.loadPtr(MacroAssembler::Address(protoGPR, JSCell::structureOffset()), scratchGPR); … … 2065 2067 2066 2068 case GetById: { 2069 if (!node.prediction()) { 2070 terminateSpeculativeExecution(JSValueRegs(), NoNode); 2071 break; 2072 } 2073 2067 2074 SpeculateCellOperand base(this, node.child1()); 2068 2075 GPRTemporary resultTag(this, base); … … 2095 2102 2096 2103 if (!isArrayPrediction(m_state.forNode(node.child1()).m_type)) 2097 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));2104 speculationCheck(JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr))); 2098 2105 2099 2106 m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), resultGPR); 2100 2107 m_jit.load32(MacroAssembler::Address(resultGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)), resultGPR); 2101 2108 2102 speculationCheck( m_jit.branch32(MacroAssembler::LessThan, resultGPR, MacroAssembler::TrustedImm32(0)));2109 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, resultGPR, MacroAssembler::TrustedImm32(0))); 2103 2110 2104 2111 integerResult(resultGPR, m_compileIndex); … … 2114 2121 2115 2122 if (!isStringPrediction(m_state.forNode(node.child1()).m_type)) 2116 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));2123 speculationCheck(JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr))); 2117 2124 2118 2125 m_jit.load32(MacroAssembler::Address(baseGPR, JSString::offsetOfLength()), resultGPR); … … 2130 2137 2131 2138 if (!isByteArrayPrediction(m_state.forNode(node.child1()).m_type)) 2132 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));2139 speculationCheck(JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr))); 2133 2140 2134 2141 m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSByteArray::offsetOfStorage()), resultGPR); … … 2141 2148 case CheckFunction: { 2142 2149 SpeculateCellOperand function(this, node.child1()); 2143 speculationCheck( m_jit.branchPtr(JITCompiler::NotEqual, function.gpr(), JITCompiler::TrustedImmPtr(node.function())));2150 speculationCheck(JSValueRegs(), NoNode, m_jit.branchPtr(JITCompiler::NotEqual, function.gpr(), JITCompiler::TrustedImmPtr(node.function()))); 2144 2151 noResult(m_compileIndex); 2145 2152 break; … … 2157 2164 2158 2165 if (node.structureSet().size() == 1) 2159 speculationCheck( m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(base.gpr(), JSCell::structureOffset()), JITCompiler::TrustedImmPtr(node.structureSet()[0])));2166 speculationCheck(JSValueRegs(), NoNode, m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(base.gpr(), JSCell::structureOffset()), JITCompiler::TrustedImmPtr(node.structureSet()[0]))); 2160 2167 else { 2161 2168 GPRTemporary structure(this); … … 2168 2175 done.append(m_jit.branchPtr(JITCompiler::Equal, structure.gpr(), JITCompiler::TrustedImmPtr(node.structureSet()[i]))); 2169 2176 2170 speculationCheck( m_jit.branchPtr(JITCompiler::NotEqual, structure.gpr(), JITCompiler::TrustedImmPtr(node.structureSet().last())));2177 speculationCheck(JSValueRegs(), NoNode, m_jit.branchPtr(JITCompiler::NotEqual, structure.gpr(), JITCompiler::TrustedImmPtr(node.structureSet().last()))); 2171 2178 2172 2179 done.link(&m_jit); … … 2279 2286 2280 2287 if (!m_state.forNode(node.child1()).m_structure.doesNotContainAnyOtherThan(methodCheckData.structure)) 2281 speculationCheck( m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), JITCompiler::TrustedImmPtr(methodCheckData.structure)));2288 speculationCheck(JSValueRegs(), NoNode, m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), JITCompiler::TrustedImmPtr(methodCheckData.structure))); 2282 2289 if (methodCheckData.prototype != m_jit.codeBlock()->globalObject()->methodCallDummy()) { 2283 2290 m_jit.move(JITCompiler::TrustedImmPtr(methodCheckData.prototype->structureAddress()), scratchGPR); 2284 speculationCheck( m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(scratchGPR), JITCompiler::TrustedImmPtr(methodCheckData.prototypeStructure)));2291 speculationCheck(JSValueRegs(), NoNode, m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(scratchGPR), JITCompiler::TrustedImmPtr(methodCheckData.prototypeStructure))); 2285 2292 } 2286 2293 … … 2367 2374 // Speculate that base 'ImplementsDefaultHasInstance'. 2368 2375 m_jit.loadPtr(MacroAssembler::Address(base.gpr(), JSCell::structureOffset()), structure.gpr()); 2369 speculationCheck( m_jit.branchTest8(MacroAssembler::Zero, MacroAssembler::Address(structure.gpr(), Structure::typeInfoFlagsOffset()), MacroAssembler::TrustedImm32(ImplementsDefaultHasInstance)));2376 speculationCheck(JSValueRegs(), NoNode, m_jit.branchTest8(MacroAssembler::Zero, MacroAssembler::Address(structure.gpr(), Structure::typeInfoFlagsOffset()), MacroAssembler::TrustedImm32(ImplementsDefaultHasInstance))); 2370 2377 2371 2378 noResult(m_compileIndex); … … 2386 2393 // Check that prototype is an object. 2387 2394 m_jit.loadPtr(MacroAssembler::Address(prototypeReg, JSCell::structureOffset()), scratchReg); 2388 speculationCheck( m_jit.branch8(MacroAssembler::NotEqual, MacroAssembler::Address(scratchReg, Structure::typeInfoTypeOffset()), MacroAssembler::TrustedImm32(ObjectType)));2395 speculationCheck(JSValueRegs(), NoNode, m_jit.branch8(MacroAssembler::NotEqual, MacroAssembler::Address(scratchReg, Structure::typeInfoTypeOffset()), MacroAssembler::TrustedImm32(ObjectType))); 2389 2396 2390 2397 // Initialize scratchReg with the value being checked. … … 2495 2502 2496 2503 case ForceOSRExit: { 2497 terminateSpeculativeExecution( );2504 terminateSpeculativeExecution(JSValueRegs(), NoNode); 2498 2505 break; 2499 2506 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r98299 r98912 48 48 case DataFormatNone: { 49 49 if ((node.hasConstant() && !isInt32Constant(nodeIndex)) || info.spillFormat() == DataFormatDouble) { 50 terminateSpeculativeExecution( );50 terminateSpeculativeExecution(JSValueRegs(), NoNode); 51 51 returnFormat = DataFormatInteger; 52 52 return allocate(); … … 98 98 GPRReg gpr = info.gpr(); 99 99 m_gprs.lock(gpr); 100 speculationCheck( m_jit.branchPtr(MacroAssembler::Below, gpr, GPRInfo::tagTypeNumberRegister));100 speculationCheck(JSValueRegs(gpr), nodeIndex, m_jit.branchPtr(MacroAssembler::Below, gpr, GPRInfo::tagTypeNumberRegister)); 101 101 info.fillJSValue(gpr, DataFormatJSInteger); 102 102 // If !strict we're done, return. … … 147 147 case DataFormatJSCell: 148 148 case DataFormatJSBoolean: { 149 terminateSpeculativeExecution( );149 terminateSpeculativeExecution(JSValueRegs(), NoNode); 150 150 returnFormat = DataFormatInteger; 151 151 return allocate(); … … 206 206 return fpr; 207 207 } 208 terminateSpeculativeExecution( );208 terminateSpeculativeExecution(JSValueRegs(), NoNode); 209 209 return fprAllocate(); 210 210 } … … 249 249 250 250 case DataFormatCell: 251 terminateSpeculativeExecution( );251 terminateSpeculativeExecution(JSValueRegs(), NoNode); 252 252 return fprAllocate(); 253 253 … … 262 262 JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister); 263 263 264 speculationCheck( m_jit.branchTestPtr(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister));264 speculationCheck(JSValueRegs(jsValueGpr), nodeIndex, m_jit.branchTestPtr(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister)); 265 265 266 266 // First, if we get here we have a double encoded as a JSValue … … 336 336 case DataFormatNone: { 337 337 if (info.spillFormat() == DataFormatInteger || info.spillFormat() == DataFormatDouble) { 338 terminateSpeculativeExecution( );338 terminateSpeculativeExecution(JSValueRegs(), NoNode); 339 339 return allocate(); 340 340 } … … 350 350 return gpr; 351 351 } 352 terminateSpeculativeExecution( );352 terminateSpeculativeExecution(JSValueRegs(), NoNode); 353 353 return gpr; 354 354 } … … 359 359 info.fillJSValue(gpr, DataFormatJS); 360 360 if (info.spillFormat() != DataFormatJSCell) 361 speculationCheck( m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister));361 speculationCheck(JSValueRegs(gpr), nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister)); 362 362 info.fillJSValue(gpr, DataFormatJSCell); 363 363 return gpr; … … 374 374 GPRReg gpr = info.gpr(); 375 375 m_gprs.lock(gpr); 376 speculationCheck( m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister));376 speculationCheck(JSValueRegs(gpr), nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister)); 377 377 info.fillJSValue(gpr, DataFormatJSCell); 378 378 return gpr; … … 385 385 case DataFormatJSBoolean: 386 386 case DataFormatBoolean: { 387 terminateSpeculativeExecution( );387 terminateSpeculativeExecution(JSValueRegs(), NoNode); 388 388 return allocate(); 389 389 } … … 409 409 case DataFormatNone: { 410 410 if (info.spillFormat() == DataFormatInteger || info.spillFormat() == DataFormatDouble) { 411 terminateSpeculativeExecution( );411 terminateSpeculativeExecution(JSValueRegs(), NoNode); 412 412 return allocate(); 413 413 } … … 423 423 return gpr; 424 424 } 425 terminateSpeculativeExecution( );425 terminateSpeculativeExecution(JSValueRegs(), NoNode); 426 426 return gpr; 427 427 } … … 433 433 if (info.spillFormat() != DataFormatJSBoolean) { 434 434 m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr); 435 speculationCheck( m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg));435 speculationCheck(JSValueRegs(gpr), nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg)); 436 436 m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr); 437 437 } … … 451 451 m_gprs.lock(gpr); 452 452 m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr); 453 speculationCheck( m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg));453 speculationCheck(JSValueRegs(gpr), nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg)); 454 454 m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr); 455 455 info.fillJSValue(gpr, DataFormatJSBoolean); … … 463 463 case DataFormatJSCell: 464 464 case DataFormatCell: { 465 terminateSpeculativeExecution( );465 terminateSpeculativeExecution(JSValueRegs(), NoNode); 466 466 return allocate(); 467 467 } … … 506 506 507 507 if (!predictionCheck(m_state.forNode(node.child1()).m_type)) 508 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(vptr)));508 speculationCheck(JSValueRegs(op1GPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(vptr))); 509 509 if (!predictionCheck(m_state.forNode(node.child2()).m_type)) 510 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR), MacroAssembler::TrustedImmPtr(vptr)));510 speculationCheck(JSValueRegs(op2GPR), node.child2(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR), MacroAssembler::TrustedImmPtr(vptr))); 511 511 512 512 MacroAssembler::Jump falseCase = m_jit.branchPtr(MacroAssembler::NotEqual, op1GPR, op2GPR); … … 585 585 MacroAssembler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister); 586 586 if (needSpeculationCheck) 587 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valueGPR), MacroAssembler::TrustedImmPtr(vptr)));587 speculationCheck(JSValueRegs(valueGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valueGPR), MacroAssembler::TrustedImmPtr(vptr))); 588 588 m_jit.move(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR); 589 589 MacroAssembler::Jump done = m_jit.jump(); … … 594 594 m_jit.move(valueGPR, resultGPR); 595 595 m_jit.andPtr(MacroAssembler::TrustedImm32(~TagBitUndefined), resultGPR); 596 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, resultGPR, MacroAssembler::TrustedImmPtr(reinterpret_cast<void*>(ValueNull))));596 speculationCheck(JSValueRegs(valueGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, resultGPR, MacroAssembler::TrustedImmPtr(reinterpret_cast<void*>(ValueNull)))); 597 597 } 598 598 m_jit.move(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR); … … 650 650 m_jit.move(value.gpr(), result.gpr()); 651 651 m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), result.gpr()); 652 speculationCheck( m_jit.branchTestPtr(JITCompiler::NonZero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1))));652 speculationCheck(JSValueRegs(value.gpr()), node.child1(), m_jit.branchTestPtr(JITCompiler::NonZero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1)))); 653 653 m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), result.gpr()); 654 654 … … 689 689 MacroAssembler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister); 690 690 if (needSpeculationCheck) 691 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valueGPR), MacroAssembler::TrustedImmPtr(vptr)));691 speculationCheck(JSValueRegs(valueGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valueGPR), MacroAssembler::TrustedImmPtr(vptr))); 692 692 addBranch(m_jit.jump(), taken); 693 693 … … 697 697 m_jit.move(valueGPR, scratchGPR); 698 698 m_jit.andPtr(MacroAssembler::TrustedImm32(~TagBitUndefined), scratchGPR); 699 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, scratchGPR, MacroAssembler::TrustedImmPtr(reinterpret_cast<void*>(ValueNull))));699 speculationCheck(JSValueRegs(valueGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, scratchGPR, MacroAssembler::TrustedImmPtr(reinterpret_cast<void*>(ValueNull)))); 700 700 } 701 701 if (notTaken != (m_block + 1)) … … 765 765 addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(true)))), taken); 766 766 767 speculationCheck( m_jit.jump());767 speculationCheck(JSValueRegs(valueGPR), node.child1(), m_jit.jump()); 768 768 value.use(); 769 769 } else { … … 806 806 // If we have no prediction for this local, then don't attempt to compile. 807 807 if (prediction == PredictNone || value.isClear()) { 808 terminateSpeculativeExecution( );808 terminateSpeculativeExecution(JSValueRegs(), NoNode); 809 809 break; 810 810 } … … 876 876 GPRReg cellGPR = cell.gpr(); 877 877 if (!isArrayPrediction(m_state.forNode(node.child1()).m_type)) 878 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));878 speculationCheck(JSValueRegs(cellGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr))); 879 879 m_jit.storePtr(cellGPR, JITCompiler::addressFor(node.local())); 880 880 noResult(m_compileIndex); … … 883 883 GPRReg cellGPR = cell.gpr(); 884 884 if (!isByteArrayPrediction(m_state.forNode(node.child1()).m_type)) 885 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));885 speculationCheck(JSValueRegs(cellGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr))); 886 886 m_jit.storePtr(cellGPR, JITCompiler::addressFor(node.local())); 887 887 noResult(m_compileIndex); … … 988 988 989 989 // Test the operand is positive. 990 speculationCheck( m_jit.branch32(MacroAssembler::LessThan, op1.gpr(), TrustedImm32(0)));990 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, op1.gpr(), TrustedImm32(0))); 991 991 992 992 m_jit.move(op1.gpr(), result.gpr()); … … 1036 1036 m_jit.add32(Imm32(imm1), result.gpr()); 1037 1037 } else 1038 speculationCheck( m_jit.branchAdd32(MacroAssembler::Overflow, op2.gpr(), Imm32(imm1), result.gpr()));1038 speculationCheck(JSValueRegs(), NoNode, m_jit.branchAdd32(MacroAssembler::Overflow, op2.gpr(), Imm32(imm1), result.gpr())); 1039 1039 1040 1040 integerResult(result.gpr(), m_compileIndex); … … 1051 1051 m_jit.add32(Imm32(imm2), result.gpr()); 1052 1052 } else 1053 speculationCheck( m_jit.branchAdd32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));1053 speculationCheck(JSValueRegs(), NoNode, m_jit.branchAdd32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr())); 1054 1054 1055 1055 integerResult(result.gpr(), m_compileIndex); … … 1076 1076 1077 1077 if (gpr1 == gprResult) 1078 speculationCheck( check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr2));1078 speculationCheck(JSValueRegs(), NoNode, check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr2)); 1079 1079 else if (gpr2 == gprResult) 1080 speculationCheck( check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr1));1080 speculationCheck(JSValueRegs(), NoNode, check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr1)); 1081 1081 else 1082 speculationCheck( check);1082 speculationCheck(JSValueRegs(), NoNode, check); 1083 1083 } 1084 1084 … … 1116 1116 m_jit.sub32(Imm32(imm2), result.gpr()); 1117 1117 } else 1118 speculationCheck( m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));1118 speculationCheck(JSValueRegs(), NoNode, m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr())); 1119 1119 1120 1120 integerResult(result.gpr(), m_compileIndex); … … 1130 1130 m_jit.sub32(op2.gpr(), result.gpr()); 1131 1131 } else 1132 speculationCheck( m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), op2.gpr(), result.gpr()));1132 speculationCheck(JSValueRegs(), NoNode, m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), op2.gpr(), result.gpr())); 1133 1133 1134 1134 integerResult(result.gpr(), m_compileIndex); … … 1165 1165 // domain. 1166 1166 1167 speculationCheck( m_jit.branchMul32(MacroAssembler::Overflow, reg1, reg2, result.gpr()));1167 speculationCheck(JSValueRegs(), NoNode, m_jit.branchMul32(MacroAssembler::Overflow, reg1, reg2, result.gpr())); 1168 1168 1169 1169 // Check for negative zero, if the users of this node care about such things. 1170 1170 if (!nodeCanIgnoreNegativeZero(node.arithNodeFlags())) { 1171 1171 MacroAssembler::Jump resultNonZero = m_jit.branchTest32(MacroAssembler::NonZero, result.gpr()); 1172 speculationCheck( m_jit.branch32(MacroAssembler::LessThan, reg1, TrustedImm32(0)));1173 speculationCheck( m_jit.branch32(MacroAssembler::LessThan, reg2, TrustedImm32(0)));1172 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, reg1, TrustedImm32(0))); 1173 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, reg2, TrustedImm32(0))); 1174 1174 resultNonZero.link(&m_jit); 1175 1175 } … … 1201 1201 GPRReg op2GPR = op2.gpr(); 1202 1202 1203 speculationCheck( m_jit.branchTest32(JITCompiler::Zero, op2GPR));1203 speculationCheck(JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::Zero, op2GPR)); 1204 1204 1205 1205 // If the user cares about negative zero, then speculate that we're not about … … 1207 1207 if (!nodeCanIgnoreNegativeZero(node.arithNodeFlags())) { 1208 1208 MacroAssembler::Jump numeratorNonZero = m_jit.branchTest32(MacroAssembler::NonZero, op1GPR); 1209 speculationCheck( m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0)));1209 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0))); 1210 1210 numeratorNonZero.link(&m_jit); 1211 1211 } … … 1227 1227 // Check that there was no remainder. If there had been, then we'd be obligated to 1228 1228 // produce a double result instead. 1229 speculationCheck( m_jit.branchTest32(JITCompiler::NonZero, edx.gpr()));1229 speculationCheck(JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::NonZero, edx.gpr())); 1230 1230 1231 1231 integerResult(eax.gpr(), m_compileIndex); … … 1271 1271 GPRReg op2Gpr = op2.gpr(); 1272 1272 1273 speculationCheck( m_jit.branchTest32(JITCompiler::Zero, op2Gpr));1273 speculationCheck(JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::Zero, op2Gpr)); 1274 1274 1275 1275 GPRReg temp2 = InvalidGPRReg; … … 1301 1301 m_jit.add32(scratch.gpr(), result.gpr()); 1302 1302 m_jit.xor32(scratch.gpr(), result.gpr()); 1303 speculationCheck( m_jit.branch32(MacroAssembler::Equal, result.gpr(), MacroAssembler::TrustedImm32(1 << 31)));1303 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Equal, result.gpr(), MacroAssembler::TrustedImm32(1 << 31))); 1304 1304 integerResult(result.gpr(), m_compileIndex); 1305 1305 break; … … 1485 1485 // If we have predicted the base to be type array, we can skip the check. 1486 1486 if (!isArrayPrediction(m_state.forNode(node.child1()).m_type)) 1487 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));1488 speculationCheck( m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));1487 speculationCheck(JSValueRegs(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr))); 1488 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset()))); 1489 1489 1490 1490 // FIXME: In cases where there are subsequent by_val accesses to the same base it might help to cache … … 1493 1493 GPRTemporary& result = storage; 1494 1494 m_jit.loadPtr(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), result.gpr()); 1495 speculationCheck( m_jit.branchTestPtr(MacroAssembler::Zero, result.gpr()));1495 speculationCheck(JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::Zero, result.gpr())); 1496 1496 1497 1497 jsValueResult(result.gpr(), m_compileIndex); … … 1540 1540 // If we have predicted the base to be type array, we can skip the check. 1541 1541 if (!isArrayPrediction(m_state.forNode(node.child1()).m_type)) 1542 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));1542 speculationCheck(JSValueRegs(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr))); 1543 1543 1544 1544 base.use(); … … 1628 1628 1629 1629 if (!isArrayPrediction(m_state.forNode(node.child1()).m_type)) 1630 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));1630 speculationCheck(JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr))); 1631 1631 1632 1632 m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), storageGPR); … … 1634 1634 1635 1635 // Refuse to handle bizarre lengths. 1636 speculationCheck( m_jit.branch32(MacroAssembler::Above, storageLengthGPR, TrustedImm32(0x7ffffffe)));1636 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Above, storageLengthGPR, TrustedImm32(0x7ffffffe))); 1637 1637 1638 1638 MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(baseGPR, JSArray::vectorLengthOffset())); … … 1671 1671 1672 1672 if (!isArrayPrediction(m_state.forNode(node.child1()).m_type)) 1673 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));1673 speculationCheck(JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr))); 1674 1674 1675 1675 m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), storageGPR); … … 1776 1776 // We expect that throw statements are rare and are intended to exit the code block 1777 1777 // anyway, so we just OSR back to the old JIT for now. 1778 terminateSpeculativeExecution( );1778 terminateSpeculativeExecution(JSValueRegs(), NoNode); 1779 1779 break; 1780 1780 } … … 1909 1909 m_jit.move(thisValueGPR, scratchGPR); 1910 1910 m_jit.andPtr(MacroAssembler::TrustedImm32(~TagBitUndefined), scratchGPR); 1911 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, scratchGPR, MacroAssembler::TrustedImmPtr(reinterpret_cast<void*>(ValueNull))));1911 speculationCheck(JSValueRegs(thisValueGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, scratchGPR, MacroAssembler::TrustedImmPtr(reinterpret_cast<void*>(ValueNull)))); 1912 1912 } 1913 1913 … … 1924 1924 1925 1925 if (!isObjectPrediction(m_state.forNode(node.child1()).m_type)) 1926 speculationCheck( m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(thisValueGPR), JITCompiler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));1926 speculationCheck(JSValueRegs(thisValueGPR), node.child1(), m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(thisValueGPR), JITCompiler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr))); 1927 1927 1928 1928 m_jit.move(thisValueGPR, resultGPR); … … 1968 1968 if (at(node.child1()).shouldSpeculateFinalObject()) { 1969 1969 if (!isFinalObjectPrediction(m_state.forNode(node.child1()).m_type)) 1970 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(protoGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsFinalObjectVPtr)));1970 speculationCheck(JSValueRegs(protoGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(protoGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsFinalObjectVPtr))); 1971 1971 } else { 1972 1972 m_jit.loadPtr(MacroAssembler::Address(protoGPR, JSCell::structureOffset()), scratchGPR); … … 2071 2071 } 2072 2072 case GetById: { 2073 if (!node.prediction()) { 2074 terminateSpeculativeExecution(JSValueRegs(), NoNode); 2075 break; 2076 } 2077 2073 2078 SpeculateCellOperand base(this, node.child1()); 2074 2079 GPRTemporary result(this, base); … … 2099 2104 2100 2105 if (!isArrayPrediction(m_state.forNode(node.child1()).m_type)) 2101 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));2106 speculationCheck(JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr))); 2102 2107 2103 2108 m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), resultGPR); 2104 2109 m_jit.load32(MacroAssembler::Address(resultGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)), resultGPR); 2105 2110 2106 speculationCheck( m_jit.branch32(MacroAssembler::LessThan, resultGPR, MacroAssembler::TrustedImm32(0)));2111 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, resultGPR, MacroAssembler::TrustedImm32(0))); 2107 2112 2108 2113 integerResult(resultGPR, m_compileIndex); … … 2118 2123 2119 2124 if (!isStringPrediction(m_state.forNode(node.child1()).m_type)) 2120 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));2125 speculationCheck(JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr))); 2121 2126 2122 2127 m_jit.load32(MacroAssembler::Address(baseGPR, JSString::offsetOfLength()), resultGPR); … … 2134 2139 2135 2140 if (!isByteArrayPrediction(m_state.forNode(node.child1()).m_type)) 2136 speculationCheck( m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));2141 speculationCheck(JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr))); 2137 2142 2138 2143 m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSByteArray::offsetOfStorage()), resultGPR); … … 2145 2150 case CheckFunction: { 2146 2151 SpeculateCellOperand function(this, node.child1()); 2147 speculationCheck( m_jit.branchPtr(JITCompiler::NotEqual, function.gpr(), JITCompiler::TrustedImmPtr(node.function())));2152 speculationCheck(JSValueRegs(), NoNode, m_jit.branchPtr(JITCompiler::NotEqual, function.gpr(), JITCompiler::TrustedImmPtr(node.function()))); 2148 2153 noResult(m_compileIndex); 2149 2154 break; … … 2160 2165 2161 2166 if (node.structureSet().size() == 1) 2162 speculationCheck( m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(base.gpr(), JSCell::structureOffset()), JITCompiler::TrustedImmPtr(node.structureSet()[0])));2167 speculationCheck(JSValueRegs(), NoNode, m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(base.gpr(), JSCell::structureOffset()), JITCompiler::TrustedImmPtr(node.structureSet()[0]))); 2163 2168 else { 2164 2169 GPRTemporary structure(this); … … 2171 2176 done.append(m_jit.branchPtr(JITCompiler::Equal, structure.gpr(), JITCompiler::TrustedImmPtr(node.structureSet()[i]))); 2172 2177 2173 speculationCheck( m_jit.branchPtr(JITCompiler::NotEqual, structure.gpr(), JITCompiler::TrustedImmPtr(node.structureSet().last())));2178 speculationCheck(JSValueRegs(), NoNode, m_jit.branchPtr(JITCompiler::NotEqual, structure.gpr(), JITCompiler::TrustedImmPtr(node.structureSet().last()))); 2174 2179 2175 2180 done.link(&m_jit); … … 2275 2280 2276 2281 if (!m_state.forNode(node.child1()).m_structure.doesNotContainAnyOtherThan(methodCheckData.structure)) 2277 speculationCheck( m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), JITCompiler::TrustedImmPtr(methodCheckData.structure)));2282 speculationCheck(JSValueRegs(), NoNode, m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), JITCompiler::TrustedImmPtr(methodCheckData.structure))); 2278 2283 if (methodCheckData.prototype != m_jit.codeBlock()->globalObject()->methodCallDummy()) { 2279 2284 m_jit.move(JITCompiler::TrustedImmPtr(methodCheckData.prototype->structureAddress()), scratchGPR); 2280 speculationCheck( m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(scratchGPR), JITCompiler::TrustedImmPtr(methodCheckData.prototypeStructure)));2285 speculationCheck(JSValueRegs(), NoNode, m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(scratchGPR), JITCompiler::TrustedImmPtr(methodCheckData.prototypeStructure))); 2281 2286 } 2282 2287 … … 2358 2363 // Speculate that base 'ImplementsDefaultHasInstance'. 2359 2364 m_jit.loadPtr(MacroAssembler::Address(base.gpr(), JSCell::structureOffset()), structure.gpr()); 2360 speculationCheck( m_jit.branchTest8(MacroAssembler::Zero, MacroAssembler::Address(structure.gpr(), Structure::typeInfoFlagsOffset()), MacroAssembler::TrustedImm32(ImplementsDefaultHasInstance)));2365 speculationCheck(JSValueRegs(), NoNode, m_jit.branchTest8(MacroAssembler::Zero, MacroAssembler::Address(structure.gpr(), Structure::typeInfoFlagsOffset()), MacroAssembler::TrustedImm32(ImplementsDefaultHasInstance))); 2361 2366 2362 2367 noResult(m_compileIndex); … … 2377 2382 // Check that prototype is an object. 2378 2383 m_jit.loadPtr(MacroAssembler::Address(prototypeReg, JSCell::structureOffset()), scratchReg); 2379 speculationCheck( m_jit.branchIfNotObject(scratchReg));2384 speculationCheck(JSValueRegs(), NoNode, m_jit.branchIfNotObject(scratchReg)); 2380 2385 2381 2386 // Initialize scratchReg with the value being checked. … … 2479 2484 2480 2485 case ForceOSRExit: { 2481 terminateSpeculativeExecution( );2486 terminateSpeculativeExecution(JSValueRegs(), NoNode); 2482 2487 break; 2483 2488 } -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
r98674 r98912 348 348 349 349 compileGetByIdSlowCase(resultVReg, baseVReg, ident, iter, true); 350 emitValueProfilingSite(SubsequentProfilingSite); 350 351 351 352 // We've already generated the following get_by_id, so make sure it's skipped over. -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
r98674 r98912 162 162 163 163 compileGetByIdSlowCase(dst, base, &(m_codeBlock->identifier(ident)), iter, true); 164 emitValueProfilingSite(SubsequentProfilingSite); 164 165 165 166 // We've already generated the following get_by_id, so make sure it's skipped over. -
trunk/Source/JavaScriptCore/runtime/Heuristics.cpp
r98214 r98912 147 147 SET(maximumOptimizationDelay, 5); 148 148 SET(desiredProfileLivenessRate, 0.75); 149 SET(desiredProfileFullnessRate, 0. 25);149 SET(desiredProfileFullnessRate, 0.35); 150 150 151 151 ASSERT(executionCounterValueForDontOptimizeAnytimeSoon <= executionCounterValueForOptimizeAfterLongWarmUp); -
trunk/Source/JavaScriptCore/runtime/JSValue.h
r98679 r98912 50 50 class JITCompiler; 51 51 class JITCodeGenerator; 52 class JSValueSource; 52 53 class SpeculativeJIT; 53 54 } … … 111 112 friend class DFG::JITCompiler; 112 113 friend class DFG::JITCodeGenerator; 114 friend class DFG::JSValueSource; 113 115 friend class DFG::SpeculativeJIT; 114 116 #endif
Note: See TracChangeset
for help on using the changeset viewer.