Changeset 252422 in webkit
- Timestamp:
- Nov 13, 2019 12:07:29 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 53 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r252416 r252422 1 2019-11-13 Robin Morisset <rmorisset@apple.com> 2 3 Split ArithProfile into a Unary and a Binary version 4 https://bugs.webkit.org/show_bug.cgi?id=202832 5 <rdar://problem/56266847> 6 7 Reviewed by Keith Miller. 8 9 The new test (kindly provided by Mark Lam) catches the metadata corruption that used to happen in the previous version of this patch. 10 11 * stress/regress-57020338.js: Added. 12 1 13 2019-11-13 Yusuke Suzuki <ysuzuki@apple.com> 2 14 -
trunk/Source/JavaScriptCore/ChangeLog
r252421 r252422 1 2019-11-13 Robin Morisset <rmorisset@apple.com> 2 3 Split ArithProfile into a Unary and a Binary version 4 https://bugs.webkit.org/show_bug.cgi?id=202832 5 <rdar://problem/56266847> 6 7 Reviewed by Keith Miller. 8 9 ArithProfile was for a long time only used for add/sub/mul/div, but recently it started being used for negate. And it will soon also have to be used for inc and dec due to BigInt. 10 So in this patch I make a separate version that only has the data for a single argument, and thus takes half as much memory. 11 12 After discussing this change with Phil I realized that the ResultType(s) that were taking space in ArithProfile are not needed: they never change and a copy is already in the bytecode instruction itself. 13 Removing them allowed shrinking both kinds of ArithProfile to fit in 16 bits (9 and 13 respectively). 14 I kept the two kinds separate because they may shrink or grow independently in the future. 15 16 This also required adding the "orh" instruction to the offline assembler, to set bits in the ArithProfile. 17 This in turn motivated the addition of "storeh", as on RISC platforms "orh" on a memory location is actually loadh -> orh -> storeh. 18 19 Finally it required adding support for or16(TrustedImm32, AbsoluteAddress) in the MacroAssembler for the ICs. 20 Instead of directly calling it (like we used to do with or32), I introduced ArithProfile::emitUnconditionalSet, so that if either ArithProfile ever changes in size again we'll have fewer places to change. 21 22 * assembler/MacroAssemblerARM64.h: 23 (JSC::MacroAssemblerARM64::or16): 24 * assembler/MacroAssemblerARMv7.h: 25 (JSC::MacroAssemblerARMv7::or16): 26 * assembler/MacroAssemblerMIPS.h: 27 (JSC::MacroAssemblerMIPS::or16): 28 * assembler/MacroAssemblerX86.h: 29 (JSC::MacroAssemblerX86::or16): 30 * assembler/MacroAssemblerX86_64.h: 31 (JSC::MacroAssemblerX86_64::or16): 32 * assembler/testmasm.cpp: 33 (JSC::testOrImmMem): 34 (JSC::run): 35 * bytecode/ArithProfile.cpp: 36 (JSC::ArithProfile<BitfieldType>::emitObserveResult): 37 (JSC::ArithProfile<BitfieldType>::shouldEmitSetDouble const): 38 (JSC::ArithProfile<BitfieldType>::emitSetDouble const): 39 (JSC::ArithProfile<BitfieldType>::shouldEmitSetNonNumeric const): 40 (JSC::ArithProfile<BitfieldType>::emitSetNonNumeric const): 41 (JSC::ArithProfile<BitfieldType>::shouldEmitSetBigInt const): 42 (JSC::ArithProfile<BitfieldType>::emitSetBigInt const): 43 (JSC::ArithProfile<BitfieldType>::emitUnconditionalSet const): 44 (WTF::printInternal): 45 * bytecode/ArithProfile.h: 46 (JSC::ArithProfile::didObserveNonInt32 const): 47 (JSC::ArithProfile::didObserveDouble const): 48 (JSC::ArithProfile::didObserveNonNegZeroDouble const): 49 (JSC::ArithProfile::didObserveNegZeroDouble const): 50 (JSC::ArithProfile::didObserveNonNumeric const): 51 (JSC::ArithProfile::didObserveBigInt const): 52 (JSC::ArithProfile::didObserveInt32Overflow const): 53 (JSC::ArithProfile::didObserveInt52Overflow const): 54 (JSC::ArithProfile::setObservedNonNegZeroDouble): 55 (JSC::ArithProfile::setObservedNegZeroDouble): 56 (JSC::ArithProfile::setObservedNonNumeric): 57 (JSC::ArithProfile::setObservedBigInt): 58 (JSC::ArithProfile::setObservedInt32Overflow): 59 (JSC::ArithProfile::setObservedInt52Overflow): 60 (JSC::ArithProfile::observeResult): 61 (JSC::ArithProfile::addressOfBits const): 62 (JSC::ArithProfile::bits const): 63 (JSC::ArithProfile::ArithProfile): 64 (JSC::ArithProfile::hasBits const): 65 (JSC::ArithProfile::setBit): 66 (JSC::UnaryArithProfile::UnaryArithProfile): 67 (JSC::UnaryArithProfile::observedIntBits): 68 (JSC::UnaryArithProfile::observedNumberBits): 69 (JSC::UnaryArithProfile::argObservedType const): 70 (JSC::UnaryArithProfile::setArgObservedType): 71 (JSC::UnaryArithProfile::argSawInt32): 72 (JSC::UnaryArithProfile::argSawNumber): 73 (JSC::UnaryArithProfile::argSawNonNumber): 74 (JSC::UnaryArithProfile::observeArg): 75 (JSC::UnaryArithProfile::isObservedTypeEmpty): 76 (JSC::BinaryArithProfile::BinaryArithProfile): 77 (JSC::BinaryArithProfile::observedIntIntBits): 78 (JSC::BinaryArithProfile::observedNumberIntBits): 79 (JSC::BinaryArithProfile::observedIntNumberBits): 80 (JSC::BinaryArithProfile::observedNumberNumberBits): 81 (JSC::BinaryArithProfile::setLhsObservedType): 82 (JSC::BinaryArithProfile::setRhsObservedType): 83 (JSC::BinaryArithProfile::observeLHS): 84 (JSC::BinaryArithProfile::observeLHSAndRHS): 85 (JSC::BinaryArithProfile::isObservedTypeEmpty): 86 * bytecode/BytecodeList.rb: 87 * bytecode/CodeBlock.cpp: 88 (JSC::CodeBlock::addJITAddIC): 89 (JSC::CodeBlock::addJITMulIC): 90 (JSC::CodeBlock::addJITSubIC): 91 (JSC::CodeBlock::addJITNegIC): 92 (JSC::CodeBlock::binaryArithProfileForBytecodeIndex): 93 (JSC::CodeBlock::unaryArithProfileForBytecodeIndex): 94 (JSC::CodeBlock::binaryArithProfileForPC): 95 (JSC::CodeBlock::unaryArithProfileForPC): 96 (JSC::CodeBlock::couldTakeSpecialArithFastCase): 97 * bytecode/CodeBlock.h: 98 (JSC::CodeBlock::addMathIC): 99 * bytecode/Fits.h: 100 * bytecode/MethodOfGettingAValueProfile.cpp: 101 (JSC::MethodOfGettingAValueProfile::emitReportValue const): 102 (JSC::MethodOfGettingAValueProfile::reportValue): 103 * bytecode/MethodOfGettingAValueProfile.h: 104 (JSC::MethodOfGettingAValueProfile::MethodOfGettingAValueProfile): 105 * bytecompiler/BytecodeGenerator.cpp: 106 (JSC::BytecodeGenerator::emitUnaryOp): 107 * bytecompiler/BytecodeGenerator.h: 108 * bytecompiler/NodesCodegen.cpp: 109 (JSC::UnaryOpNode::emitBytecode): 110 * dfg/DFGByteCodeParser.cpp: 111 (JSC::DFG::ByteCodeParser::makeSafe): 112 (JSC::DFG::ByteCodeParser::makeDivSafe): 113 * dfg/DFGGraph.cpp: 114 (JSC::DFG::Graph::methodOfGettingAValueProfileFor): 115 * dfg/DFGSpeculativeJIT.cpp: 116 (JSC::DFG::SpeculativeJIT::compileValueAdd): 117 (JSC::DFG::SpeculativeJIT::compileValueSub): 118 (JSC::DFG::SpeculativeJIT::compileValueNegate): 119 (JSC::DFG::SpeculativeJIT::compileValueMul): 120 * ftl/FTLLowerDFGToB3.cpp: 121 (JSC::FTL::DFG::LowerDFGToB3::compileValueAdd): 122 (JSC::FTL::DFG::LowerDFGToB3::compileValueSub): 123 (JSC::FTL::DFG::LowerDFGToB3::compileValueMul): 124 (JSC::FTL::DFG::LowerDFGToB3::compileUnaryMathIC): 125 (JSC::FTL::DFG::LowerDFGToB3::compileBinaryMathIC): 126 (JSC::FTL::DFG::LowerDFGToB3::compileArithAddOrSub): 127 (JSC::FTL::DFG::LowerDFGToB3::compileValueNegate): 128 * jit/JIT.h: 129 * jit/JITAddGenerator.cpp: 130 (JSC::JITAddGenerator::generateInline): 131 (JSC::JITAddGenerator::generateFastPath): 132 * jit/JITAddGenerator.h: 133 * jit/JITArithmetic.cpp: 134 (JSC::JIT::emit_op_negate): 135 (JSC::JIT::emit_op_add): 136 (JSC::JIT::emitMathICFast): 137 (JSC::JIT::emitMathICSlow): 138 (JSC::JIT::emit_op_div): 139 (JSC::JIT::emit_op_mul): 140 (JSC::JIT::emit_op_sub): 141 * jit/JITDivGenerator.cpp: 142 (JSC::JITDivGenerator::generateFastPath): 143 * jit/JITDivGenerator.h: 144 (JSC::JITDivGenerator::JITDivGenerator): 145 * jit/JITInlines.h: 146 (JSC::JIT::copiedArithProfile): 147 * jit/JITMathIC.h: 148 (JSC::JITMathIC::JITMathIC): 149 (JSC::JITMathIC::generateInline): 150 (JSC::JITMathIC::arithProfile const): 151 (JSC::JITBinaryMathIC::JITBinaryMathIC): 152 (JSC::JITUnaryMathIC::JITUnaryMathIC): 153 * jit/JITMulGenerator.cpp: 154 (JSC::JITMulGenerator::generateInline): 155 (JSC::JITMulGenerator::generateFastPath): 156 * jit/JITMulGenerator.h: 157 * jit/JITNegGenerator.cpp: 158 (JSC::JITNegGenerator::generateInline): 159 (JSC::JITNegGenerator::generateFastPath): 160 * jit/JITNegGenerator.h: 161 * jit/JITOperations.cpp: 162 * jit/JITOperations.h: 163 * jit/JITSubGenerator.cpp: 164 (JSC::JITSubGenerator::generateInline): 165 (JSC::JITSubGenerator::generateFastPath): 166 * jit/JITSubGenerator.h: 167 * llint/LLIntData.cpp: 168 (JSC::LLInt::Data::performAssertions): 169 * llint/LLIntOffsetsExtractor.cpp: 170 (JSC::LLIntOffsetsExtractor::dummy): 171 * llint/LowLevelInterpreter.asm: 172 * llint/LowLevelInterpreter32_64.asm: 173 * llint/LowLevelInterpreter64.asm: 174 * offlineasm/arm.rb: 175 * offlineasm/arm64.rb: 176 * offlineasm/cloop.rb: 177 * offlineasm/instructions.rb: 178 * offlineasm/mips.rb: 179 * offlineasm/risc.rb: 180 * offlineasm/x86.rb: 181 * parser/ResultType.h: 182 (JSC::ResultType::ResultType): 183 * runtime/CommonSlowPaths.cpp: 184 (JSC::updateArithProfileForUnaryArithOp): 185 (JSC::updateArithProfileForBinaryArithOp): 186 (JSC::SLOW_PATH_DECL): 187 1 188 2019-11-13 Yusuke Suzuki <ysuzuki@apple.com> 2 189 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h
r250654 r252422 616 616 } 617 617 618 void or16(TrustedImm32 imm, AbsoluteAddress address) 619 { 620 LogicalImmediate logicalImm = LogicalImmediate::create32(imm.m_value); 621 if (logicalImm.isValid()) { 622 load16(address.m_ptr, getCachedDataTempRegisterIDAndInvalidate()); 623 m_assembler.orr<32>(dataTempRegister, dataTempRegister, logicalImm); 624 store16(dataTempRegister, address.m_ptr); 625 } else { 626 load16(address.m_ptr, getCachedMemoryTempRegisterIDAndInvalidate()); 627 or32(imm, memoryTempRegister, getCachedDataTempRegisterIDAndInvalidate()); 628 store16(dataTempRegister, address.m_ptr); 629 } 630 } 631 618 632 void or32(RegisterID src, RegisterID dest) 619 633 { … … 1239 1253 } 1240 1254 1255 void load16(const void* address, RegisterID dest) 1256 { 1257 load<16>(address, dest); 1258 } 1259 1241 1260 void load16Unaligned(ImplicitAddress address, RegisterID dest) 1242 1261 { … … 1545 1564 m_assembler.add<64>(memoryTempRegister, memoryTempRegister, address.index, Assembler::UXTX, address.scale); 1546 1565 m_assembler.strh(src, address.base, memoryTempRegister); 1566 } 1567 1568 void store16(RegisterID src, const void* address) 1569 { 1570 store<16>(src, address); 1571 } 1572 1573 void store16(TrustedImm32 imm, const void* address) 1574 { 1575 if (!imm.m_value) { 1576 store16(ARM64Registers::zr, address); 1577 return; 1578 } 1579 1580 moveToCachedReg(imm, dataMemoryTempRegister()); 1581 store16(dataTempRegister, address); 1547 1582 } 1548 1583 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
r250005 r252422 366 366 m_assembler.orr(dest, dest, src); 367 367 } 368 369 void or16(TrustedImm32 imm, AbsoluteAddress dest) 370 { 371 ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value); 372 if (armImm.isValid()) { 373 move(TrustedImmPtr(address.m_ptr), addressTempRegister); 374 load16(addressTempRegister, dataTempRegister); 375 m_assembler.orr(dataTempRegister, dataTempRegister, armImm); 376 store16(dataTempRegister, addressTempRegister); 377 } else { 378 move(TrustedImmPtr(address.m_ptr), addressTempRegister); 379 load16(addressTempRegister, dataTempRegister); 380 move(imm, addressTempRegister); 381 m_assembler.orr(dataTempRegister, dataTempRegister, addressTempRegister); 382 move(TrustedImmPtr(address.m_ptr), addressTempRegister); 383 store16(dataTempRegister, addressTempRegister); 384 } 385 } 368 386 369 387 void or32(RegisterID src, AbsoluteAddress dest) … … 783 801 } 784 802 803 void load16(const void* address, RegisterID dest) 804 { 805 move(TrustedImmPtr(address), addressTempRegister); 806 m_assembler.ldrh(dest, addressTempRegister, ARMThumbImmediate::makeUInt16(0)); 807 } 808 785 809 void load16(BaseIndex address, RegisterID dest) 786 810 { … … 888 912 { 889 913 store16(src, setupArmAddress(address)); 914 } 915 916 void store16(RegisterID src, const void* address) 917 { 918 move(TrustedImmPtr(address), addressTempRegister); 919 m_assembler.strh(src, addressTempRegister, ARMThumbImmediate::makeUInt12(0)); 920 } 921 922 void store16(TrustedImm32 imm, const void* address) 923 { 924 move(imm, dataTempRegister); 925 store16(dataTempRegister, address); 890 926 } 891 927 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
r250005 r252422 474 474 { 475 475 m_assembler.subu(dest, MIPSRegisters::zero, src); 476 } 477 478 void or16(TrustedImm32 imm, AbsoluteAddress dest) 479 { 480 if (!imm.m_value && !m_fixedWidth) 481 return; 482 483 if (m_fixedWidth) { 484 // TODO: Swap dataTempRegister and immTempRegister usage 485 load16(dest.m_ptr, immTempRegister); 486 or32(imm, immTempRegister); 487 store16(immTempRegister, dest.m_ptr); 488 } else { 489 uintptr_t adr = reinterpret_cast<uintptr_t>(dest.m_ptr); 490 m_assembler.lui(addrTempRegister, (adr + 0x8000) >> 16); 491 m_assembler.lw(immTempRegister, addrTempRegister, adr & 0xffff); 492 or16(imm, immTempRegister); 493 m_assembler.sw(immTempRegister, addrTempRegister, adr & 0xffff); 494 } 476 495 } 477 496 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86.h
r250005 r252422 100 100 m_assembler.orl_rm(reg, address.m_ptr); 101 101 } 102 103 void or16(TrustedImm32 imm, AbsoluteAddress address) 104 { 105 m_assembler.orw_im(imm.m_value, address.m_ptr); 106 } 102 107 103 108 void sub32(TrustedImm32 imm, AbsoluteAddress address) -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
r250559 r252422 48 48 using MacroAssemblerX86Common::branchAdd32; 49 49 using MacroAssemblerX86Common::or32; 50 using MacroAssemblerX86Common::or16; 50 51 using MacroAssemblerX86Common::sub32; 51 52 using MacroAssemblerX86Common::load8; … … 88 89 move(TrustedImmPtr(address.m_ptr), scratchRegister()); 89 90 or32(reg, Address(scratchRegister())); 91 } 92 93 void or16(TrustedImm32 imm, AbsoluteAddress address) 94 { 95 move(TrustedImmPtr(address.m_ptr), scratchRegister()); 96 or16(imm, Address(scratchRegister())); 90 97 } 91 98 -
trunk/Source/JavaScriptCore/assembler/testmasm.cpp
r250695 r252422 1105 1105 #endif // ENABLE(MASM_PROBE) 1106 1106 1107 void testOrImmMem() 1108 { 1109 // FIXME: this does not test that the or does not touch beyond its width. 1110 // I am not sure how to do such a test without a lot of complexity (running multiple threads, with a race on the high bits of the memory location). 1111 uint64_t memoryLocation = 0x12341234; 1112 auto or32 = compile([&] (CCallHelpers& jit) { 1113 emitFunctionPrologue(jit); 1114 jit.or32(CCallHelpers::TrustedImm32(42), CCallHelpers::AbsoluteAddress(&memoryLocation)); 1115 emitFunctionEpilogue(jit); 1116 jit.ret(); 1117 }); 1118 invoke<void>(or32); 1119 CHECK_EQ(memoryLocation, 0x12341234 | 42); 1120 1121 memoryLocation = 0x12341234; 1122 auto or16 = compile([&] (CCallHelpers& jit) { 1123 emitFunctionPrologue(jit); 1124 jit.or16(CCallHelpers::TrustedImm32(42), CCallHelpers::AbsoluteAddress(&memoryLocation)); 1125 emitFunctionEpilogue(jit); 1126 jit.ret(); 1127 }); 1128 invoke<void>(or16); 1129 CHECK_EQ(memoryLocation, 0x12341234 | 42); 1130 } 1131 1107 1132 void testByteSwap() 1108 1133 { … … 1361 1386 RUN(testCagePreservesPACFailureBit()); 1362 1387 1388 RUN(testOrImmMem()); 1389 1363 1390 if (tasks.isEmpty()) 1364 1391 usage(); -
trunk/Source/JavaScriptCore/bytecode/ArithProfile.cpp
r252273 r252422 33 33 34 34 #if ENABLE(JIT) 35 void ArithProfile::emitObserveResult(CCallHelpers& jit, JSValueRegs regs, TagRegistersMode mode) 35 template<typename BitfieldType> 36 void ArithProfile<BitfieldType>::emitObserveResult(CCallHelpers& jit, JSValueRegs regs, TagRegistersMode mode) 36 37 { 37 38 if (!shouldEmitSetDouble() && !shouldEmitSetNonNumeric() && !shouldEmitSetBigInt()) … … 59 60 } 60 61 61 bool ArithProfile::shouldEmitSetDouble() const 62 { 63 uint32_t mask = ArithProfile::Int32Overflow | ArithProfile::Int52Overflow | ArithProfile::NegZeroDouble | ArithProfile::NonNegZeroDouble; 62 template<typename BitfieldType> 63 bool ArithProfile<BitfieldType>::shouldEmitSetDouble() const 64 { 65 BitfieldType mask = Int32Overflow | Int52Overflow | NegZeroDouble | NonNegZeroDouble; 64 66 return (m_bits & mask) != mask; 65 67 } 66 68 67 void ArithProfile::emitSetDouble(CCallHelpers& jit) const 69 template<typename BitfieldType> 70 void ArithProfile<BitfieldType>::emitSetDouble(CCallHelpers& jit) const 68 71 { 69 72 if (shouldEmitSetDouble()) 70 jit.or32(CCallHelpers::TrustedImm32(ArithProfile::Int32Overflow | ArithProfile::Int52Overflow | ArithProfile::NegZeroDouble | ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(addressOfBits())); 71 } 72 73 bool ArithProfile::shouldEmitSetNonNumeric() const 74 { 75 uint32_t mask = ArithProfile::NonNumeric; 73 emitUnconditionalSet(jit, Int32Overflow | Int52Overflow | NegZeroDouble | NonNegZeroDouble); 74 } 75 76 template<typename BitfieldType> 77 bool ArithProfile<BitfieldType>::shouldEmitSetNonNumeric() const 78 { 79 BitfieldType mask = ArithProfile::NonNumeric; 76 80 return (m_bits & mask) != mask; 77 81 } 78 82 79 bool ArithProfile::shouldEmitSetBigInt() const 80 { 81 uint32_t mask = ArithProfile::BigInt; 83 template<typename BitfieldType> 84 void ArithProfile<BitfieldType>::emitSetNonNumeric(CCallHelpers& jit) const 85 { 86 if (shouldEmitSetNonNumeric()) 87 emitUnconditionalSet(jit, NonNumeric); 88 } 89 90 template<typename BitfieldType> 91 bool ArithProfile<BitfieldType>::shouldEmitSetBigInt() const 92 { 93 BitfieldType mask = ArithProfile::BigInt; 82 94 return (m_bits & mask) != mask; 83 95 } 84 96 85 void ArithProfile::emitSetNonNumeric(CCallHelpers& jit) const 86 { 87 if (shouldEmitSetNonNumeric()) 88 jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NonNumeric), CCallHelpers::AbsoluteAddress(addressOfBits())); 89 } 90 91 void ArithProfile::emitSetBigInt(CCallHelpers& jit) const 97 template<typename BitfieldType> 98 void ArithProfile<BitfieldType>::emitSetBigInt(CCallHelpers& jit) const 92 99 { 93 100 if (shouldEmitSetBigInt()) 94 jit.or32(CCallHelpers::TrustedImm32(ArithProfile::BigInt), CCallHelpers::AbsoluteAddress(addressOfBits())); 95 } 101 emitUnconditionalSet(jit, BigInt); 102 } 103 104 template<typename BitfieldType> 105 void ArithProfile<BitfieldType>::emitUnconditionalSet(CCallHelpers& jit, BitfieldType mask) const 106 { 107 static_assert(std::is_same<BitfieldType, uint16_t>::value); 108 jit.or16(CCallHelpers::TrustedImm32(mask), CCallHelpers::AbsoluteAddress(addressOfBits())); 109 } 110 111 // Generate the implementations of the functions above for UnaryArithProfile/BinaryArithProfile 112 // If changing the size of either, add the corresponding lines here. 113 template class ArithProfile<uint16_t>; 96 114 #endif // ENABLE(JIT) 97 115 … … 102 120 using namespace JSC; 103 121 104 void printInternal(PrintStream& out, const ArithProfile& profile) 122 template <typename T> 123 void printInternal(PrintStream& out, const ArithProfile<T>& profile) 105 124 { 106 125 const char* separator = ""; … … 136 155 } 137 156 } 157 out.print(">"); 158 } 159 160 void printInternal(PrintStream& out, const UnaryArithProfile& profile) 161 { 162 printInternal(out, static_cast<ArithProfile<UnaryArithProfileBase>>(profile)); 163 164 out.print(" Arg ObservedType:<"); 165 out.print(profile.argObservedType()); 166 out.print(">"); 167 } 168 169 void printInternal(PrintStream& out, const BinaryArithProfile& profile) 170 { 171 printInternal(out, static_cast<ArithProfile<UnaryArithProfileBase>>(profile)); 172 138 173 if (profile.tookSpecialFastPath()) 139 out.print(separator, "Took special fast path."); 140 out.print(">"); 174 out.print(" Took special fast path."); 141 175 142 176 out.print(" LHS ObservedType:<"); … … 145 179 out.print(profile.rhsObservedType()); 146 180 out.print(">"); 147 148 out.print(" LHS ResultType:<", RawPointer(bitwise_cast<void*>(static_cast<uintptr_t>(profile.lhsResultType().bits()))));149 out.print("> RHS ResultType:<", RawPointer(bitwise_cast<void*>(static_cast<uintptr_t>(profile.rhsResultType().bits()))));150 out.print(">");151 181 } 152 182 -
trunk/Source/JavaScriptCore/bytecode/ArithProfile.h
r252273 r252422 67 67 }; 68 68 69 struct ArithProfile { 70 private: 71 static constexpr uint32_t numberOfFlagBits = 6; 72 static constexpr uint32_t rhsResultTypeShift = numberOfFlagBits; 73 static constexpr uint32_t lhsResultTypeShift = rhsResultTypeShift + ResultType::numBitsNeeded; 74 static constexpr uint32_t rhsObservedTypeShift = lhsResultTypeShift + ResultType::numBitsNeeded; 75 static constexpr uint32_t lhsObservedTypeShift = rhsObservedTypeShift + ObservedType::numBitsNeeded; 76 77 static_assert(ObservedType::numBitsNeeded == 3, "We make a hard assumption about that here."); 78 static constexpr uint32_t clearRhsObservedTypeBitMask = static_cast<uint32_t>(~((1 << rhsObservedTypeShift) | (1 << (rhsObservedTypeShift + 1)) | (1 << (rhsObservedTypeShift + 2)))); 79 static constexpr uint32_t clearLhsObservedTypeBitMask = static_cast<uint32_t>(~((1 << lhsObservedTypeShift) | (1 << (lhsObservedTypeShift + 1)) | (1 << (lhsObservedTypeShift + 2)))); 80 81 static constexpr uint32_t resultTypeMask = (1 << ResultType::numBitsNeeded) - 1; 82 static constexpr uint32_t observedTypeMask = (1 << ObservedType::numBitsNeeded) - 1; 83 84 enum class ConstantTag { Constant }; 85 69 template <typename BitfieldType> 70 class ArithProfile { 86 71 public: 87 static constexpr uint32_t specialFastPathBit = 1 << (lhsObservedTypeShift + ObservedType::numBitsNeeded); 88 static_assert((lhsObservedTypeShift + ObservedType::numBitsNeeded) <= (sizeof(uint32_t) * 8) - 1, "Should fit in a uint32_t."); 89 static_assert(!(specialFastPathBit & ~clearLhsObservedTypeBitMask), "These bits should not intersect."); 90 static_assert(specialFastPathBit & clearLhsObservedTypeBitMask, "These bits should intersect."); 91 static_assert(specialFastPathBit > ~clearLhsObservedTypeBitMask, "These bits should not intersect and specialFastPathBit should be a higher bit."); 92 93 ArithProfile(ResultType arg) 94 : ArithProfile(ConstantTag::Constant, arg) 95 { 96 ASSERT(lhsResultType().bits() == arg.bits()); 97 ASSERT(lhsObservedType().isEmpty()); 98 ASSERT(rhsObservedType().isEmpty()); 99 } 100 101 ArithProfile(ResultType lhs, ResultType rhs) 102 : ArithProfile(ConstantTag::Constant, lhs, rhs) 103 { 104 ASSERT(lhsResultType().bits() == lhs.bits() && rhsResultType().bits() == rhs.bits()); 105 ASSERT(lhsObservedType().isEmpty()); 106 ASSERT(rhsObservedType().isEmpty()); 107 } 108 109 ArithProfile(OperandTypes types) 110 : ArithProfile(types.first(), types.second()) 111 { } 112 113 ArithProfile() = default; 114 115 static constexpr ArithProfile fromInt(uint32_t bits) 116 { 117 return ArithProfile { ConstantTag::Constant, bits }; 118 } 119 120 static constexpr ArithProfile observedUnaryInt() 121 { 122 constexpr ObservedType observedInt32 { ObservedType().withInt32() }; 123 constexpr uint32_t bits = observedInt32.bits() << lhsObservedTypeShift; 124 static_assert(bits == 0x800000, ""); 125 return fromInt(bits); 126 } 127 static constexpr ArithProfile observedUnaryNumber() 128 { 129 constexpr ObservedType observedNumber { ObservedType().withNumber() }; 130 constexpr uint32_t bits = observedNumber.bits() << lhsObservedTypeShift; 131 static_assert(bits == 0x1000000, ""); 132 return fromInt(bits); 133 } 134 static constexpr ArithProfile observedBinaryIntInt() 135 { 136 constexpr ObservedType observedInt32 { ObservedType().withInt32() }; 137 constexpr uint32_t bits = (observedInt32.bits() << lhsObservedTypeShift) | (observedInt32.bits() << rhsObservedTypeShift); 138 static_assert(bits == 0x900000, ""); 139 return fromInt(bits); 140 } 141 static constexpr ArithProfile observedBinaryNumberInt() 142 { 143 constexpr ObservedType observedNumber { ObservedType().withNumber() }; 144 constexpr ObservedType observedInt32 { ObservedType().withInt32() }; 145 constexpr uint32_t bits = (observedNumber.bits() << lhsObservedTypeShift) | (observedInt32.bits() << rhsObservedTypeShift); 146 static_assert(bits == 0x1100000, ""); 147 return fromInt(bits); 148 } 149 static constexpr ArithProfile observedBinaryIntNumber() 150 { 151 constexpr ObservedType observedNumber { ObservedType().withNumber() }; 152 constexpr ObservedType observedInt32 { ObservedType().withInt32() }; 153 constexpr uint32_t bits = (observedInt32.bits() << lhsObservedTypeShift) | (observedNumber.bits() << rhsObservedTypeShift); 154 static_assert(bits == 0xa00000, ""); 155 return fromInt(bits); 156 } 157 static constexpr ArithProfile observedBinaryNumberNumber() 158 { 159 constexpr ObservedType observedNumber { ObservedType().withNumber() }; 160 constexpr uint32_t bits = (observedNumber.bits() << lhsObservedTypeShift) | (observedNumber.bits() << rhsObservedTypeShift); 161 static_assert(bits == 0x1200000, ""); 162 return fromInt(bits); 163 } 164 165 enum ObservedResults { 72 enum ObservedResults : BitfieldType { 166 73 NonNegZeroDouble = 1 << 0, 167 74 NegZeroDouble = 1 << 1, … … 171 78 BigInt = 1 << 5, 172 79 }; 173 174 ResultType lhsResultType() const { return ResultType((m_bits >> lhsResultTypeShift) & resultTypeMask); } 175 ResultType rhsResultType() const { return ResultType((m_bits >> rhsResultTypeShift) & resultTypeMask); } 176 177 constexpr ObservedType lhsObservedType() const { return ObservedType((m_bits >> lhsObservedTypeShift) & observedTypeMask); } 178 constexpr ObservedType rhsObservedType() const { return ObservedType((m_bits >> rhsObservedTypeShift) & observedTypeMask); } 179 void setLhsObservedType(ObservedType type) 180 { 181 uint32_t bits = m_bits; 182 bits &= clearLhsObservedTypeBitMask; 183 bits |= type.bits() << lhsObservedTypeShift; 184 m_bits = bits; 185 ASSERT(lhsObservedType() == type); 186 } 187 188 void setRhsObservedType(ObservedType type) 189 { 190 uint32_t bits = m_bits; 191 bits &= clearRhsObservedTypeBitMask; 192 bits |= type.bits() << rhsObservedTypeShift; 193 m_bits = bits; 194 ASSERT(rhsObservedType() == type); 195 } 196 197 bool tookSpecialFastPath() const { return m_bits & specialFastPathBit; } 80 static constexpr uint32_t observedResultsNumBitsNeeded = 6; 198 81 199 82 bool didObserveNonInt32() const { return hasBits(NonNegZeroDouble | NegZeroDouble | NonNumeric | BigInt); } … … 212 95 void setObservedInt32Overflow() { setBit(Int32Overflow); } 213 96 void setObservedInt52Overflow() { setBit(Int52Overflow); } 214 215 const void* addressOfBits() const { return &m_bits; }216 97 217 98 void observeResult(JSValue value) … … 230 111 } 231 112 113 const void* addressOfBits() const { return &m_bits; } 114 115 #if ENABLE(JIT) 116 // Sets (Int32Overflow | Int52Overflow | NonNegZeroDouble | NegZeroDouble) if it sees a 117 // double. Sets NonNumeric if it sees a non-numeric. 118 void emitObserveResult(CCallHelpers&, JSValueRegs, TagRegistersMode = HaveTagRegisters); 119 120 // Sets (Int32Overflow | Int52Overflow | NonNegZeroDouble | NegZeroDouble). 121 bool shouldEmitSetDouble() const; 122 void emitSetDouble(CCallHelpers&) const; 123 124 // Sets NonNumeric 125 void emitSetNonNumeric(CCallHelpers&) const; 126 bool shouldEmitSetNonNumeric() const; 127 128 // Sets BigInt 129 void emitSetBigInt(CCallHelpers&) const; 130 bool shouldEmitSetBigInt() const; 131 132 void emitUnconditionalSet(CCallHelpers&, BitfieldType) const; 133 #endif // ENABLE(JIT) 134 135 constexpr uint32_t bits() const { return m_bits; } 136 137 protected: 138 ArithProfile() 139 { 140 } 141 142 bool hasBits(int mask) const { return m_bits & mask; } 143 void setBit(int mask) { m_bits |= mask; } 144 145 BitfieldType m_bits { 0 }; // We take care to update m_bits only in a single operation. We don't ever store an inconsistent bit representation to it. 146 }; 147 148 /* This class stores the following components in 16 bits: 149 * - ObservedResults 150 * - ObservedType for the argument 151 */ 152 using UnaryArithProfileBase = uint16_t; 153 class UnaryArithProfile : public ArithProfile<UnaryArithProfileBase> { 154 static constexpr unsigned argObservedTypeShift = observedResultsNumBitsNeeded; 155 156 static_assert(argObservedTypeShift + ObservedType::numBitsNeeded <= sizeof(UnaryArithProfileBase) * 8, "Should fit in a the type of the underlying bitfield."); 157 158 static constexpr UnaryArithProfileBase clearArgObservedTypeBitMask = static_cast<UnaryArithProfileBase>(~(0b111 << argObservedTypeShift)); 159 160 static constexpr UnaryArithProfileBase observedTypeMask = (1 << ObservedType::numBitsNeeded) - 1; 161 162 public: 163 UnaryArithProfile() 164 : ArithProfile<UnaryArithProfileBase>() 165 { 166 ASSERT(argObservedType().isEmpty()); 167 ASSERT(argObservedType().isEmpty()); 168 } 169 170 static constexpr UnaryArithProfileBase observedIntBits() 171 { 172 constexpr ObservedType observedInt32 { ObservedType().withInt32() }; 173 constexpr UnaryArithProfileBase bits = observedInt32.bits() << argObservedTypeShift; 174 return bits; 175 } 176 static constexpr UnaryArithProfileBase observedNumberBits() 177 { 178 constexpr ObservedType observedNumber { ObservedType().withNumber() }; 179 constexpr UnaryArithProfileBase bits = observedNumber.bits() << argObservedTypeShift; 180 return bits; 181 } 182 183 constexpr ObservedType argObservedType() const { return ObservedType((m_bits >> argObservedTypeShift) & observedTypeMask); } 184 void setArgObservedType(ObservedType type) 185 { 186 UnaryArithProfileBase bits = m_bits; 187 bits &= clearArgObservedTypeBitMask; 188 bits |= type.bits() << argObservedTypeShift; 189 m_bits = bits; 190 ASSERT(argObservedType() == type); 191 } 192 193 void argSawInt32() { setArgObservedType(argObservedType().withInt32()); } 194 void argSawNumber() { setArgObservedType(argObservedType().withNumber()); } 195 void argSawNonNumber() { setArgObservedType(argObservedType().withNonNumber()); } 196 197 void observeArg(JSValue arg) 198 { 199 UnaryArithProfile newProfile = *this; 200 if (arg.isNumber()) { 201 if (arg.isInt32()) 202 newProfile.argSawInt32(); 203 else 204 newProfile.argSawNumber(); 205 } else 206 newProfile.argSawNonNumber(); 207 208 m_bits = newProfile.bits(); 209 } 210 211 bool isObservedTypeEmpty() 212 { 213 return argObservedType().isEmpty(); 214 } 215 216 friend class JSC::LLIntOffsetsExtractor; 217 }; 218 219 /* This class stores the following components in 16 bits: 220 * - ObservedResults 221 * - ObservedType for right-hand-side 222 * - ObservedType for left-hand-side 223 * - a bit used by division to indicate whether a special fast path was taken 224 */ 225 using BinaryArithProfileBase = uint16_t; 226 class BinaryArithProfile : public ArithProfile<BinaryArithProfileBase> { 227 static constexpr uint32_t rhsObservedTypeShift = observedResultsNumBitsNeeded; 228 static constexpr uint32_t lhsObservedTypeShift = rhsObservedTypeShift + ObservedType::numBitsNeeded; 229 230 static_assert(ObservedType::numBitsNeeded == 3, "We make a hard assumption about that here."); 231 static constexpr BinaryArithProfileBase clearRhsObservedTypeBitMask = static_cast<BinaryArithProfileBase>(~(0b111 << rhsObservedTypeShift)); 232 static constexpr BinaryArithProfileBase clearLhsObservedTypeBitMask = static_cast<BinaryArithProfileBase>(~(0b111 << lhsObservedTypeShift)); 233 234 static constexpr BinaryArithProfileBase observedTypeMask = (1 << ObservedType::numBitsNeeded) - 1; 235 236 public: 237 static constexpr BinaryArithProfileBase specialFastPathBit = 1 << (lhsObservedTypeShift + ObservedType::numBitsNeeded); 238 static_assert((lhsObservedTypeShift + ObservedType::numBitsNeeded + 1) <= sizeof(BinaryArithProfileBase) * 8, "Should fit in a uint32_t."); 239 static_assert(!(specialFastPathBit & ~clearLhsObservedTypeBitMask), "These bits should not intersect."); 240 static_assert(specialFastPathBit & clearLhsObservedTypeBitMask, "These bits should intersect."); 241 static_assert(specialFastPathBit > ~clearLhsObservedTypeBitMask, "These bits should not intersect and specialFastPathBit should be a higher bit."); 242 243 BinaryArithProfile() 244 : ArithProfile<BinaryArithProfileBase> () 245 { 246 ASSERT(lhsObservedType().isEmpty()); 247 ASSERT(rhsObservedType().isEmpty()); 248 } 249 250 static constexpr BinaryArithProfileBase observedIntIntBits() 251 { 252 constexpr ObservedType observedInt32 { ObservedType().withInt32() }; 253 constexpr BinaryArithProfileBase bits = (observedInt32.bits() << lhsObservedTypeShift) | (observedInt32.bits() << rhsObservedTypeShift); 254 return bits; 255 } 256 static constexpr BinaryArithProfileBase observedNumberIntBits() 257 { 258 constexpr ObservedType observedNumber { ObservedType().withNumber() }; 259 constexpr ObservedType observedInt32 { ObservedType().withInt32() }; 260 constexpr BinaryArithProfileBase bits = (observedNumber.bits() << lhsObservedTypeShift) | (observedInt32.bits() << rhsObservedTypeShift); 261 return bits; 262 } 263 static constexpr BinaryArithProfileBase observedIntNumberBits() 264 { 265 constexpr ObservedType observedNumber { ObservedType().withNumber() }; 266 constexpr ObservedType observedInt32 { ObservedType().withInt32() }; 267 constexpr BinaryArithProfileBase bits = (observedInt32.bits() << lhsObservedTypeShift) | (observedNumber.bits() << rhsObservedTypeShift); 268 return bits; 269 } 270 static constexpr BinaryArithProfileBase observedNumberNumberBits() 271 { 272 constexpr ObservedType observedNumber { ObservedType().withNumber() }; 273 constexpr BinaryArithProfileBase bits = (observedNumber.bits() << lhsObservedTypeShift) | (observedNumber.bits() << rhsObservedTypeShift); 274 return bits; 275 } 276 277 constexpr ObservedType lhsObservedType() const { return ObservedType((m_bits >> lhsObservedTypeShift) & observedTypeMask); } 278 constexpr ObservedType rhsObservedType() const { return ObservedType((m_bits >> rhsObservedTypeShift) & observedTypeMask); } 279 void setLhsObservedType(ObservedType type) 280 { 281 BinaryArithProfileBase bits = m_bits; 282 bits &= clearLhsObservedTypeBitMask; 283 bits |= type.bits() << lhsObservedTypeShift; 284 m_bits = bits; 285 ASSERT(lhsObservedType() == type); 286 } 287 288 void setRhsObservedType(ObservedType type) 289 { 290 BinaryArithProfileBase bits = m_bits; 291 bits &= clearRhsObservedTypeBitMask; 292 bits |= type.bits() << rhsObservedTypeShift; 293 m_bits = bits; 294 ASSERT(rhsObservedType() == type); 295 } 296 297 bool tookSpecialFastPath() const { return m_bits & specialFastPathBit; } 298 232 299 void lhsSawInt32() { setLhsObservedType(lhsObservedType().withInt32()); } 233 300 void lhsSawNumber() { setLhsObservedType(lhsObservedType().withNumber()); } … … 239 306 void observeLHS(JSValue lhs) 240 307 { 241 ArithProfile newProfile = *this;308 BinaryArithProfile newProfile = *this; 242 309 if (lhs.isNumber()) { 243 310 if (lhs.isInt32()) … … 255 322 observeLHS(lhs); 256 323 257 ArithProfile newProfile = *this;324 BinaryArithProfile newProfile = *this; 258 325 if (rhs.isNumber()) { 259 326 if (rhs.isInt32()) … … 267 334 } 268 335 269 #if ENABLE(JIT) 270 // Sets (Int32Overflow | Int52Overflow | NonNegZeroDouble | NegZeroDouble) if it sees a 271 // double. Sets NonNumeric if it sees a non-numeric. 272 void emitObserveResult(CCallHelpers&, JSValueRegs, TagRegistersMode = HaveTagRegisters); 273 274 // Sets (Int32Overflow | Int52Overflow | NonNegZeroDouble | NegZeroDouble). 275 bool shouldEmitSetDouble() const; 276 void emitSetDouble(CCallHelpers&) const; 277 278 // Sets NonNumber. 279 void emitSetNonNumeric(CCallHelpers&) const; 280 bool shouldEmitSetNonNumeric() const; 281 282 // Sets BigInt 283 void emitSetBigInt(CCallHelpers&) const; 284 bool shouldEmitSetBigInt() const; 285 #endif // ENABLE(JIT) 286 287 constexpr uint32_t bits() const { return m_bits; } 288 289 private: 290 constexpr explicit ArithProfile(ConstantTag, uint32_t bits) 291 : m_bits(bits) 292 { 293 } 294 295 constexpr ArithProfile(ConstantTag, ResultType arg) 296 : m_bits(arg.bits() << lhsResultTypeShift) 297 { 298 } 299 300 constexpr ArithProfile(ConstantTag, ResultType lhs, ResultType rhs) 301 : m_bits((lhs.bits() << lhsResultTypeShift) | (rhs.bits() << rhsResultTypeShift)) 302 { 303 } 304 305 bool hasBits(int mask) const { return m_bits & mask; } 306 void setBit(int mask) { m_bits |= mask; } 307 308 uint32_t m_bits { 0 }; // We take care to update m_bits only in a single operation. We don't ever store an inconsistent bit representation to it. 336 bool isObservedTypeEmpty() 337 { 338 return lhsObservedType().isEmpty() && rhsObservedType().isEmpty(); 339 } 309 340 310 341 friend class JSC::LLIntOffsetsExtractor; … … 315 346 namespace WTF { 316 347 317 void printInternal(PrintStream&, const JSC::ArithProfile&); 348 void printInternal(PrintStream&, const JSC::UnaryArithProfile&); 349 void printInternal(PrintStream&, const JSC::BinaryArithProfile&); 318 350 void printInternal(PrintStream&, const JSC::ObservedType&); 319 351 -
trunk/Source/JavaScriptCore/bytecode/BytecodeList.rb
r252273 r252422 42 42 :JSValue, 43 43 :LLIntCallLinkInfo, 44 :ResultType, 44 45 :OperandTypes, 45 46 :ProfileTypeBytecodeFlag, … … 59 60 :ValueProfile, 60 61 :ValueProfileAndOperandBuffer, 61 :ArithProfile, 62 :UnaryArithProfile, 63 :BinaryArithProfile, 62 64 :ArrayProfile, 63 65 :ArrayAllocationProfile, … … 280 282 }, 281 283 metadata: { 282 arithProfile: ArithProfile 283 }, 284 metadata_initializers: { 285 arithProfile: :operandTypes 284 arithProfile: BinaryArithProfile 286 285 } 287 286 … … 365 364 dst: VirtualRegister, 366 365 operand: VirtualRegister, 367 operandTypes: OperandTypes, 368 }, 369 metadata: { 370 arithProfile: ArithProfile, 371 }, 372 metadata_initializers: { 373 arithProfile: :operandTypes 366 resultType: ResultType, 367 }, 368 metadata: { 369 arithProfile: UnaryArithProfile, 374 370 } 375 371 -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r252273 r252422 1480 1480 } 1481 1481 1482 JITAddIC* CodeBlock::addJITAddIC( ArithProfile* arithProfile)1482 JITAddIC* CodeBlock::addJITAddIC(BinaryArithProfile* arithProfile) 1483 1483 { 1484 1484 ConcurrentJSLocker locker(m_lock); … … 1486 1486 } 1487 1487 1488 JITMulIC* CodeBlock::addJITMulIC( ArithProfile* arithProfile)1488 JITMulIC* CodeBlock::addJITMulIC(BinaryArithProfile* arithProfile) 1489 1489 { 1490 1490 ConcurrentJSLocker locker(m_lock); … … 1492 1492 } 1493 1493 1494 JITSubIC* CodeBlock::addJITSubIC( ArithProfile* arithProfile)1494 JITSubIC* CodeBlock::addJITSubIC(BinaryArithProfile* arithProfile) 1495 1495 { 1496 1496 ConcurrentJSLocker locker(m_lock); … … 1498 1498 } 1499 1499 1500 JITNegIC* CodeBlock::addJITNegIC( ArithProfile* arithProfile)1500 JITNegIC* CodeBlock::addJITNegIC(UnaryArithProfile* arithProfile) 1501 1501 { 1502 1502 ConcurrentJSLocker locker(m_lock); … … 3085 3085 } 3086 3086 3087 ArithProfile* CodeBlock::arithProfileForBytecodeIndex(BytecodeIndex bytecodeIndex) 3088 { 3089 return arithProfileForPC(instructions().at(bytecodeIndex.offset()).ptr()); 3090 } 3091 3092 ArithProfile* CodeBlock::arithProfileForPC(const Instruction* pc) 3087 BinaryArithProfile* CodeBlock::binaryArithProfileForBytecodeIndex(BytecodeIndex bytecodeIndex) 3088 { 3089 return binaryArithProfileForPC(instructions().at(bytecodeIndex.offset()).ptr()); 3090 } 3091 3092 UnaryArithProfile* CodeBlock::unaryArithProfileForBytecodeIndex(BytecodeIndex bytecodeIndex) 3093 { 3094 return unaryArithProfileForPC(instructions().at(bytecodeIndex.offset()).ptr()); 3095 } 3096 3097 BinaryArithProfile* CodeBlock::binaryArithProfileForPC(const Instruction* pc) 3093 3098 { 3094 3099 switch (pc->opcodeID()) { 3095 case op_negate:3096 return &pc->as<OpNegate>().metadata(this).m_arithProfile;3097 3100 case op_add: 3098 3101 return &pc->as<OpAdd>().metadata(this).m_arithProfile; … … 3110 3113 } 3111 3114 3115 UnaryArithProfile* CodeBlock::unaryArithProfileForPC(const Instruction* pc) 3116 { 3117 switch (pc->opcodeID()) { 3118 case op_negate: 3119 return &pc->as<OpNegate>().metadata(this).m_arithProfile; 3120 default: 3121 break; 3122 } 3123 3124 return nullptr; 3125 } 3126 3112 3127 bool CodeBlock::couldTakeSpecialArithFastCase(BytecodeIndex bytecodeIndex) 3113 3128 { 3114 3129 if (!hasBaselineJITProfiling()) 3115 3130 return false; 3116 ArithProfile* profile = arithProfileForBytecodeIndex(bytecodeIndex);3131 BinaryArithProfile* profile = binaryArithProfileForBytecodeIndex(bytecodeIndex); 3117 3132 if (!profile) 3118 3133 return false; -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.h
r252385 r252422 84 84 #endif 85 85 86 class UnaryArithProfile; 87 class BinaryArithProfile; 86 88 class BytecodeLivenessAnalysis; 87 89 class CodeBlockSet; … … 97 99 enum class AccessType : int8_t; 98 100 99 struct ArithProfile;100 101 struct OpCatch; 101 102 … … 282 283 JITData& ensureJITDataSlow(const ConcurrentJSLocker&); 283 284 284 JITAddIC* addJITAddIC( ArithProfile*);285 JITMulIC* addJITMulIC( ArithProfile*);286 JITNegIC* addJITNegIC( ArithProfile*);287 JITSubIC* addJITSubIC( ArithProfile*);285 JITAddIC* addJITAddIC(BinaryArithProfile*); 286 JITMulIC* addJITMulIC(BinaryArithProfile*); 287 JITNegIC* addJITNegIC(UnaryArithProfile*); 288 JITSubIC* addJITSubIC(BinaryArithProfile*); 288 289 289 290 template <typename Generator, typename = typename std::enable_if<std::is_same<Generator, JITAddGenerator>::value>::type> 290 JITAddIC* addMathIC( ArithProfile* profile) { return addJITAddIC(profile); }291 JITAddIC* addMathIC(BinaryArithProfile* profile) { return addJITAddIC(profile); } 291 292 292 293 template <typename Generator, typename = typename std::enable_if<std::is_same<Generator, JITMulGenerator>::value>::type> 293 JITMulIC* addMathIC( ArithProfile* profile) { return addJITMulIC(profile); }294 JITMulIC* addMathIC(BinaryArithProfile* profile) { return addJITMulIC(profile); } 294 295 295 296 template <typename Generator, typename = typename std::enable_if<std::is_same<Generator, JITNegGenerator>::value>::type> 296 JITNegIC* addMathIC( ArithProfile* profile) { return addJITNegIC(profile); }297 JITNegIC* addMathIC(UnaryArithProfile* profile) { return addJITNegIC(profile); } 297 298 298 299 template <typename Generator, typename = typename std::enable_if<std::is_same<Generator, JITSubGenerator>::value>::type> 299 JITSubIC* addMathIC( ArithProfile* profile) { return addJITSubIC(profile); }300 JITSubIC* addMathIC(BinaryArithProfile* profile) { return addJITSubIC(profile); } 300 301 301 302 StructureStubInfo* addStubInfo(AccessType); … … 500 501 template<typename Functor> void forEachLLIntCallLinkInfo(const Functor&); 501 502 502 ArithProfile* arithProfileForBytecodeIndex(BytecodeIndex); 503 ArithProfile* arithProfileForPC(const Instruction*); 503 BinaryArithProfile* binaryArithProfileForBytecodeIndex(BytecodeIndex); 504 UnaryArithProfile* unaryArithProfileForBytecodeIndex(BytecodeIndex); 505 BinaryArithProfile* binaryArithProfileForPC(const Instruction*); 506 UnaryArithProfile* unaryArithProfileForPC(const Instruction*); 504 507 505 508 bool couldTakeSpecialArithFastCase(BytecodeIndex bytecodeOffset); -
trunk/Source/JavaScriptCore/bytecode/Fits.h
r252273 r252422 237 237 238 238 template<OpcodeSize size> 239 struct Fits<ResultType, size, std::enable_if_t<sizeof(ResultType) != size, std::true_type>> : public Fits<uint8_t, size> { 240 static_assert(sizeof(ResultType) == sizeof(uint8_t)); 241 using Base = Fits<uint8_t, size>; 242 243 static bool check(ResultType type) { return Base::check(type.bits()); } 244 245 static typename Base::TargetType convert(ResultType type) { return Base::convert(type.bits()); } 246 247 static ResultType convert(typename Base::TargetType type) { return ResultType(Base::convert(type)); } 248 }; 249 250 template<OpcodeSize size> 239 251 struct Fits<OperandTypes, size, std::enable_if_t<sizeof(OperandTypes) != size, std::true_type>> { 240 252 static_assert(sizeof(OperandTypes) == sizeof(uint16_t)); -
trunk/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.cpp
r252273 r252422 67 67 } 68 68 69 case ArithProfileReady: {70 u. arithProfile->emitObserveResult(jit, regs, DoNotHaveTagRegisters);69 case UnaryArithProfileReady: { 70 u.unaryArithProfile->emitObserveResult(jit, regs, DoNotHaveTagRegisters); 71 71 return; 72 } } 72 } 73 74 case BinaryArithProfileReady: { 75 u.binaryArithProfile->emitObserveResult(jit, regs, DoNotHaveTagRegisters); 76 return; 77 } 78 } 73 79 74 80 RELEASE_ASSERT_NOT_REACHED(); … … 95 101 } 96 102 97 case ArithProfileReady: {98 u. arithProfile->observeResult(value);103 case UnaryArithProfileReady: { 104 u.unaryArithProfile->observeResult(value); 99 105 return; 100 } } 106 } 107 108 case BinaryArithProfileReady: { 109 u.binaryArithProfile->observeResult(value); 110 return; 111 } 112 } 101 113 102 114 RELEASE_ASSERT_NOT_REACHED(); -
trunk/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.h
r252273 r252422 37 37 namespace JSC { 38 38 39 class UnaryArithProfile; 40 class BinaryArithProfile; 39 41 class CCallHelpers; 40 42 class CodeBlock; 41 43 class LazyOperandValueProfileKey; 42 struct ArithProfile;43 44 struct ValueProfile; 44 45 … … 58 59 m_kind = None; 59 60 } 60 61 MethodOfGettingAValueProfile( ArithProfile* profile)61 62 MethodOfGettingAValueProfile(UnaryArithProfile* profile) 62 63 { 63 64 if (profile) { 64 m_kind = ArithProfileReady; 65 u.arithProfile = profile; 65 m_kind = UnaryArithProfileReady; 66 u.unaryArithProfile = profile; 67 } else 68 m_kind = None; 69 } 70 71 MethodOfGettingAValueProfile(BinaryArithProfile* profile) 72 { 73 if (profile) { 74 m_kind = BinaryArithProfileReady; 75 u.binaryArithProfile = profile; 66 76 } else 67 77 m_kind = None; … … 80 90 None, 81 91 Ready, 82 ArithProfileReady, 92 UnaryArithProfileReady, 93 BinaryArithProfileReady, 83 94 LazyOperand 84 95 }; … … 91 102 92 103 ValueProfile* profile; 93 ArithProfile* arithProfile; 104 UnaryArithProfile* unaryArithProfile; 105 BinaryArithProfile* binaryArithProfile; 94 106 struct { 95 107 CodeBlock* codeBlock; -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r252273 r252422 1517 1517 } 1518 1518 1519 RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src, OperandTypes types)1519 RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src, ResultType type) 1520 1520 { 1521 1521 switch (opcodeID) { … … 1524 1524 break; 1525 1525 case op_negate: 1526 OpNegate::emit(this, dst, src, type s);1526 OpNegate::emit(this, dst, src, type); 1527 1527 break; 1528 1528 case op_bitnot: -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r252306 r252422 683 683 } 684 684 685 RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src, OperandTypes);685 RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src, ResultType); 686 686 687 687 template<typename BinaryOp> -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r252273 r252422 2147 2147 RefPtr<RegisterID> src = generator.emitNode(m_expr); 2148 2148 generator.emitExpressionInfo(position(), position(), position()); 2149 return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src.get(), OperandTypes(m_expr->resultDescriptor()));2149 return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src.get(), m_expr->resultDescriptor()); 2150 2150 } 2151 2151 -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r252273 r252422 943 943 return node; 944 944 945 { 946 ArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->arithProfileForBytecodeIndex(m_currentIndex); 947 if (arithProfile) { 948 switch (node->op()) { 949 case ArithAdd: 950 case ArithSub: 951 case ValueAdd: 952 if (arithProfile->didObserveDouble()) 953 node->mergeFlags(NodeMayHaveDoubleResult); 954 if (arithProfile->didObserveNonNumeric()) 955 node->mergeFlags(NodeMayHaveNonNumericResult); 956 if (arithProfile->didObserveBigInt()) 957 node->mergeFlags(NodeMayHaveBigIntResult); 958 break; 959 960 case ValueMul: 961 case ArithMul: { 962 if (arithProfile->didObserveInt52Overflow()) 963 node->mergeFlags(NodeMayOverflowInt52); 964 if (arithProfile->didObserveInt32Overflow() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow)) 965 node->mergeFlags(NodeMayOverflowInt32InBaseline); 966 if (arithProfile->didObserveNegZeroDouble() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero)) 967 node->mergeFlags(NodeMayNegZeroInBaseline); 968 if (arithProfile->didObserveDouble()) 969 node->mergeFlags(NodeMayHaveDoubleResult); 970 if (arithProfile->didObserveNonNumeric()) 971 node->mergeFlags(NodeMayHaveNonNumericResult); 972 if (arithProfile->didObserveBigInt()) 973 node->mergeFlags(NodeMayHaveBigIntResult); 974 break; 975 } 976 case ValueNegate: 977 case ArithNegate: { 978 if (arithProfile->lhsObservedType().sawNumber() || arithProfile->didObserveDouble()) 979 node->mergeFlags(NodeMayHaveDoubleResult); 980 if (arithProfile->didObserveNegZeroDouble() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero)) 981 node->mergeFlags(NodeMayNegZeroInBaseline); 982 if (arithProfile->didObserveInt32Overflow() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow)) 983 node->mergeFlags(NodeMayOverflowInt32InBaseline); 984 if (arithProfile->didObserveNonNumeric()) 985 node->mergeFlags(NodeMayHaveNonNumericResult); 986 if (arithProfile->didObserveBigInt()) 987 node->mergeFlags(NodeMayHaveBigIntResult); 988 break; 989 } 990 991 default: 992 break; 993 } 994 } 945 switch (node->op()) { 946 case ArithAdd: 947 case ArithSub: 948 case ValueAdd: { 949 BinaryArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->binaryArithProfileForBytecodeIndex(m_currentIndex); 950 if (!arithProfile) 951 break; 952 if (arithProfile->didObserveDouble()) 953 node->mergeFlags(NodeMayHaveDoubleResult); 954 if (arithProfile->didObserveNonNumeric()) 955 node->mergeFlags(NodeMayHaveNonNumericResult); 956 if (arithProfile->didObserveBigInt()) 957 node->mergeFlags(NodeMayHaveBigIntResult); 958 break; 959 } 960 case ValueMul: 961 case ArithMul: { 962 BinaryArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->binaryArithProfileForBytecodeIndex(m_currentIndex); 963 if (!arithProfile) 964 break; 965 if (arithProfile->didObserveInt52Overflow()) 966 node->mergeFlags(NodeMayOverflowInt52); 967 if (arithProfile->didObserveInt32Overflow() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow)) 968 node->mergeFlags(NodeMayOverflowInt32InBaseline); 969 if (arithProfile->didObserveNegZeroDouble() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero)) 970 node->mergeFlags(NodeMayNegZeroInBaseline); 971 if (arithProfile->didObserveDouble()) 972 node->mergeFlags(NodeMayHaveDoubleResult); 973 if (arithProfile->didObserveNonNumeric()) 974 node->mergeFlags(NodeMayHaveNonNumericResult); 975 if (arithProfile->didObserveBigInt()) 976 node->mergeFlags(NodeMayHaveBigIntResult); 977 break; 978 } 979 case ValueNegate: 980 case ArithNegate: { 981 UnaryArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->unaryArithProfileForBytecodeIndex(m_currentIndex); 982 if (!arithProfile) 983 break; 984 if (arithProfile->argObservedType().sawNumber() || arithProfile->didObserveDouble()) 985 node->mergeFlags(NodeMayHaveDoubleResult); 986 if (arithProfile->didObserveNegZeroDouble() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero)) 987 node->mergeFlags(NodeMayNegZeroInBaseline); 988 if (arithProfile->didObserveInt32Overflow() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow)) 989 node->mergeFlags(NodeMayOverflowInt32InBaseline); 990 if (arithProfile->didObserveNonNumeric()) 991 node->mergeFlags(NodeMayHaveNonNumericResult); 992 if (arithProfile->didObserveBigInt()) 993 node->mergeFlags(NodeMayHaveBigIntResult); 994 break; 995 } 996 997 default: 998 break; 995 999 } 996 1000 … … 1034 1038 // FIXME: It might be possible to make this more granular. 1035 1039 node->mergeFlags(NodeMayOverflowInt32InBaseline | NodeMayNegZeroInBaseline); 1036 1037 ArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->arithProfileForBytecodeIndex(m_currentIndex);1040 1041 BinaryArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->binaryArithProfileForBytecodeIndex(m_currentIndex); 1038 1042 if (arithProfile->didObserveBigInt()) 1039 1043 node->mergeFlags(NodeMayHaveBigIntResult); -
trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp
r252273 r252422 1655 1655 1656 1656 if (profiledBlock->hasBaselineJITProfiling()) { 1657 if (ArithProfile* result = profiledBlock->arithProfileForBytecodeIndex(node->origin.semantic.bytecodeIndex())) 1657 if (BinaryArithProfile* result = profiledBlock->binaryArithProfileForBytecodeIndex(node->origin.semantic.bytecodeIndex())) 1658 return result; 1659 if (UnaryArithProfile* result = profiledBlock->unaryArithProfileForBytecodeIndex(node->origin.semantic.bytecodeIndex())) 1658 1660 return result; 1659 1661 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r252273 r252422 3996 3996 CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic); 3997 3997 BytecodeIndex bytecodeIndex = node->origin.semantic.bytecodeIndex(); 3998 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeIndex(bytecodeIndex);3998 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeIndex(bytecodeIndex); 3999 3999 JITAddIC* addIC = m_jit.codeBlock()->addJITAddIC(arithProfile); 4000 4000 auto repatchingFunction = operationValueAddOptimize; … … 4020 4020 CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic); 4021 4021 BytecodeIndex bytecodeIndex = node->origin.semantic.bytecodeIndex(); 4022 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeIndex(bytecodeIndex);4022 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeIndex(bytecodeIndex); 4023 4023 JITSubIC* subIC = m_jit.codeBlock()->addJITSubIC(arithProfile); 4024 4024 auto repatchingFunction = operationValueSubOptimize; … … 4614 4614 CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic); 4615 4615 BytecodeIndex bytecodeIndex = node->origin.semantic.bytecodeIndex(); 4616 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeIndex(bytecodeIndex);4616 UnaryArithProfile* arithProfile = baselineCodeBlock->unaryArithProfileForBytecodeIndex(bytecodeIndex); 4617 4617 JITNegIC* negIC = m_jit.codeBlock()->addJITNegIC(arithProfile); 4618 4618 auto repatchingFunction = operationArithNegateOptimize; … … 4837 4837 CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic); 4838 4838 BytecodeIndex bytecodeIndex = node->origin.semantic.bytecodeIndex(); 4839 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeIndex(bytecodeIndex);4839 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeIndex(bytecodeIndex); 4840 4840 JITMulIC* mulIC = m_jit.codeBlock()->addJITMulIC(arithProfile); 4841 4841 auto repatchingFunction = operationValueMulOptimize; -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r252273 r252422 2117 2117 CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic); 2118 2118 BytecodeIndex bytecodeIndex = m_node->origin.semantic.bytecodeIndex(); 2119 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeIndex(bytecodeIndex);2119 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeIndex(bytecodeIndex); 2120 2120 auto repatchingFunction = operationValueAddOptimize; 2121 2121 auto nonRepatchingFunction = operationValueAdd; … … 2138 2138 CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic); 2139 2139 BytecodeIndex bytecodeIndex = m_node->origin.semantic.bytecodeIndex(); 2140 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeIndex(bytecodeIndex);2140 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeIndex(bytecodeIndex); 2141 2141 auto repatchingFunction = operationValueSubOptimize; 2142 2142 auto nonRepatchingFunction = operationValueSub; … … 2159 2159 CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic); 2160 2160 BytecodeIndex bytecodeIndex = m_node->origin.semantic.bytecodeIndex(); 2161 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeIndex(bytecodeIndex);2161 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeIndex(bytecodeIndex); 2162 2162 auto repatchingFunction = operationValueMulOptimize; 2163 2163 auto nonRepatchingFunction = operationValueMul; … … 2167 2167 template <typename Generator, typename Func1, typename Func2, 2168 2168 typename = std::enable_if_t<std::is_function<typename std::remove_pointer<Func1>::type>::value && std::is_function<typename std::remove_pointer<Func2>::type>::value>> 2169 void compileUnaryMathIC( ArithProfile* arithProfile, Func1 repatchingFunction, Func2 nonRepatchingFunction)2169 void compileUnaryMathIC(UnaryArithProfile* arithProfile, Func1 repatchingFunction, Func2 nonRepatchingFunction) 2170 2170 { 2171 2171 Node* node = m_node; … … 2253 2253 template <typename Generator, typename Func1, typename Func2, 2254 2254 typename = std::enable_if_t<std::is_function<typename std::remove_pointer<Func1>::type>::value && std::is_function<typename std::remove_pointer<Func2>::type>::value>> 2255 void compileBinaryMathIC( ArithProfile* arithProfile, Func1 repatchingFunction, Func2 nonRepatchingFunction)2255 void compileBinaryMathIC(BinaryArithProfile* arithProfile, Func1 repatchingFunction, Func2 nonRepatchingFunction) 2256 2256 { 2257 2257 Node* node = m_node; … … 2422 2422 CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic); 2423 2423 BytecodeIndex bytecodeIndex = m_node->origin.semantic.bytecodeIndex(); 2424 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeIndex(bytecodeIndex);2424 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeIndex(bytecodeIndex); 2425 2425 auto repatchingFunction = operationValueSubOptimize; 2426 2426 auto nonRepatchingFunction = operationValueSub; … … 3100 3100 CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic); 3101 3101 BytecodeIndex bytecodeIndex = m_node->origin.semantic.bytecodeIndex(); 3102 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeIndex(bytecodeIndex);3102 UnaryArithProfile* arithProfile = baselineCodeBlock->unaryArithProfileForBytecodeIndex(bytecodeIndex); 3103 3103 auto repatchingFunction = operationArithNegateOptimize; 3104 3104 auto nonRepatchingFunction = operationArithNegate; -
trunk/Source/JavaScriptCore/jit/JIT.h
r252273 r252422 920 920 GetPutInfo copiedGetPutInfo(OpPutToScope); 921 921 template<typename BinaryOp> 922 ArithProfile copiedArithProfile(BinaryOp);922 BinaryArithProfile copiedArithProfile(BinaryOp); 923 923 924 924 Interpreter* m_interpreter; … … 940 940 941 941 HashMap<unsigned, unsigned> m_copiedGetPutInfos; 942 HashMap<uint64_t, ArithProfile> m_copiedArithProfiles;942 HashMap<uint64_t, BinaryArithProfile> m_copiedArithProfiles; 943 943 944 944 JumpList m_exceptionChecks; -
trunk/Source/JavaScriptCore/jit/JITAddGenerator.cpp
r252273 r252422 35 35 namespace JSC { 36 36 37 JITMathICInlineResult JITAddGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const ArithProfile* arithProfile)37 JITMathICInlineResult JITAddGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const BinaryArithProfile* arithProfile) 38 38 { 39 39 // We default to speculating int32. … … 74 74 } 75 75 76 bool JITAddGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile* arithProfile, bool shouldEmitProfiling)76 bool JITAddGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const BinaryArithProfile* arithProfile, bool shouldEmitProfiling) 77 77 { 78 78 ASSERT(m_scratchGPR != InvalidGPRReg); -
trunk/Source/JavaScriptCore/jit/JITAddGenerator.h
r252273 r252422 56 56 } 57 57 58 JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const ArithProfile*);59 bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile*, bool shouldEmitProfiling);58 JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const BinaryArithProfile*); 59 bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const BinaryArithProfile*, bool shouldEmitProfiling); 60 60 61 61 static bool isLeftOperandValidConstant(SnippetOperand leftOperand) { return leftOperand.isPositiveConstInt32(); } -
trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp
r252273 r252422 454 454 void JIT::emit_op_negate(const Instruction* currentInstruction) 455 455 { 456 ArithProfile* arithProfile = ¤tInstruction->as<OpNegate>().metadata(m_codeBlock).m_arithProfile;456 UnaryArithProfile* arithProfile = ¤tInstruction->as<OpNegate>().metadata(m_codeBlock).m_arithProfile; 457 457 JITNegIC* negateIC = m_codeBlock->addJITNegIC(arithProfile); 458 458 m_instructionToMathIC.add(currentInstruction, negateIC); … … 635 635 } 636 636 637 ALWAYS_INLINE static OperandTypes getOperandTypes(const ArithProfile& arithProfile)638 {639 return OperandTypes(arithProfile.lhsResultType(), arithProfile.rhsResultType());640 }641 642 637 void JIT::emit_op_add(const Instruction* currentInstruction) 643 638 { 644 ArithProfile* arithProfile = ¤tInstruction->as<OpAdd>().metadata(m_codeBlock).m_arithProfile;639 BinaryArithProfile* arithProfile = ¤tInstruction->as<OpAdd>().metadata(m_codeBlock).m_arithProfile; 645 640 JITAddIC* addIC = m_codeBlock->addJITAddIC(arithProfile); 646 641 m_instructionToMathIC.add(currentInstruction, addIC); … … 687 682 bool generatedInlineCode = mathIC->generateInline(*this, mathICGenerationState); 688 683 if (!generatedInlineCode) { 689 ArithProfile* arithProfile = mathIC->arithProfile();684 UnaryArithProfile* arithProfile = mathIC->arithProfile(); 690 685 if (arithProfile && shouldEmitProfiling()) 691 686 callOperationWithResult(profiledFunction, resultRegs, TrustedImmPtr(m_codeBlock->globalObject()), srcRegs, arithProfile); … … 710 705 { 711 706 auto bytecode = currentInstruction->as<Op>(); 712 OperandTypes types = getOperandTypes(copiedArithProfile(bytecode));713 707 int result = bytecode.m_dst.offset(); 714 708 int op1 = bytecode.m_lhs.offset(); … … 729 723 #endif 730 724 731 SnippetOperand leftOperand( types.first());732 SnippetOperand rightOperand( types.second());725 SnippetOperand leftOperand(bytecode.m_operandTypes.first()); 726 SnippetOperand rightOperand(bytecode.m_operandTypes.second()); 733 727 734 728 if (isOperandConstantInt(op1)) … … 760 754 else if (rightOperand.isConst()) 761 755 emitGetVirtualRegister(op2, rightRegs); 762 ArithProfile* arithProfile = mathIC->arithProfile();756 BinaryArithProfile* arithProfile = mathIC->arithProfile(); 763 757 if (arithProfile && shouldEmitProfiling()) 764 758 callOperationWithResult(profiledFunction, resultRegs, TrustedImmPtr(m_codeBlock->globalObject()), leftRegs, rightRegs, arithProfile); … … 800 794 #endif 801 795 802 ArithProfile* arithProfile = mathIC->arithProfile();796 UnaryArithProfile* arithProfile = mathIC->arithProfile(); 803 797 if (arithProfile && shouldEmitProfiling()) { 804 798 if (mathICGenerationState.shouldSlowPathRepatch) … … 832 826 833 827 auto bytecode = currentInstruction->as<Op>(); 834 OperandTypes types = getOperandTypes(copiedArithProfile(bytecode));835 828 int result = bytecode.m_dst.offset(); 836 829 int op1 = bytecode.m_lhs.offset(); … … 847 840 #endif 848 841 849 SnippetOperand leftOperand( types.first());850 SnippetOperand rightOperand( types.second());842 SnippetOperand leftOperand(bytecode.m_operandTypes.first()); 843 SnippetOperand rightOperand(bytecode.m_operandTypes.second()); 851 844 852 845 if (isOperandConstantInt(op1)) … … 866 859 #endif 867 860 868 ArithProfile* arithProfile = mathIC->arithProfile();861 BinaryArithProfile* arithProfile = mathIC->arithProfile(); 869 862 if (arithProfile && shouldEmitProfiling()) { 870 863 if (mathICGenerationState.shouldSlowPathRepatch) … … 894 887 { 895 888 auto bytecode = currentInstruction->as<OpDiv>(); 896 auto& metadata = bytecode.metadata(m_codeBlock);897 889 int result = bytecode.m_dst.offset(); 898 890 int op1 = bytecode.m_lhs.offset(); … … 900 892 901 893 #if USE(JSVALUE64) 902 OperandTypes types = getOperandTypes(metadata.m_arithProfile);903 894 JSValueRegs leftRegs = JSValueRegs(regT0); 904 895 JSValueRegs rightRegs = JSValueRegs(regT1); … … 906 897 GPRReg scratchGPR = regT2; 907 898 #else 908 OperandTypes types = getOperandTypes(metadata.m_arithProfile);909 899 JSValueRegs leftRegs = JSValueRegs(regT1, regT0); 910 900 JSValueRegs rightRegs = JSValueRegs(regT3, regT2); … … 914 904 FPRReg scratchFPR = fpRegT2; 915 905 916 ArithProfile* arithProfile = nullptr;906 BinaryArithProfile* arithProfile = nullptr; 917 907 if (shouldEmitProfiling()) 918 908 arithProfile = ¤tInstruction->as<OpDiv>().metadata(m_codeBlock).m_arithProfile; 919 909 920 SnippetOperand leftOperand( types.first());921 SnippetOperand rightOperand( types.second());910 SnippetOperand leftOperand(bytecode.m_operandTypes.first()); 911 SnippetOperand rightOperand(bytecode.m_operandTypes.second()); 922 912 923 913 if (isOperandConstantInt(op1)) … … 961 951 void JIT::emit_op_mul(const Instruction* currentInstruction) 962 952 { 963 ArithProfile* arithProfile = ¤tInstruction->as<OpMul>().metadata(m_codeBlock).m_arithProfile;953 BinaryArithProfile* arithProfile = ¤tInstruction->as<OpMul>().metadata(m_codeBlock).m_arithProfile; 964 954 JITMulIC* mulIC = m_codeBlock->addJITMulIC(arithProfile); 965 955 m_instructionToMathIC.add(currentInstruction, mulIC); … … 977 967 void JIT::emit_op_sub(const Instruction* currentInstruction) 978 968 { 979 ArithProfile* arithProfile = ¤tInstruction->as<OpSub>().metadata(m_codeBlock).m_arithProfile;969 BinaryArithProfile* arithProfile = ¤tInstruction->as<OpSub>().metadata(m_codeBlock).m_arithProfile; 980 970 JITSubIC* subIC = m_codeBlock->addJITSubIC(arithProfile); 981 971 m_instructionToMathIC.add(currentInstruction, subIC); -
trunk/Source/JavaScriptCore/jit/JITDivGenerator.cpp
r252273 r252422 131 131 #endif 132 132 if (m_arithProfile) 133 jit.or32(CCallHelpers::TrustedImm32(ArithProfile::specialFastPathBit), CCallHelpers::AbsoluteAddress(m_arithProfile->addressOfBits()));133 m_arithProfile->emitUnconditionalSet(jit, BinaryArithProfile::specialFastPathBit); 134 134 jit.boxDouble(m_leftFPR, m_result); 135 135 } -
trunk/Source/JavaScriptCore/jit/JITDivGenerator.h
r252273 r252422 38 38 JSValueRegs result, JSValueRegs left, JSValueRegs right, 39 39 FPRReg leftFPR, FPRReg rightFPR, GPRReg scratchGPR, FPRReg scratchFPR, 40 ArithProfile* arithProfile = nullptr)40 BinaryArithProfile* arithProfile = nullptr) 41 41 : m_leftOperand(leftOperand) 42 42 , m_rightOperand(rightOperand) … … 72 72 FPRReg m_scratchFPR; 73 73 bool m_didEmitFastPath { false }; 74 ArithProfile* m_arithProfile;74 BinaryArithProfile* m_arithProfile; 75 75 76 76 CCallHelpers::JumpList m_endJumpList; -
trunk/Source/JavaScriptCore/jit/JITInlines.h
r252273 r252422 717 717 718 718 template<typename BinaryOp> 719 ALWAYS_INLINE ArithProfile JIT::copiedArithProfile(BinaryOp bytecode)719 ALWAYS_INLINE BinaryArithProfile JIT::copiedArithProfile(BinaryOp bytecode) 720 720 { 721 721 uint64_t key = (static_cast<uint64_t>(BinaryOp::opcodeID) + 1) << 32 | static_cast<uint64_t>(bytecode.m_metadataID); … … 723 723 if (iterator != m_copiedArithProfiles.end()) 724 724 return iterator->value; 725 ArithProfile arithProfile = bytecode.metadata(m_codeBlock).m_arithProfile;725 BinaryArithProfile arithProfile = bytecode.metadata(m_codeBlock).m_arithProfile; 726 726 m_copiedArithProfiles.add(key, arithProfile); 727 727 return arithProfile; -
trunk/Source/JavaScriptCore/jit/JITMathIC.h
r252273 r252422 53 53 #define ENABLE_MATH_IC_STATS 0 54 54 55 template <typename GeneratorType, bool(*isProfileEmpty)(ArithProfile&)>55 template <typename GeneratorType, typename ArithProfileType> 56 56 class JITMathIC { 57 57 WTF_MAKE_FAST_ALLOCATED; 58 58 public: 59 JITMathIC(ArithProfile * arithProfile)59 JITMathIC(ArithProfileType* arithProfile) 60 60 : m_arithProfile(arithProfile) 61 61 { … … 72 72 73 73 if (m_arithProfile) { 74 if ( isProfileEmpty(*m_arithProfile)) {74 if (m_arithProfile->isObservedTypeEmpty()) { 75 75 // It looks like the MathIC has yet to execute. We don't want to emit code in this 76 76 // case for a couple reasons. First, the operation may never execute, so if we don't emit … … 224 224 } 225 225 226 ArithProfile * arithProfile() const { return m_arithProfile; }226 ArithProfileType* arithProfile() const { return m_arithProfile; } 227 227 228 228 #if ENABLE(MATH_IC_STATS) … … 237 237 #endif 238 238 239 ArithProfile * m_arithProfile;239 ArithProfileType* m_arithProfile; 240 240 MacroAssemblerCodeRef<JITStubRoutinePtrTag> m_code; 241 241 CodeLocationLabel<JSInternalPtrTag> m_inlineStart; … … 247 247 }; 248 248 249 inline bool isBinaryProfileEmpty(ArithProfile& arithProfile)250 {251 return arithProfile.lhsObservedType().isEmpty() || arithProfile.rhsObservedType().isEmpty();252 }253 249 template <typename GeneratorType> 254 class JITBinaryMathIC : public JITMathIC<GeneratorType, isBinaryProfileEmpty> {250 class JITBinaryMathIC : public JITMathIC<GeneratorType, BinaryArithProfile> { 255 251 public: 256 JITBinaryMathIC( ArithProfile* arithProfile)257 : JITMathIC<GeneratorType, isBinaryProfileEmpty>(arithProfile)252 JITBinaryMathIC(BinaryArithProfile* arithProfile) 253 : JITMathIC<GeneratorType, BinaryArithProfile>(arithProfile) 258 254 { 259 255 } … … 264 260 typedef JITBinaryMathIC<JITSubGenerator> JITSubIC; 265 261 266 267 inline bool isUnaryProfileEmpty(ArithProfile& arithProfile)268 {269 return arithProfile.lhsObservedType().isEmpty();270 }271 262 template <typename GeneratorType> 272 class JITUnaryMathIC : public JITMathIC<GeneratorType, isUnaryProfileEmpty> {263 class JITUnaryMathIC : public JITMathIC<GeneratorType, UnaryArithProfile> { 273 264 public: 274 JITUnaryMathIC( ArithProfile* arithProfile)275 : JITMathIC<GeneratorType, isUnaryProfileEmpty>(arithProfile)265 JITUnaryMathIC(UnaryArithProfile* arithProfile) 266 : JITMathIC<GeneratorType, UnaryArithProfile>(arithProfile) 276 267 { 277 268 } -
trunk/Source/JavaScriptCore/jit/JITMulGenerator.cpp
r252273 r252422 34 34 namespace JSC { 35 35 36 JITMathICInlineResult JITMulGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const ArithProfile* arithProfile)36 JITMathICInlineResult JITMulGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const BinaryArithProfile* arithProfile) 37 37 { 38 38 // We default to speculating int32. … … 90 90 } 91 91 92 bool JITMulGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile* arithProfile, bool shouldEmitProfiling)92 bool JITMulGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const BinaryArithProfile* arithProfile, bool shouldEmitProfiling) 93 93 { 94 94 ASSERT(m_scratchGPR != InvalidGPRReg); … … 206 206 CCallHelpers::Jump notNegativeZero = jit.branch64(CCallHelpers::NotEqual, m_result.payloadGPR(), CCallHelpers::TrustedImm64(negativeZeroBits)); 207 207 208 jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));208 arithProfile->emitUnconditionalSet(jit, BinaryArithProfile::NegZeroDouble); 209 209 CCallHelpers::Jump done = jit.jump(); 210 210 211 211 notNegativeZero.link(&jit); 212 jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));212 arithProfile->emitUnconditionalSet(jit, BinaryArithProfile::NonNegZeroDouble); 213 213 214 214 jit.move(m_result.payloadGPR(), m_scratchGPR); … … 217 217 CCallHelpers::Jump noInt52Overflow = jit.branch32(CCallHelpers::LessThanOrEqual, m_scratchGPR, CCallHelpers::TrustedImm32(0x431)); 218 218 219 jit.or32(CCallHelpers::TrustedImm32(ArithProfile::Int52Overflow), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));219 arithProfile->emitUnconditionalSet(jit, BinaryArithProfile::Int52Overflow); 220 220 noInt52Overflow.link(&jit); 221 221 … … 228 228 notNegativeZero.append(jit.branch32(CCallHelpers::NotEqual, m_result.tagGPR(), CCallHelpers::TrustedImm32(negativeZeroBits >> 32))); 229 229 230 jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));230 arithProfile->emitUnconditionalSet(jit, BinaryArithProfile::NegZeroDouble); 231 231 CCallHelpers::Jump done = jit.jump(); 232 232 233 233 notNegativeZero.link(&jit); 234 jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));234 arithProfile->emitUnconditionalSet(jit, BinaryArithProfile::NonNegZeroDouble); 235 235 236 236 jit.move(m_result.tagGPR(), m_scratchGPR); … … 238 238 jit.and32(CCallHelpers::Imm32(0x7ff), m_scratchGPR); 239 239 CCallHelpers::Jump noInt52Overflow = jit.branch32(CCallHelpers::LessThanOrEqual, m_scratchGPR, CCallHelpers::TrustedImm32(0x431)); 240 241 jit.or32(CCallHelpers::TrustedImm32(ArithProfile::Int52Overflow), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));240 241 arithProfile->emitUnconditionalSet(jit, BinaryArithProfile::Int52Overflow); 242 242 243 243 endJumpList.append(noInt52Overflow); -
trunk/Source/JavaScriptCore/jit/JITMulGenerator.h
r252273 r252422 57 57 } 58 58 59 JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const ArithProfile*);60 bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowJumpList, const ArithProfile*, bool shouldEmitProfiling);59 JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const BinaryArithProfile*); 60 bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowJumpList, const BinaryArithProfile*, bool shouldEmitProfiling); 61 61 62 62 static bool isLeftOperandValidConstant(SnippetOperand leftOperand) { return leftOperand.isPositiveConstInt32(); } -
trunk/Source/JavaScriptCore/jit/JITNegGenerator.cpp
r252273 r252422 33 33 namespace JSC { 34 34 35 JITMathICInlineResult JITNegGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const ArithProfile* arithProfile)35 JITMathICInlineResult JITNegGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const UnaryArithProfile* arithProfile) 36 36 { 37 37 ASSERT(m_scratchGPR != InvalidGPRReg); … … 46 46 ObservedType observedTypes = ObservedType().withInt32(); 47 47 if (arithProfile) 48 observedTypes = arithProfile-> lhsObservedType();48 observedTypes = arithProfile->argObservedType(); 49 49 ASSERT_WITH_MESSAGE(!observedTypes.isEmpty(), "We should not attempt to generate anything if we do not have a profile."); 50 50 … … 83 83 } 84 84 85 bool JITNegGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile* arithProfile, bool shouldEmitProfiling)85 bool JITNegGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const UnaryArithProfile* arithProfile, bool shouldEmitProfiling) 86 86 { 87 87 ASSERT(m_scratchGPR != m_src.payloadGPR()); … … 118 118 // The flags of ArithNegate are basic in DFG. 119 119 // We only need to know if we ever produced a number. 120 if (shouldEmitProfiling && arithProfile && !arithProfile-> lhsObservedType().sawNumber() && !arithProfile->didObserveDouble())120 if (shouldEmitProfiling && arithProfile && !arithProfile->argObservedType().sawNumber() && !arithProfile->didObserveDouble()) 121 121 arithProfile->emitSetDouble(jit); 122 122 return true; -
trunk/Source/JavaScriptCore/jit/JITNegGenerator.h
r252273 r252422 44 44 { } 45 45 46 JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const ArithProfile*);47 bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile*, bool shouldEmitProfiling);46 JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const UnaryArithProfile*); 47 bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const UnaryArithProfile*, bool shouldEmitProfiling); 48 48 49 49 private: -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r252273 r252422 2646 2646 } 2647 2647 2648 ALWAYS_INLINE static JSValue profiledAdd(JSGlobalObject* globalObject, JSValue op1, JSValue op2, ArithProfile& arithProfile)2648 ALWAYS_INLINE static JSValue profiledAdd(JSGlobalObject* globalObject, JSValue op1, JSValue op2, BinaryArithProfile& arithProfile) 2649 2649 { 2650 2650 arithProfile.observeLHSAndRHS(op1, op2); … … 2662 2662 } 2663 2663 2664 EncodedJSValue JIT_OPERATION operationValueAddProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)2664 EncodedJSValue JIT_OPERATION operationValueAddProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile* arithProfile) 2665 2665 { 2666 2666 ASSERT(arithProfile); … … 2680 2680 JSValue op2 = JSValue::decode(encodedOp2); 2681 2681 2682 ArithProfile* arithProfile = addIC->arithProfile();2682 BinaryArithProfile* arithProfile = addIC->arithProfile(); 2683 2683 ASSERT(arithProfile); 2684 2684 arithProfile->observeLHSAndRHS(op1, op2); … … 2702 2702 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 2703 2703 2704 ArithProfile* arithProfile = addIC->arithProfile();2704 BinaryArithProfile* arithProfile = addIC->arithProfile(); 2705 2705 ASSERT(arithProfile); 2706 2706 return JSValue::encode(profiledAdd(globalObject, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2), *arithProfile)); … … 2717 2717 2718 2718 auto nonOptimizeVariant = operationValueAddNoOptimize; 2719 if ( ArithProfile* arithProfile = addIC->arithProfile())2719 if (BinaryArithProfile* arithProfile = addIC->arithProfile()) 2720 2720 arithProfile->observeLHSAndRHS(op1, op2); 2721 2721 addIC->generateOutOfLine(callFrame->codeBlock(), nonOptimizeVariant); … … 2750 2750 } 2751 2751 2752 ALWAYS_INLINE static EncodedJSValue profiledMul(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true)2752 ALWAYS_INLINE static EncodedJSValue profiledMul(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true) 2753 2753 { 2754 2754 VM& vm = globalObject->vm(); … … 2791 2791 2792 2792 auto nonOptimizeVariant = operationValueMulNoOptimize; 2793 if ( ArithProfile* arithProfile = mulIC->arithProfile())2793 if (BinaryArithProfile* arithProfile = mulIC->arithProfile()) 2794 2794 arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); 2795 2795 mulIC->generateOutOfLine(callFrame->codeBlock(), nonOptimizeVariant); … … 2802 2802 } 2803 2803 2804 EncodedJSValue JIT_OPERATION operationValueMulProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)2804 EncodedJSValue JIT_OPERATION operationValueMulProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile* arithProfile) 2805 2805 { 2806 2806 VM& vm = globalObject->vm(); … … 2818 2818 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 2819 2819 2820 ArithProfile* arithProfile = mulIC->arithProfile();2820 BinaryArithProfile* arithProfile = mulIC->arithProfile(); 2821 2821 ASSERT(arithProfile); 2822 2822 arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); … … 2837 2837 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 2838 2838 2839 ArithProfile* arithProfile = mulIC->arithProfile();2839 BinaryArithProfile* arithProfile = mulIC->arithProfile(); 2840 2840 ASSERT(arithProfile); 2841 2841 return profiledMul(globalObject, encodedOp1, encodedOp2, *arithProfile); … … 2863 2863 } 2864 2864 2865 EncodedJSValue JIT_OPERATION operationArithNegateProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOperand, ArithProfile* arithProfile)2865 EncodedJSValue JIT_OPERATION operationArithNegateProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOperand, UnaryArithProfile* arithProfile) 2866 2866 { 2867 2867 ASSERT(arithProfile); … … 2872 2872 2873 2873 JSValue operand = JSValue::decode(encodedOperand); 2874 arithProfile->observe LHS(operand);2874 arithProfile->observeArg(operand); 2875 2875 2876 2876 JSValue primValue = operand.toPrimitive(globalObject); … … 2900 2900 JSValue operand = JSValue::decode(encodedOperand); 2901 2901 2902 ArithProfile* arithProfile = negIC->arithProfile();2902 UnaryArithProfile* arithProfile = negIC->arithProfile(); 2903 2903 ASSERT(arithProfile); 2904 arithProfile->observe LHS(operand);2904 arithProfile->observeArg(operand); 2905 2905 negIC->generateOutOfLine(callFrame->codeBlock(), operationArithNegateProfiled); 2906 2906 … … 2934 2934 JSValue operand = JSValue::decode(encodedOperand); 2935 2935 2936 if ( ArithProfile* arithProfile = negIC->arithProfile())2937 arithProfile->observe LHS(operand);2936 if (UnaryArithProfile* arithProfile = negIC->arithProfile()) 2937 arithProfile->observeArg(operand); 2938 2938 negIC->generateOutOfLine(callFrame->codeBlock(), operationArithNegate); 2939 2939 … … 2961 2961 } 2962 2962 2963 ALWAYS_INLINE static EncodedJSValue profiledSub(VM& vm, JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true)2963 ALWAYS_INLINE static EncodedJSValue profiledSub(VM& vm, JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true) 2964 2964 { 2965 2965 auto scope = DECLARE_THROW_SCOPE(vm); … … 2985 2985 } 2986 2986 2987 EncodedJSValue JIT_OPERATION operationValueSubProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)2987 EncodedJSValue JIT_OPERATION operationValueSubProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile* arithProfile) 2988 2988 { 2989 2989 ASSERT(arithProfile); … … 3003 3003 3004 3004 auto nonOptimizeVariant = operationValueSubNoOptimize; 3005 if ( ArithProfile* arithProfile = subIC->arithProfile())3005 if (BinaryArithProfile* arithProfile = subIC->arithProfile()) 3006 3006 arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); 3007 3007 subIC->generateOutOfLine(callFrame->codeBlock(), nonOptimizeVariant); … … 3029 3029 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3030 3030 3031 ArithProfile* arithProfile = subIC->arithProfile();3031 BinaryArithProfile* arithProfile = subIC->arithProfile(); 3032 3032 ASSERT(arithProfile); 3033 3033 arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); … … 3048 3048 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3049 3049 3050 ArithProfile* arithProfile = subIC->arithProfile();3050 BinaryArithProfile* arithProfile = subIC->arithProfile(); 3051 3051 ASSERT(arithProfile); 3052 3052 return profiledSub(vm, globalObject, encodedOp1, encodedOp2, *arithProfile); -
trunk/Source/JavaScriptCore/jit/JITOperations.h
r252273 r252422 39 39 class ArrayAllocationProfile; 40 40 class ArrayProfile; 41 class UnaryArithProfile; 42 class BinaryArithProfile; 41 43 class Butterfly; 42 44 class CallFrame; … … 65 67 struct InlineCallFrame; 66 68 struct Instruction; 67 struct ArithProfile;68 69 69 70 extern "C" { … … 78 79 Aap: ArrayAllocationProfile* 79 80 Ap: ArrayProfile* 80 Arp: ArithProfile*81 Arp: BinaryArithProfile* 81 82 B: Butterfly* 82 83 By: ByValInfo* … … 283 284 284 285 EncodedJSValue JIT_OPERATION operationValueAdd(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL; 285 EncodedJSValue JIT_OPERATION operationValueAddProfiled(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*) WTF_INTERNAL;286 EncodedJSValue JIT_OPERATION operationValueAddProfiled(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile*) WTF_INTERNAL; 286 287 EncodedJSValue JIT_OPERATION operationValueAddProfiledOptimize(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC*) WTF_INTERNAL; 287 288 EncodedJSValue JIT_OPERATION operationValueAddProfiledNoOptimize(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC*) WTF_INTERNAL; … … 293 294 EncodedJSValue JIT_OPERATION operationValueMulProfiledOptimize(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC*) WTF_INTERNAL; 294 295 EncodedJSValue JIT_OPERATION operationValueMulProfiledNoOptimize(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC*) WTF_INTERNAL; 295 EncodedJSValue JIT_OPERATION operationValueMulProfiled(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*) WTF_INTERNAL;296 EncodedJSValue JIT_OPERATION operationValueMulProfiled(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile*) WTF_INTERNAL; 296 297 EncodedJSValue JIT_OPERATION operationArithNegate(JSGlobalObject*, EncodedJSValue operand); 297 EncodedJSValue JIT_OPERATION operationArithNegateProfiled(JSGlobalObject*, EncodedJSValue operand, ArithProfile*);298 EncodedJSValue JIT_OPERATION operationArithNegateProfiled(JSGlobalObject*, EncodedJSValue operand, UnaryArithProfile*); 298 299 EncodedJSValue JIT_OPERATION operationArithNegateProfiledOptimize(JSGlobalObject*, EncodedJSValue encodedOperand, JITNegIC*); 299 300 EncodedJSValue JIT_OPERATION operationArithNegateOptimize(JSGlobalObject*, EncodedJSValue encodedOperand, JITNegIC*); 300 301 EncodedJSValue JIT_OPERATION operationValueSub(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL; 301 EncodedJSValue JIT_OPERATION operationValueSubProfiled(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*) WTF_INTERNAL;302 EncodedJSValue JIT_OPERATION operationValueSubProfiled(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile*) WTF_INTERNAL; 302 303 EncodedJSValue JIT_OPERATION operationValueSubOptimize(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC*) WTF_INTERNAL; 303 304 EncodedJSValue JIT_OPERATION operationValueSubNoOptimize(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC*) WTF_INTERNAL; -
trunk/Source/JavaScriptCore/jit/JITSubGenerator.cpp
r252273 r252422 34 34 namespace JSC { 35 35 36 JITMathICInlineResult JITSubGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const ArithProfile* arithProfile)36 JITMathICInlineResult JITSubGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const BinaryArithProfile* arithProfile) 37 37 { 38 38 // We default to speculating int32. … … 79 79 } 80 80 81 bool JITSubGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile* arithProfile, bool shouldEmitProfiling)81 bool JITSubGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const BinaryArithProfile* arithProfile, bool shouldEmitProfiling) 82 82 { 83 83 ASSERT(m_scratchGPR != InvalidGPRReg); -
trunk/Source/JavaScriptCore/jit/JITSubGenerator.h
r252273 r252422 54 54 { } 55 55 56 JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const ArithProfile*);57 bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile*, bool shouldEmitProfiling);56 JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const BinaryArithProfile*); 57 bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const BinaryArithProfile*, bool shouldEmitProfiling); 58 58 59 59 static bool isLeftOperandValidConstant(SnippetOperand) { return false; } -
trunk/Source/JavaScriptCore/llint/LLIntData.cpp
r252273 r252422 148 148 149 149 { 150 ArithProfile arithProfile; 150 UnaryArithProfile arithProfile; 151 arithProfile.argSawInt32(); 152 ASSERT(arithProfile.bits() == UnaryArithProfile::observedIntBits()); 153 ASSERT(arithProfile.argObservedType().isOnlyInt32()); 154 } 155 { 156 UnaryArithProfile arithProfile; 157 arithProfile.argSawNumber(); 158 ASSERT(arithProfile.bits() == UnaryArithProfile::observedNumberBits()); 159 ASSERT(arithProfile.argObservedType().isOnlyNumber()); 160 } 161 162 { 163 BinaryArithProfile arithProfile; 151 164 arithProfile.lhsSawInt32(); 152 165 arithProfile.rhsSawInt32(); 153 ASSERT(arithProfile.bits() == ArithProfile::observedBinaryIntInt().bits());154 STATIC_ASSERT(ArithProfile::observedBinaryIntInt().lhsObservedType().isOnlyInt32());155 STATIC_ASSERT(ArithProfile::observedBinaryIntInt().rhsObservedType().isOnlyInt32());166 ASSERT(arithProfile.bits() == BinaryArithProfile::observedIntIntBits()); 167 ASSERT(arithProfile.lhsObservedType().isOnlyInt32()); 168 ASSERT(arithProfile.rhsObservedType().isOnlyInt32()); 156 169 } 157 170 { 158 ArithProfile arithProfile;171 BinaryArithProfile arithProfile; 159 172 arithProfile.lhsSawNumber(); 160 173 arithProfile.rhsSawInt32(); 161 ASSERT(arithProfile.bits() == ArithProfile::observedBinaryNumberInt().bits());162 STATIC_ASSERT(ArithProfile::observedBinaryNumberInt().lhsObservedType().isOnlyNumber());163 STATIC_ASSERT(ArithProfile::observedBinaryNumberInt().rhsObservedType().isOnlyInt32());174 ASSERT(arithProfile.bits() == BinaryArithProfile::observedNumberIntBits()); 175 ASSERT(arithProfile.lhsObservedType().isOnlyNumber()); 176 ASSERT(arithProfile.rhsObservedType().isOnlyInt32()); 164 177 } 165 178 { 166 ArithProfile arithProfile;179 BinaryArithProfile arithProfile; 167 180 arithProfile.lhsSawNumber(); 168 181 arithProfile.rhsSawNumber(); 169 ASSERT(arithProfile.bits() == ArithProfile::observedBinaryNumberNumber().bits());170 STATIC_ASSERT(ArithProfile::observedBinaryNumberNumber().lhsObservedType().isOnlyNumber());171 STATIC_ASSERT(ArithProfile::observedBinaryNumberNumber().rhsObservedType().isOnlyNumber());182 ASSERT(arithProfile.bits() == BinaryArithProfile::observedNumberNumberBits()); 183 ASSERT(arithProfile.lhsObservedType().isOnlyNumber()); 184 ASSERT(arithProfile.rhsObservedType().isOnlyNumber()); 172 185 } 173 186 { 174 ArithProfile arithProfile;187 BinaryArithProfile arithProfile; 175 188 arithProfile.lhsSawInt32(); 176 189 arithProfile.rhsSawNumber(); 177 ASSERT(arithProfile.bits() == ArithProfile::observedBinaryIntNumber().bits());178 STATIC_ASSERT(ArithProfile::observedBinaryIntNumber().lhsObservedType().isOnlyInt32());179 STATIC_ASSERT(ArithProfile::observedBinaryIntNumber().rhsObservedType().isOnlyNumber());190 ASSERT(arithProfile.bits() == BinaryArithProfile::observedIntNumberBits()); 191 ASSERT(arithProfile.lhsObservedType().isOnlyInt32()); 192 ASSERT(arithProfile.rhsObservedType().isOnlyNumber()); 180 193 } 181 194 } -
trunk/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
r252273 r252422 92 92 const int64_t* LLIntOffsetsExtractor::dummy() 93 93 { 94 // This is a file generated by offlineasm/generate_offset s_extractor.rb, and contains code94 // This is a file generated by offlineasm/generate_offset_extractor.rb, and contains code 95 95 // to create a table of offsets, sizes, and a header identifying what combination of 96 96 // Platform.h macros we have set. We include it inside of a method on LLIntOffsetsExtractor -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r252302 r252422 242 242 const ShadowChickenTailMarker = constexpr ShadowChicken::Packet::tailMarkerValue 243 243 244 # ArithProfile data 245 const ArithProfileInt = constexpr (ArithProfile::observedUnaryInt().bits()) 246 const ArithProfileNumber = constexpr (ArithProfile::observedUnaryNumber().bits()) 247 const ArithProfileIntInt = constexpr (ArithProfile::observedBinaryIntInt().bits()) 248 const ArithProfileNumberInt = constexpr (ArithProfile::observedBinaryNumberInt().bits()) 249 const ArithProfileIntNumber = constexpr (ArithProfile::observedBinaryIntNumber().bits()) 250 const ArithProfileNumberNumber = constexpr (ArithProfile::observedBinaryNumberNumber().bits()) 244 # UnaryArithProfile data 245 const ArithProfileInt = constexpr (UnaryArithProfile::observedIntBits()) 246 const ArithProfileNumber = constexpr (UnaryArithProfile::observedNumberBits()) 247 248 # BinaryArithProfile data 249 const ArithProfileIntInt = constexpr (BinaryArithProfile::observedIntIntBits()) 250 const ArithProfileNumberInt = constexpr (BinaryArithProfile::observedNumberIntBits()) 251 const ArithProfileIntNumber = constexpr (BinaryArithProfile::observedIntNumberBits()) 252 const ArithProfileNumberNumber = constexpr (BinaryArithProfile::observedNumberNumberBits()) 251 253 252 254 # Pointer Tags -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
r252273 r252422 1001 1001 llintOpWithMetadata(op_negate, OpNegate, macro (size, get, dispatch, metadata, return) 1002 1002 1003 macro arithProfile(type)1004 or i type, OpNegate::Metadata::m_arithProfile +ArithProfile::m_bits[t5]1003 macro updateArithProfile(type) 1004 orh type, OpNegate::Metadata::m_arithProfile + UnaryArithProfile::m_bits[t5] 1005 1005 end 1006 1006 … … 1011 1011 btiz t2, 0x7fffffff, .opNegateSlow 1012 1012 negi t2 1013 arithProfile(ArithProfileInt)1013 updateArithProfile(ArithProfileInt) 1014 1014 return (Int32Tag, t2) 1015 1015 .opNegateSrcNotInt: 1016 1016 bia t1, LowestTag, .opNegateSlow 1017 1017 xori 0x80000000, t1 1018 arithProfile(ArithProfileNumber)1018 updateArithProfile(ArithProfileNumber) 1019 1019 return(t1, t2) 1020 1020 … … 1028 1028 llintOpWithMetadata(op_%opcodeName%, opcodeStruct, macro (size, get, dispatch, metadata, return) 1029 1029 macro arithProfile(type) 1030 or i type, %opcodeStruct%::Metadata::m_arithProfile +ArithProfile::m_bits[t5]1030 orh type, %opcodeStruct%::Metadata::m_arithProfile + BinaryArithProfile::m_bits[t5] 1031 1031 end 1032 1032 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r252273 r252422 982 982 983 983 llintOpWithMetadata(op_negate, OpNegate, macro (size, get, dispatch, metadata, return) 984 985 macro updateArithProfile(type) 986 orh type, OpNegate::Metadata::m_arithProfile + UnaryArithProfile::m_bits[t1] 987 end 988 984 989 get(m_operand, t0) 985 990 loadConstantOrVariable(size, t0, t3) 986 991 metadata(t1, t2) 987 loadi OpNegate::Metadata::m_arithProfile + ArithProfile::m_bits[t1], t2988 992 bqb t3, numberTag, .opNegateNotInt 989 993 btiz t3, 0x7fffffff, .opNegateSlow 990 994 negi t3 991 995 orq numberTag, t3 992 ori ArithProfileInt, t2 993 storei t2, OpNegate::Metadata::m_arithProfile + ArithProfile::m_bits[t1] 996 updateArithProfile(ArithProfileInt) 994 997 return(t3) 995 998 .opNegateNotInt: 996 999 btqz t3, numberTag, .opNegateSlow 997 1000 xorq 0x8000000000000000, t3 998 ori ArithProfileNumber, t2 999 storei t2, OpNegate::Metadata::m_arithProfile + ArithProfile::m_bits[t1] 1001 updateArithProfile(ArithProfileNumber) 1000 1002 return(t3) 1001 1003 … … 1011 1013 1012 1014 macro profile(type) 1013 or i type, %opcodeStruct%::Metadata::m_arithProfile +ArithProfile::m_bits[t5]1015 orh type, %opcodeStruct%::Metadata::m_arithProfile + UnaryArithProfile::m_bits[t5] 1014 1016 end 1015 1017 -
trunk/Source/JavaScriptCore/offlineasm/arm.rb
r252273 r252422 300 300 } 301 301 result = riscLowerMalformedAddressesDouble(result) 302 result = riscLowerMisplacedImmediates(result, ["storeb", "store i", "storep", "storeq"])302 result = riscLowerMisplacedImmediates(result, ["storeb", "storeh", "storei", "storep", "storeq"]) 303 303 result = riscLowerMalformedImmediates(result, 0..0xff, 0..0x0ff) 304 304 result = riscLowerMisplacedAddresses(result) … … 419 419 when "andi", "andp" 420 420 emitArmCompact("ands", "and", operands) 421 when "ori", "orp" 421 when "ori", "orp", "orh" 422 422 emitArmCompact("orrs", "orr", operands) 423 423 when "oris" -
trunk/Source/JavaScriptCore/offlineasm/arm64.rb
r252273 r252422 394 394 when "loadb", "loadbsi", "loadbsq", "storeb", /^bb/, /^btb/, /^cb/, /^tb/ 395 395 size = 1 396 when "loadh", "loadhsi", "loadhsq", " storeh"396 when "loadh", "loadhsi", "loadhsq", "orh", "storeh" 397 397 size = 2 398 398 when "loadi", "loadis", "storei", "addi", "andi", "lshifti", "muli", "negi", … … 419 419 } 420 420 421 result = riscLowerMisplacedImmediates(result, ["storeb", "store i", "storep", "storeq"])421 result = riscLowerMisplacedImmediates(result, ["storeb", "storeh", "storei", "storep", "storeq"]) 422 422 423 423 # The rules for which immediates are valid for and/or/xor instructions are fairly involved, see https://dinfuehr.github.io/blog/encoding-of-immediate-values-on-aarch64/ … … 712 712 when "orq" 713 713 emitARM64TAC("orr", operands, :quad) 714 when "orh" 715 emitARM64TAC("orr", operands, :word) # not :half because 16-bit registers don't exist on ARM. 714 716 when "xori" 715 717 emitARM64TAC("eor", operands, :word) -
trunk/Source/JavaScriptCore/offlineasm/cloop.rb
r252273 r252422 161 161 case type 162 162 when :int8; "int8_t(#{valueStr})" 163 when :int16; "int16_t(#{valueStr})" 163 164 when :int32; "int32_t(#{valueStr})" 164 165 when :int64; "int64_t(#{valueStr})" … … 184 185 case type 185 186 when :int8; int8MemRef 187 when :int16; int16MemRef 186 188 when :int32; int32MemRef 187 189 when :int64; int64MemRef … … 387 389 def cloopEmitOperation(operands, type, operator) 388 390 raise unless type == :intptr || type == :uintptr || type == :int32 || type == :uint32 || \ 389 type == :int64 || type == :uint64 || type == :double 391 type == :int64 || type == :uint64 || type == :double || type == :int16 390 392 if operands.size == 3 391 393 op1 = operands[0] … … 401 403 if dst.is_a? RegisterID and (type == :int32 or type == :uint32) 402 404 truncationHeader = "(uint32_t)(" 405 truncationFooter = ")" 406 elsif dst.is_a? RegisterID and (type == :int16) 407 truncationHeader = "(uint16_t)(" 403 408 truncationFooter = ")" 404 409 else … … 586 591 when "orp" 587 592 cloopEmitOperation(operands, :intptr, "|") 593 when "orh" 594 cloopEmitOperation(operands, :int16, "|") 588 595 589 596 when "xori" -
trunk/Source/JavaScriptCore/offlineasm/instructions.rb
r252273 r252422 47 47 "orf", 48 48 "ord", 49 "orh", 49 50 "rshifti", 50 51 "urshifti", -
trunk/Source/JavaScriptCore/offlineasm/mips.rb
r252273 r252422 528 528 when /^(addi|subi)/ 529 529 newList << node.riscLowerMalformedImmediatesRecurse(newList, -0x7fff..0x7fff) 530 when "andi", "andp", "ori", "orp", " xori", "xorp"530 when "andi", "andp", "ori", "orp", "orh", "xori", "xorp" 531 531 newList << node.riscLowerMalformedImmediatesRecurse(newList, 0..0xffff) 532 532 else … … 861 861 when "andi", "andp" 862 862 emitMIPSCompact("and", "and", operands) 863 when "ori", "orp" 863 when "ori", "orp", "orh" 864 864 emitMIPSCompact("or", "orr", operands) 865 865 when "oris" -
trunk/Source/JavaScriptCore/offlineasm/risc.rb
r252273 r252422 463 463 annotation = node.annotation 464 464 case node.opcode 465 when "addi", "addis", "andi", "lshifti", "muli", "negi", "noti", "ori", "or is",465 when "addi", "addis", "andi", "lshifti", "muli", "negi", "noti", "ori", "orh", "oris", 466 466 "rshifti", "urshifti", "subi", "subis", "xori", /^bi/, /^bti/, /^ci/, /^ti/ 467 467 newList << Instruction.new(node.codeOrigin, -
trunk/Source/JavaScriptCore/offlineasm/x86.rb
r252273 r252422 1124 1124 when "ord" 1125 1125 handleX86Op("orpd", :double) 1126 when "orh" 1127 handleX86Op("or#{x86Suffix(:half)}", :half) 1126 1128 when "rshifti" 1127 1129 handleX86Shift("sar#{x86Suffix(:int)}", :int) -
trunk/Source/JavaScriptCore/parser/ResultType.h
r252273 r252422 49 49 static_assert((TypeBits & ((1 << numBitsNeeded) - 1)) == TypeBits, "This is necessary for correctness."); 50 50 51 constexpr explicit ResultType() 52 : ResultType(unknownType()) 53 { 54 } 51 55 constexpr explicit ResultType(Type type) 52 56 : m_bits(type) -
trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
r252273 r252422 478 478 static void updateArithProfileForUnaryArithOp(OpNegate::Metadata& metadata, JSValue result, JSValue operand) 479 479 { 480 ArithProfile& profile = metadata.m_arithProfile;481 profile.observe LHS(operand);480 UnaryArithProfile& profile = metadata.m_arithProfile; 481 profile.observeArg(operand); 482 482 ASSERT(result.isNumber() || result.isBigInt()); 483 483 if (result.isNumber()) { … … 536 536 static void updateArithProfileForBinaryArithOp(JSGlobalObject*, CodeBlock* codeBlock, const Instruction* pc, JSValue result, JSValue left, JSValue right) 537 537 { 538 ArithProfile& profile = *codeBlock->arithProfileForPC(pc);538 BinaryArithProfile& profile = *codeBlock->binaryArithProfileForPC(pc); 539 539 540 540 if (result.isNumber()) { … … 597 597 JSValue v2 = GET_C(bytecode.m_rhs).jsValue(); 598 598 599 ArithProfile& arithProfile = *codeBlock->arithProfileForPC(pc);599 BinaryArithProfile& arithProfile = *codeBlock->binaryArithProfileForPC(pc); 600 600 arithProfile.observeLHSAndRHS(v1, v2); 601 601
Note: See TracChangeset
for help on using the changeset viewer.