Source/JavaScriptCore/ChangeLog

 12013-12-11 Filip Pizlo <fpizlo@apple.com>
 2
 3 Get rid of forward exit on UInt32ToNumber by adding an op_unsigned bytecode instruction
 4 https://bugs.webkit.org/show_bug.cgi?id=125553
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 UInt32ToNumber was a super complicated node because it had to do a speculation, but it
 9 would do it after we already had computed the urshift. It couldn't just back to the
 10 beginning of the urshift because the inputs to the urshift weren't necessarily live
 11 anymore. We couldn't jump forward to the beginning of the next instruction because the
 12 result of the urshift was not yet unsigned-converted.
 13
 14 For a while we solved this by forward-exiting in UInt32ToNumber. But that's really
 15 gross and I want to get rid of all forward exits. They cause a lot of bugs.
 16
 17 We could also have turned UInt32ToNumber to a backwards exit by forcing the inputs to
 18 the urshift to be live. I figure that this might be a bit too extreme.
 19
 20 So, I just created a new place that we can exit to: I split op_urshift into op_urshift
 21 followed by op_unsigned. op_unsigned is an "unsigned cast" along the lines of what
 22 UInt32ToNumber does. This allows me to get rid of all of the nastyness in the DFG for
 23 forward exiting in UInt32ToNumber.
 24
 25 This patch enables massive code carnage in the DFG and FTL, and brings us closer to
 26 eliminating one of the DFG's most confusing concepts. On the flipside, it does make the
 27 bytecode slightly more complex (one new instruction). This is a profitable trade. We
 28 want the DFG and FTL to trend towards simplicity, since they are both currently too
 29 complicated.
 30
 31 * bytecode/BytecodeUseDef.h:
 32 (JSC::computeUsesForBytecodeOffset):
 33 (JSC::computeDefsForBytecodeOffset):
 34 * bytecode/CodeBlock.cpp:
 35 (JSC::CodeBlock::dumpBytecode):
 36 * bytecode/Opcode.h:
 37 (JSC::padOpcodeName):
 38 * bytecode/ValueRecovery.cpp:
 39 (JSC::ValueRecovery::dumpInContext):
 40 * bytecode/ValueRecovery.h:
 41 (JSC::ValueRecovery::gpr):
 42 * bytecompiler/NodesCodegen.cpp:
 43 (JSC::BinaryOpNode::emitBytecode):
 44 (JSC::emitReadModifyAssignment):
 45 * dfg/DFGByteCodeParser.cpp:
 46 (JSC::DFG::ByteCodeParser::toInt32):
 47 (JSC::DFG::ByteCodeParser::parseBlock):
 48 * dfg/DFGClobberize.h:
 49 (JSC::DFG::clobberize):
 50 * dfg/DFGNodeType.h:
 51 * dfg/DFGOSRExitCompiler32_64.cpp:
 52 (JSC::DFG::OSRExitCompiler::compileExit):
 53 * dfg/DFGOSRExitCompiler64.cpp:
 54 (JSC::DFG::OSRExitCompiler::compileExit):
 55 * dfg/DFGSpeculativeJIT.cpp:
 56 (JSC::DFG::SpeculativeJIT::compileMovHint):
 57 (JSC::DFG::SpeculativeJIT::compileUInt32ToNumber):
 58 * dfg/DFGSpeculativeJIT.h:
 59 * dfg/DFGSpeculativeJIT32_64.cpp:
 60 * dfg/DFGSpeculativeJIT64.cpp:
 61 * dfg/DFGStrengthReductionPhase.cpp:
 62 (JSC::DFG::StrengthReductionPhase::handleNode):
 63 (JSC::DFG::StrengthReductionPhase::convertToIdentityOverChild):
 64 (JSC::DFG::StrengthReductionPhase::convertToIdentityOverChild1):
 65 (JSC::DFG::StrengthReductionPhase::convertToIdentityOverChild2):
 66 * ftl/FTLFormattedValue.h:
 67 (JSC::FTL::int32Value):
 68 * ftl/FTLLowerDFGToLLVM.cpp:
 69 (JSC::FTL::LowerDFGToLLVM::compileUInt32ToNumber):
 70 * ftl/FTLValueFormat.cpp:
 71 (JSC::FTL::reboxAccordingToFormat):
 72 (WTF::printInternal):
 73 * ftl/FTLValueFormat.h:
 74 * jit/JIT.cpp:
 75 (JSC::JIT::privateCompileMainPass):
 76 (JSC::JIT::privateCompileSlowCases):
 77 * jit/JIT.h:
 78 * jit/JITArithmetic.cpp:
 79 (JSC::JIT::emit_op_urshift):
 80 (JSC::JIT::emitSlow_op_urshift):
 81 (JSC::JIT::emit_op_unsigned):
 82 (JSC::JIT::emitSlow_op_unsigned):
 83 * jit/JITArithmetic32_64.cpp:
 84 (JSC::JIT::emitRightShift):
 85 (JSC::JIT::emitRightShiftSlowCase):
 86 (JSC::JIT::emit_op_unsigned):
 87 (JSC::JIT::emitSlow_op_unsigned):
 88 * llint/LowLevelInterpreter32_64.asm:
 89 * llint/LowLevelInterpreter64.asm:
 90 * runtime/CommonSlowPaths.cpp:
 91 (JSC::SLOW_PATH_DECL):
 92 * runtime/CommonSlowPaths.h:
 93
1942013-12-11 Joseph Pecoraro <pecoraro@apple.com>
295
396 Web Inspector: Push More Inspector Required Classes Down into JavaScriptCore
160476

Source/JavaScriptCore/bytecode/BytecodeUseDef.h

@@void computeUsesForBytecodeOffset(
156156 case op_new_array_with_size:
157157 case op_create_this:
158158 case op_get_pnames:
159  case op_del_by_id: {
 159 case op_del_by_id:
 160 case op_unsigned: {
160161 functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
161162 return;
162163 }

@@void computeDefsForBytecodeOffset(CodeBl
390391 case op_create_activation:
391392 case op_create_arguments:
392393 case op_del_by_id:
393  case op_del_by_val: {
 394 case op_del_by_val:
 395 case op_unsigned: {
394396 functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
395397 return;
396398 }
160441

Source/JavaScriptCore/bytecode/CodeBlock.cpp

@@void CodeBlock::dumpBytecode(PrintStream
901901 out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data());
902902 break;
903903 }
 904 case op_unsigned: {
 905 printUnaryOp(out, exec, location, it, "unsigned");
 906 break;
 907 }
904908 case op_typeof: {
905909 printUnaryOp(out, exec, location, it, "typeof");
906910 break;
160441

Source/JavaScriptCore/bytecode/Opcode.h

@@namespace JSC {
8282 macro(op_lshift, 4) \
8383 macro(op_rshift, 4) \
8484 macro(op_urshift, 4) \
 85 macro(op_unsigned, 3) \
8586 macro(op_bitand, 5) \
8687 macro(op_bitxor, 5) \
8788 macro(op_bitor, 5) \
160441

Source/JavaScriptCore/bytecode/ValueRecovery.cpp

@@void ValueRecovery::dumpInContext(PrintS
8383 case UnboxedCellInGPR:
8484 out.print("cell(", gpr(), ")");
8585 return;
86  case UInt32InGPR:
87  out.print("uint32(", gpr(), ")");
88  return;
8986 case InFPR:
9087 out.print(fpr());
9188 return;
160441

Source/JavaScriptCore/bytecode/ValueRecovery.h

@@enum ValueRecoveryTechnique {
5454 InPair,
5555#endif
5656 InFPR,
57  UInt32InGPR,
5857 // It's in the stack, but at a different location.
5958 DisplacedInJSStack,
6059 // It's in the stack, at a different location, and it's unboxed.

@@public:
105104 return result;
106105 }
107106
108  static ValueRecovery uint32InGPR(MacroAssembler::RegisterID gpr)
109  {
110  ValueRecovery result;
111  result.m_technique = UInt32InGPR;
112  result.m_source.gpr = gpr;
113  return result;
114  }
115 
116107#if USE(JSVALUE32_64)
117108 static ValueRecovery inPair(MacroAssembler::RegisterID tagGPR, MacroAssembler::RegisterID payloadGPR)
118109 {

@@public:
209200
210201 MacroAssembler::RegisterID gpr() const
211202 {
212  ASSERT(m_technique == InGPR || m_technique == UnboxedInt32InGPR || m_technique == UnboxedBooleanInGPR || m_technique == UInt32InGPR || m_technique == UnboxedInt52InGPR || m_technique == UnboxedStrictInt52InGPR || m_technique == UnboxedCellInGPR);
 203 ASSERT(m_technique == InGPR || m_technique == UnboxedInt32InGPR || m_technique == UnboxedBooleanInGPR || m_technique == UnboxedInt52InGPR || m_technique == UnboxedStrictInt52InGPR || m_technique == UnboxedCellInGPR);
213204 return m_source.gpr;
214205 }
215206
160441

Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

@@RegisterID* BinaryOpNode::emitBytecode(B
11681168 RELEASE_ASSERT_NOT_REACHED();
11691169 return generator.emitUnaryOp(op_not, generator.finalDestination(dst, tmp.get()), tmp.get());
11701170 }
1171  return generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(left->resultDescriptor(), right->resultDescriptor()));
 1171 RegisterID* result = generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(left->resultDescriptor(), right->resultDescriptor()));
 1172 if (opcodeID == op_urshift && dst != generator.ignoredResult())
 1173 return generator.emitUnaryOp(op_unsigned, result, result);
 1174 return result;
11721175}
11731176
11741177RegisterID* EqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)

@@static ALWAYS_INLINE RegisterID* emitRea
13351338 // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
13361339 if (emitExpressionInfoForMe)
13371340 generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->divotStart(), emitExpressionInfoForMe->divotEnd());
1338  return generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
 1341 RegisterID* result = generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
 1342 if (oper == OpURShift)
 1343 return generator.emitUnaryOp(op_unsigned, result, result);
 1344 return result;
13391345}
13401346
13411347RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
160441

Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

@@private:
513513 if (node->hasInt32Result())
514514 return node;
515515
516  if (node->op() == UInt32ToNumber)
517  return node->child1().node();
518 
519516 // Check for numeric constants boxed as JSValues.
520517 if (canFold(node)) {
521518 JSValue v = valueOfJSConstant(node);

@@bool ByteCodeParser::parseBlock(unsigned
20502047 case op_rshift: {
20512048 Node* op1 = getToInt32(currentInstruction[2].u.operand);
20522049 Node* op2 = getToInt32(currentInstruction[3].u.operand);
2053  Node* result;
2054  // Optimize out shifts by zero.
2055  if (isInt32Constant(op2) && !(valueOfInt32Constant(op2) & 0x1f))
2056  result = op1;
2057  else
2058  result = addToGraph(BitRShift, op1, op2);
2059  set(VirtualRegister(currentInstruction[1].u.operand), result);
 2050 set(VirtualRegister(currentInstruction[1].u.operand),
 2051 addToGraph(BitRShift, op1, op2));
20602052 NEXT_OPCODE(op_rshift);
20612053 }
20622054
20632055 case op_lshift: {
20642056 Node* op1 = getToInt32(currentInstruction[2].u.operand);
20652057 Node* op2 = getToInt32(currentInstruction[3].u.operand);
2066  Node* result;
2067  // Optimize out shifts by zero.
2068  if (isInt32Constant(op2) && !(valueOfInt32Constant(op2) & 0x1f))
2069  result = op1;
2070  else
2071  result = addToGraph(BitLShift, op1, op2);
2072  set(VirtualRegister(currentInstruction[1].u.operand), result);
 2058 set(VirtualRegister(currentInstruction[1].u.operand),
 2059 addToGraph(BitLShift, op1, op2));
20732060 NEXT_OPCODE(op_lshift);
20742061 }
20752062
20762063 case op_urshift: {
20772064 Node* op1 = getToInt32(currentInstruction[2].u.operand);
20782065 Node* op2 = getToInt32(currentInstruction[3].u.operand);
2079  Node* result;
2080  // The result of a zero-extending right shift is treated as an unsigned value.
2081  // This means that if the top bit is set, the result is not in the int32 range,
2082  // and as such must be stored as a double. If the shift amount is a constant,
2083  // we may be able to optimize.
2084  if (isInt32Constant(op2)) {
2085  // If we know we are shifting by a non-zero amount, then since the operation
2086  // zero fills we know the top bit of the result must be zero, and as such the
2087  // result must be within the int32 range. Conversely, if this is a shift by
2088  // zero, then the result may be changed by the conversion to unsigned, but it
2089  // is not necessary to perform the shift!
2090  if (valueOfInt32Constant(op2) & 0x1f)
2091  result = addToGraph(BitURShift, op1, op2);
2092  else
2093  result = makeSafe(addToGraph(UInt32ToNumber, op1));
2094  } else {
2095  // Cannot optimize at this stage; shift & potentially rebox as a double.
2096  result = addToGraph(BitURShift, op1, op2);
2097  result = makeSafe(addToGraph(UInt32ToNumber, result));
2098  }
2099  set(VirtualRegister(currentInstruction[1].u.operand), result);
 2066 set(VirtualRegister(currentInstruction[1].u.operand),
 2067 addToGraph(BitURShift, op1, op2));
21002068 NEXT_OPCODE(op_urshift);
21012069 }
 2070
 2071 case op_unsigned: {
 2072 set(VirtualRegister(currentInstruction[1].u.operand),
 2073 makeSafe(addToGraph(UInt32ToNumber, getToInt32(currentInstruction[2].u.operand))));
 2074 NEXT_OPCODE(op_unsigned);
 2075 }
21022076
21032077 // === Increment/Decrement opcodes ===
21042078
160441

Source/JavaScriptCore/dfg/DFGClobberize.h

@@void clobberize(Graph& graph, Node* node
118118 case Int52ToValue:
119119 case CheckInBounds:
120120 case ConstantStoragePointer:
 121 case UInt32ToNumber:
 122 case DoubleAsInt32:
121123 return;
122124
123125 case MovHintAndCheck:

@@void clobberize(Graph& graph, Node* node
168170 read(Watchpoint_fire);
169171 return;
170172
171  // These are forward-exiting nodes that assume that the subsequent instruction
172  // is a MovHint, and they try to roll forward over this MovHint in their
173  // execution. This makes hoisting them impossible without additional magic. We
174  // may add such magic eventually, but just not yet.
175  case UInt32ToNumber:
176  case DoubleAsInt32:
177  write(SideState);
178  return;
179 
180173 case ToThis:
181174 case CreateThis:
182175 read(MiscFields);
160441

Source/JavaScriptCore/dfg/DFGNodeType.h

@@namespace JSC { namespace DFG {
105105 /* Bitwise operators call ToInt32 on their operands. */\
106106 macro(ValueToInt32, NodeResultInt32) \
107107 /* Used to box the result of URShift nodes (result has range 0..2^32-1). */\
108  macro(UInt32ToNumber, NodeResultNumber | NodeExitsForward) \
 108 macro(UInt32ToNumber, NodeResultNumber) \
109109 \
110110 /* Used to cast known integers to doubles, so as to separate the double form */\
111111 /* of the value from the integer form. */\
160441

Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp

@@void OSRExitCompiler::compileExit(const
177177
178178 switch (recovery.technique()) {
179179 case UnboxedInt32InGPR:
180  case UInt32InGPR:
181180 case UnboxedBooleanInGPR:
182181 case UnboxedCellInGPR:
183182 m_jit.store32(

@@void OSRExitCompiler::compileExit(const
317316 AssemblyHelpers::payloadFor(operand));
318317 break;
319318
320  case UInt32InGPR: {
321  m_jit.load32(
322  &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload,
323  GPRInfo::regT0);
324  AssemblyHelpers::Jump positive = m_jit.branch32(
325  AssemblyHelpers::GreaterThanOrEqual,
326  GPRInfo::regT0, AssemblyHelpers::TrustedImm32(0));
327  m_jit.convertInt32ToDouble(GPRInfo::regT0, FPRInfo::fpRegT0);
328  m_jit.addDouble(
329  AssemblyHelpers::AbsoluteAddress(&AssemblyHelpers::twoToThe32),
330  FPRInfo::fpRegT0);
331  m_jit.storeDouble(FPRInfo::fpRegT0, AssemblyHelpers::addressFor(operand));
332  AssemblyHelpers::Jump done = m_jit.jump();
333  positive.link(&m_jit);
334  m_jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
335  m_jit.store32(
336  AssemblyHelpers::TrustedImm32(JSValue::Int32Tag),
337  AssemblyHelpers::tagFor(operand));
338  done.link(&m_jit);
339  break;
340  }
341 
342319 case Constant:
343320 m_jit.store32(
344321 AssemblyHelpers::TrustedImm32(recovery.constant().tag()),
160441

Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp

@@void OSRExitCompiler::compileExit(const
185185 switch (recovery.technique()) {
186186 case InGPR:
187187 case UnboxedInt32InGPR:
188  case UInt32InGPR:
189188 case UnboxedInt52InGPR:
190189 case UnboxedStrictInt52InGPR:
191190 case UnboxedCellInGPR:

@@void OSRExitCompiler::compileExit(const
283282 m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
284283 break;
285284
286  case UInt32InGPR:
287  m_jit.load64(scratch + index, GPRInfo::regT0);
288  m_jit.zeroExtend32ToPtr(GPRInfo::regT0, GPRInfo::regT0);
289  m_jit.boxInt52(GPRInfo::regT0, GPRInfo::regT0, GPRInfo::regT1, FPRInfo::fpRegT0);
290  m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
291  break;
292 
293285 case InFPR:
294286 case DoubleDisplacedInJSStack:
295287 m_jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);
160441

Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

@@bool SpeculativeJIT::fillJSValue(Edge ed
168168 }
169169}
170170
171 void SpeculativeJIT::nonSpeculativeUInt32ToNumber(Node* node)
172 {
173  SpeculateInt32Operand op1(this, node->child1());
174  FPRTemporary boxer(this);
175  GPRTemporary resultTag(this, Reuse, op1);
176  GPRTemporary resultPayload(this);
177 
178  JITCompiler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, op1.gpr(), TrustedImm32(0));
179 
180  m_jit.convertInt32ToDouble(op1.gpr(), boxer.fpr());
181  m_jit.move(JITCompiler::TrustedImmPtr(&AssemblyHelpers::twoToThe32), resultPayload.gpr()); // reuse resultPayload register here.
182  m_jit.addDouble(JITCompiler::Address(resultPayload.gpr(), 0), boxer.fpr());
183 
184  boxDouble(boxer.fpr(), resultTag.gpr(), resultPayload.gpr());
185 
186  JITCompiler::Jump done = m_jit.jump();
187 
188  positive.link(&m_jit);
189 
190  m_jit.move(TrustedImm32(JSValue::Int32Tag), resultTag.gpr());
191  m_jit.move(op1.gpr(), resultPayload.gpr());
192 
193  done.link(&m_jit);
194 
195  jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
196 }
197 
198171void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode)
199172{
200173 JITGetByIdGenerator gen(
160441

Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

@@GPRReg SpeculativeJIT::fillJSValue(Edge
186186 }
187187}
188188
189 void SpeculativeJIT::nonSpeculativeUInt32ToNumber(Node* node)
190 {
191  SpeculateInt32Operand op1(this, node->child1());
192  FPRTemporary boxer(this);
193  GPRTemporary result(this, Reuse, op1);
194 
195  JITCompiler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, op1.gpr(), TrustedImm32(0));
196 
197  m_jit.convertInt32ToDouble(op1.gpr(), boxer.fpr());
198  m_jit.addDouble(JITCompiler::AbsoluteAddress(&AssemblyHelpers::twoToThe32), boxer.fpr());
199 
200  boxDouble(boxer.fpr(), result.gpr());
201 
202  JITCompiler::Jump done = m_jit.jump();
203 
204  positive.link(&m_jit);
205 
206  m_jit.or64(GPRInfo::tagTypeNumberRegister, op1.gpr(), result.gpr());
207 
208  done.link(&m_jit);
209 
210  jsValueResult(result.gpr(), m_currentNode);
211 }
212 
213189void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode)
214190{
215191 JITGetByIdGenerator gen(
160441

Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

@@void SpeculativeJIT::compileMovHint(Node
14241424 Node* child = node->child1().node();
14251425 noticeOSRBirth(child);
14261426
1427  if (child->op() == UInt32ToNumber)
1428  noticeOSRBirth(child->child1().node());
1429 
14301427 m_stream->appendAndLog(VariableEvent::movHint(MinifiedID(child), node->local()));
14311428}
14321429

@@void SpeculativeJIT::compileUInt32ToNumb
21612158 }
21622159
21632160 SpeculateInt32Operand op1(this, node->child1());
2164  GPRTemporary result(this); // For the benefit of OSR exit, force these to be in different registers. In reality the OSR exit compiler could find cases where you have uint32(%r1) followed by int32(%r1) and then use different registers, but that seems like too much effort.
 2161 GPRTemporary result(this);
21652162
21662163 m_jit.move(op1.gpr(), result.gpr());
21672164
2168  // Test the operand is positive. This is a very special speculation check - we actually
2169  // use roll-forward speculation here, where if this fails, we jump to the baseline
2170  // instruction that follows us, rather than the one we're executing right now. We have
2171  // to do this because by this point, the original values necessary to compile whatever
2172  // operation the UInt32ToNumber originated from might be dead.
2173  forwardSpeculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, result.gpr(), TrustedImm32(0)), ValueRecovery::uint32InGPR(result.gpr()));
 2165 speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, result.gpr(), TrustedImm32(0)));
21742166
21752167 int32Result(result.gpr(), node, op1.format());
21762168}
160441

Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

@@public:
698698 void compileMovHint(Node*);
699699 void compileMovHintAndCheck(Node*);
700700
701  void nonSpeculativeUInt32ToNumber(Node*);
702 
703701#if USE(JSVALUE64)
704702 void cachedGetById(CodeOrigin, GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
705703 void cachedPutById(CodeOrigin, GPRReg base, GPRReg value, Edge valueUse, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
160441

Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp

@@private:
7070 {
7171 switch (m_node->op()) {
7272 case BitOr:
73  // Optimize X|0 -> X.
 73 if (m_node->child1()->isConstant()) {
 74 JSValue op1 = m_graph.valueOfJSConstant(m_node->child1().node());
 75 if (op1.isInt32() && !op1.asInt32()) {
 76 convertToIdentityOverChild2();
 77 break;
 78 }
 79 }
7480 if (m_node->child2()->isConstant()) {
75  JSValue C2 = m_graph.valueOfJSConstant(m_node->child2().node());
76  if (C2.isInt32() && !C2.asInt32()) {
77  m_insertionSet.insertNode(
78  m_nodeIndex, SpecNone, Phantom, m_node->codeOrigin,
79  m_node->child2());
80  m_node->children.removeEdge(1);
 81 JSValue op2 = m_graph.valueOfJSConstant(m_node->child2().node());
 82 if (op2.isInt32() && !op2.asInt32()) {
 83 convertToIdentityOverChild1();
 84 break;
 85 }
 86 }
 87 break;
 88
 89 case BitLShift:
 90 case BitRShift:
 91 case BitURShift:
 92 if (m_node->child2()->isConstant()) {
 93 JSValue op2 = m_graph.valueOfJSConstant(m_node->child2().node());
 94 if (op2.isInt32() && !(op2.asInt32() & 0x1f)) {
 95 convertToIdentityOverChild1();
 96 break;
 97 }
 98 }
 99 break;
 100
 101 case UInt32ToNumber:
 102 if (m_node->child1()->op() == BitURShift
 103 && m_node->child1()->child2()->isConstant()) {
 104 JSValue shiftAmount = m_graph.valueOfJSConstant(
 105 m_node->child1()->child2().node());
 106 if (shiftAmount.isInt32() && (shiftAmount.asInt32() & 0x1f)) {
81107 m_node->convertToIdentity();
82108 m_changed = true;
83109 break;

@@private:
116142 break;
117143 }
118144 }
 145
 146 void convertToIdentityOverChild(unsigned childIndex)
 147 {
 148 m_insertionSet.insertNode(
 149 m_nodeIndex, SpecNone, Phantom, m_node->codeOrigin, m_node->children);
 150 m_node->children.removeEdge(childIndex ^ 1);
 151 m_node->convertToIdentity();
 152 m_changed = true;
 153 }
 154
 155 void convertToIdentityOverChild1()
 156 {
 157 convertToIdentityOverChild(0);
 158 }
 159
 160 void convertToIdentityOverChild2()
 161 {
 162 convertToIdentityOverChild(1);
 163 }
119164
120165 void foldTypedArrayPropertyToConstant(JSArrayBufferView* view, JSValue constant)
121166 {
160441

Source/JavaScriptCore/ftl/FTLFormattedValue.h

@@private:
7272
7373static inline FormattedValue noValue() { return FormattedValue(); }
7474static inline FormattedValue int32Value(LValue value) { return FormattedValue(ValueFormatInt32, value); }
75 static inline FormattedValue uInt32Value(LValue value) { return FormattedValue(ValueFormatUInt32, value); }
7675static inline FormattedValue booleanValue(LValue value) { return FormattedValue(ValueFormatBoolean, value); }
7776static inline FormattedValue jsValueValue(LValue value) { return FormattedValue(ValueFormatJSValue, value); }
7877static inline FormattedValue doubleValue(LValue value) { return FormattedValue(ValueFormatDouble, value); }
160441

Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

@@private:
11711171 return;
11721172 }
11731173
1174  speculateForward(
1175  Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero),
1176  FormattedValue(ValueFormatUInt32, value));
 1174 speculate(Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero));
11771175 setInt32(value);
11781176 }
11791177
160441

Source/JavaScriptCore/ftl/FTLValueFormat.cpp

@@void reboxAccordingToFormat(
4242 break;
4343 }
4444
45  case ValueFormatUInt32: {
46  jit.zeroExtend32ToPtr(value, value);
47  jit.moveDoubleTo64(FPRInfo::fpRegT0, scratch2);
48  jit.boxInt52(value, value, scratch1, FPRInfo::fpRegT0);
49  jit.move64ToDouble(scratch2, FPRInfo::fpRegT0);
50  break;
51  }
52 
5345 case ValueFormatInt52: {
5446 jit.rshift64(AssemblyHelpers::TrustedImm32(JSValue::int52ShiftAmount), value);
5547 jit.moveDoubleTo64(FPRInfo::fpRegT0, scratch2);

@@void printInternal(PrintStream& out, Val
10597 case ValueFormatInt32:
10698 out.print("Int32");
10799 return;
108  case ValueFormatUInt32:
109  out.print("UInt32");
110  return;
111100 case ValueFormatInt52:
112101 out.print("Int52");
113102 return;
160441

Source/JavaScriptCore/ftl/FTLValueFormat.h

@@namespace FTL {
4545enum ValueFormat {
4646 InvalidValueFormat,
4747 ValueFormatInt32,
48  ValueFormatUInt32,
4948 ValueFormatInt52,
5049 ValueFormatStrictInt52,
5150 ValueFormatBoolean,
160441

Source/JavaScriptCore/jit/JIT.cpp

@@void JIT::privateCompileMainPass()
267267 DEFINE_OP(op_ret)
268268 DEFINE_OP(op_ret_object_or_this)
269269 DEFINE_OP(op_rshift)
 270 DEFINE_OP(op_unsigned)
270271 DEFINE_OP(op_urshift)
271272 DEFINE_OP(op_strcat)
272273 DEFINE_OP(op_stricteq)

@@void JIT::privateCompileSlowCases()
412413 case op_put_by_val_direct:
413414 DEFINE_SLOWCASE_OP(op_put_by_val)
414415 DEFINE_SLOWCASE_OP(op_rshift)
 416 DEFINE_SLOWCASE_OP(op_unsigned)
415417 DEFINE_SLOWCASE_OP(op_urshift)
416418 DEFINE_SLOWCASE_OP(op_stricteq)
417419 DEFINE_SLOWCASE_OP(op_sub)
160441

Source/JavaScriptCore/jit/JIT.h

@@namespace JSC {
552552 void emit_op_to_number(Instruction*);
553553 void emit_op_to_primitive(Instruction*);
554554 void emit_op_unexpected_load(Instruction*);
 555 void emit_op_unsigned(Instruction*);
555556 void emit_op_urshift(Instruction*);
556557
557558 void emitSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&);

@@namespace JSC {
603604 void emitSlow_op_sub(Instruction*, Vector<SlowCaseEntry>::iterator&);
604605 void emitSlow_op_to_number(Instruction*, Vector<SlowCaseEntry>::iterator&);
605606 void emitSlow_op_to_primitive(Instruction*, Vector<SlowCaseEntry>::iterator&);
 607 void emitSlow_op_unsigned(Instruction*, Vector<SlowCaseEntry>::iterator&);
606608 void emitSlow_op_urshift(Instruction*, Vector<SlowCaseEntry>::iterator&);
607609
608610 void emit_op_resolve_scope(Instruction*);
160441

Source/JavaScriptCore/jit/JITArithmetic32_64.cpp

@@void JIT::emitRightShift(Instruction* cu
211211 urshift32(Imm32(shift), regT0);
212212 else
213213 rshift32(Imm32(shift), regT0);
214  } else if (isUnsigned) // signed right shift by zero is simply toInt conversion
215  addSlowCase(branch32(LessThan, regT0, TrustedImm32(0)));
 214 }
216215 emitStoreInt32(dst, regT0, dst == op1);
217216 } else {
218217 emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
219218 if (!isOperandConstantImmediateInt(op1))
220219 addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
221220 addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
222  if (isUnsigned) {
 221 if (isUnsigned)
223222 urshift32(regT2, regT0);
224  addSlowCase(branch32(LessThan, regT0, TrustedImm32(0)));
225  } else
 223 else
226224 rshift32(regT2, regT0);
227225 emitStoreInt32(dst, regT0, dst == op1);
228226 }

@@void JIT::emitRightShiftSlowCase(Instruc
247245 urshift32(Imm32(shift), regT0);
248246 else
249247 rshift32(Imm32(shift), regT0);
250  } else if (isUnsigned) // signed right shift by zero is simply toInt conversion
251  failures.append(branch32(LessThan, regT0, TrustedImm32(0)));
 248 }
252249 move(TrustedImm32(JSValue::Int32Tag), regT1);
253250 emitStoreInt32(dst, regT0, false);
254251 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift));
255252 failures.link(this);
256253 }
257  if (isUnsigned && !shift)
258  linkSlowCase(iter); // failed to box in hot path
259254 } else {
260255 // op1 = regT1:regT0
261256 // op2 = regT3:regT2

@@void JIT::emitRightShiftSlowCase(Instruc
267262 emitLoadDouble(op1, fpRegT0);
268263 failures.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); // op2 is not an int
269264 failures.append(branchTruncateDoubleToInt32(fpRegT0, regT0));
270  if (isUnsigned) {
 265 if (isUnsigned)
271266 urshift32(regT2, regT0);
272  failures.append(branch32(LessThan, regT0, TrustedImm32(0)));
273  } else
 267 else
274268 rshift32(regT2, regT0);
275269 move(TrustedImm32(JSValue::Int32Tag), regT1);
276270 emitStoreInt32(dst, regT0, false);

@@void JIT::emitRightShiftSlowCase(Instruc
280274 }
281275
282276 linkSlowCase(iter); // int32 check - op2 is not an int
283  if (isUnsigned)
284  linkSlowCase(iter); // Can't represent unsigned result as an immediate
285277 }
286278
287279 JITSlowPathCall slowPathCall(this, currentInstruction, isUnsigned ? slow_path_urshift : slow_path_rshift);

@@void JIT::emitSlow_op_urshift(Instructio
312304 emitRightShiftSlowCase(currentInstruction, iter, true);
313305}
314306
 307void JIT::emit_op_unsigned(Instruction* currentInstruction)
 308{
 309 int result = currentInstruction[1].u.operand;
 310 int op1 = currentInstruction[2].u.operand;
 311
 312 emitLoad(op1, regT1, regT0);
 313
 314 addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
 315 addSlowCase(branch32(LessThan, regT0, TrustedImm32(0)));
 316 emitStoreInt32(result, regT0, result == op1);
 317}
 318
 319void JIT::emitSlow_op_unsigned(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 320{
 321 linkSlowCase(iter);
 322 linkSlowCase(iter);
 323
 324 JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_unsigned);
 325 slowPathCall.call();
 326}
 327
315328// BitAnd (&)
316329
317330void JIT::emit_op_bitand(Instruction* currentInstruction)
160441

Source/JavaScriptCore/jit/JITArithmetic.cpp

@@void JIT::emitSlow_op_rshift(Instruction
306306
307307void JIT::emit_op_urshift(Instruction* currentInstruction)
308308{
309  int dst = currentInstruction[1].u.operand;
 309 int result = currentInstruction[1].u.operand;
310310 int op1 = currentInstruction[2].u.operand;
311311 int op2 = currentInstruction[3].u.operand;
312312
313  // Slow case of urshift makes assumptions about what registers hold the
314  // shift arguments, so any changes must be updated there as well.
315313 if (isOperandConstantImmediateInt(op2)) {
 314 // isOperandConstantImmediateInt(op2) => 1 SlowCase
316315 emitGetVirtualRegister(op1, regT0);
317316 emitJumpSlowCaseIfNotImmediateInteger(regT0);
318  emitFastArithImmToInt(regT0);
319  int shift = getConstantOperand(op2).asInt32();
320  if (shift)
321  urshift32(Imm32(shift & 0x1f), regT0);
322  // unsigned shift < 0 or shift = k*2^32 may result in (essentially)
323  // a toUint conversion, which can result in a value we can represent
324  // as an immediate int.
325  if (shift < 0 || !(shift & 31))
326  addSlowCase(branch32(LessThan, regT0, TrustedImm32(0)));
327  emitFastArithReTagImmediate(regT0, regT0);
328  emitPutVirtualRegister(dst, regT0);
329  return;
 317 // Mask with 0x1f as per ecma-262 11.7.2 step 7.
 318 urshift32(Imm32(getConstantOperandImmediateInt(op2) & 0x1f), regT0);
 319 } else {
 320 emitGetVirtualRegisters(op1, regT0, op2, regT2);
 321 if (supportsFloatingPointTruncate()) {
 322 Jump lhsIsInt = emitJumpIfImmediateInteger(regT0);
 323 // supportsFloatingPoint() && USE(JSVALUE64) => 3 SlowCases
 324 addSlowCase(emitJumpIfNotImmediateNumber(regT0));
 325 add64(tagTypeNumberRegister, regT0);
 326 move64ToDouble(regT0, fpRegT0);
 327 addSlowCase(branchTruncateDoubleToInt32(fpRegT0, regT0));
 328 lhsIsInt.link(this);
 329 emitJumpSlowCaseIfNotImmediateInteger(regT2);
 330 } else {
 331 // !supportsFloatingPoint() => 2 SlowCases
 332 emitJumpSlowCaseIfNotImmediateInteger(regT0);
 333 emitJumpSlowCaseIfNotImmediateInteger(regT2);
 334 }
 335 emitFastArithImmToInt(regT2);
 336 urshift32(regT2, regT0);
330337 }
331  emitGetVirtualRegisters(op1, regT0, op2, regT1);
332  if (!isOperandConstantImmediateInt(op1))
333  emitJumpSlowCaseIfNotImmediateInteger(regT0);
334  emitJumpSlowCaseIfNotImmediateInteger(regT1);
335  emitFastArithImmToInt(regT0);
336  emitFastArithImmToInt(regT1);
337  urshift32(regT1, regT0);
338  addSlowCase(branch32(LessThan, regT0, TrustedImm32(0)));
339  emitFastArithReTagImmediate(regT0, regT0);
340  emitPutVirtualRegister(dst, regT0);
 338 emitFastArithIntToImmNoCheck(regT0, regT0);
 339 emitPutVirtualRegister(result);
341340}
342341
343342void JIT::emitSlow_op_urshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
344343{
345  int dst = currentInstruction[1].u.operand;
346  int op1 = currentInstruction[2].u.operand;
347344 int op2 = currentInstruction[3].u.operand;
348  if (isOperandConstantImmediateInt(op2)) {
349  int shift = getConstantOperand(op2).asInt32();
350  // op1 = regT0
351  linkSlowCase(iter); // int32 check
 345
 346 if (isOperandConstantImmediateInt(op2))
 347 linkSlowCase(iter);
 348
 349 else {
352350 if (supportsFloatingPointTruncate()) {
353  JumpList failures;
354  failures.append(emitJumpIfNotImmediateNumber(regT0)); // op1 is not a double
355  add64(tagTypeNumberRegister, regT0);
356  move64ToDouble(regT0, fpRegT0);
357  failures.append(branchTruncateDoubleToInt32(fpRegT0, regT0));
358  if (shift)
359  urshift32(Imm32(shift & 0x1f), regT0);
360  if (shift < 0 || !(shift & 31))
361  failures.append(branch32(LessThan, regT0, TrustedImm32(0)));
362  emitFastArithReTagImmediate(regT0, regT0);
363  emitPutVirtualRegister(dst, regT0);
364  emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift));
365  failures.link(this);
366  }
367  if (shift < 0 || !(shift & 31))
368  linkSlowCase(iter); // failed to box in hot path
369  } else {
370  // op1 = regT0
371  // op2 = regT1
372  if (!isOperandConstantImmediateInt(op1)) {
373  linkSlowCase(iter); // int32 check -- op1 is not an int
374  if (supportsFloatingPointTruncate()) {
375  JumpList failures;
376  failures.append(emitJumpIfNotImmediateNumber(regT0)); // op1 is not a double
377  add64(tagTypeNumberRegister, regT0);
378  move64ToDouble(regT0, fpRegT0);
379  failures.append(branchTruncateDoubleToInt32(fpRegT0, regT0));
380  failures.append(emitJumpIfNotImmediateInteger(regT1)); // op2 is not an int
381  emitFastArithImmToInt(regT1);
382  urshift32(regT1, regT0);
383  failures.append(branch32(LessThan, regT0, TrustedImm32(0)));
384  emitFastArithReTagImmediate(regT0, regT0);
385  emitPutVirtualRegister(dst, regT0);
386  emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift));
387  failures.link(this);
388  }
 351 linkSlowCase(iter);
 352 linkSlowCase(iter);
 353 linkSlowCase(iter);
 354 } else {
 355 linkSlowCase(iter);
 356 linkSlowCase(iter);
389357 }
390 
391  linkSlowCase(iter); // int32 check - op2 is not an int
392  linkSlowCase(iter); // Can't represent unsigned result as an immediate
393358 }
394 
 359
395360 JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_urshift);
396361 slowPathCall.call();
397362}
398363
 364void JIT::emit_op_unsigned(Instruction* currentInstruction)
 365{
 366 int result = currentInstruction[1].u.operand;
 367 int op1 = currentInstruction[2].u.operand;
 368
 369 emitGetVirtualRegister(op1, regT0);
 370 emitJumpSlowCaseIfNotImmediateInteger(regT0);
 371 addSlowCase(branch32(LessThan, regT0, TrustedImm32(0)));
 372 emitFastArithReTagImmediate(regT0, regT0);
 373 emitPutVirtualRegister(result, regT0);
 374}
 375
 376void JIT::emitSlow_op_unsigned(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 377{
 378 linkSlowCase(iter);
 379 linkSlowCase(iter);
 380
 381 JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_unsigned);
 382 slowPathCall.call();
 383}
 384
399385void JIT::emit_compareAndJump(OpcodeID, int op1, int op2, unsigned target, RelationalCondition condition)
400386{
401387 // We generate inline code for the following cases in the fast path:
160441

Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm

@@macro bitOp(operation, slowPath, advance
10421042 bineq t3, Int32Tag, .slow
10431043 bineq t2, Int32Tag, .slow
10441044 loadi 4[PC], t2
1045  operation(t1, t0, .slow)
 1045 operation(t1, t0)
10461046 storei t3, TagOffset[cfr, t2, 8]
10471047 storei t0, PayloadOffset[cfr, t2, 8]
10481048 dispatch(advance)

@@end
10551055_llint_op_lshift:
10561056 traceExecution()
10571057 bitOp(
1058  macro (left, right, slow) lshifti left, right end,
 1058 macro (left, right) lshifti left, right end,
10591059 _slow_path_lshift,
10601060 4)
10611061

@@_llint_op_lshift:
10631063_llint_op_rshift:
10641064 traceExecution()
10651065 bitOp(
1066  macro (left, right, slow) rshifti left, right end,
 1066 macro (left, right) rshifti left, right end,
10671067 _slow_path_rshift,
10681068 4)
10691069

@@_llint_op_rshift:
10711071_llint_op_urshift:
10721072 traceExecution()
10731073 bitOp(
1074  macro (left, right, slow)
1075  urshifti left, right
1076  bilt right, 0, slow
1077  end,
 1074 macro (left, right) urshifti left, right end,
10781075 _slow_path_urshift,
10791076 4)
10801077
10811078
 1079_llint_op_unsigned:
 1080 traceExecution()
 1081 loadi 4[PC], t0
 1082 loadi 8[PC], t1
 1083 loadConstantOrVariablePayload(t1, Int32Tag, t2, .opUnsignedSlow)
 1084 bilt t2, 0, .opUnsignedSlow
 1085 storei t2, PayloadOffset[cfr, t0, 8]
 1086 storei Int32Tag, TagOffset[cfr, t0, 8]
 1087 dispatch(3)
 1088.opUnsignedSlow:
 1089 callSlowPath(_slow_path_unsigned)
 1090 dispatch(3)
 1091
 1092
10821093_llint_op_bitand:
10831094 traceExecution()
10841095 bitOp(
1085  macro (left, right, slow) andi left, right end,
 1096 macro (left, right) andi left, right end,
10861097 _slow_path_bitand,
10871098 5)
10881099

@@_llint_op_bitand:
10901101_llint_op_bitxor:
10911102 traceExecution()
10921103 bitOp(
1093  macro (left, right, slow) xori left, right end,
 1104 macro (left, right) xori left, right end,
10941105 _slow_path_bitxor,
10951106 5)
10961107

@@_llint_op_bitxor:
10981109_llint_op_bitor:
10991110 traceExecution()
11001111 bitOp(
1101  macro (left, right, slow) ori left, right end,
 1112 macro (left, right) ori left, right end,
11021113 _slow_path_bitor,
11031114 5)
11041115
160441

Source/JavaScriptCore/llint/LowLevelInterpreter64.asm

@@macro bitOp(operation, slowPath, advance
859859 loadConstantOrVariable(t2, t0)
860860 bqb t0, tagTypeNumber, .slow
861861 bqb t1, tagTypeNumber, .slow
862  operation(t1, t0, .slow)
 862 operation(t1, t0)
863863 orq tagTypeNumber, t0
864864 storeq t0, [cfr, t3, 8]
865865 dispatch(advance)

@@end
872872_llint_op_lshift:
873873 traceExecution()
874874 bitOp(
875  macro (left, right, slow) lshifti left, right end,
 875 macro (left, right) lshifti left, right end,
876876 _slow_path_lshift,
877877 4)
878878

@@_llint_op_lshift:
880880_llint_op_rshift:
881881 traceExecution()
882882 bitOp(
883  macro (left, right, slow) rshifti left, right end,
 883 macro (left, right) rshifti left, right end,
884884 _slow_path_rshift,
885885 4)
886886

@@_llint_op_rshift:
888888_llint_op_urshift:
889889 traceExecution()
890890 bitOp(
891  macro (left, right, slow)
892  urshifti left, right
893  bilt right, 0, slow
894  end,
 891 macro (left, right) urshifti left, right end,
895892 _slow_path_urshift,
896893 4)
897894
898895
 896_llint_op_unsigned:
 897 traceExecution()
 898 loadisFromInstruction(1, t0)
 899 loadisFromInstruction(2, t1)
 900 loadConstantOrVariable(t1, t2)
 901 bilt t2, 0, .opUnsignedSlow
 902 storeq t2, [cfr, t0, 8]
 903 dispatch(3)
 904.opUnsignedSlow:
 905 callSlowPath(_slow_path_unsigned)
 906 dispatch(3)
 907
 908
899909_llint_op_bitand:
900910 traceExecution()
901911 bitOp(
902  macro (left, right, slow) andi left, right end,
 912 macro (left, right) andi left, right end,
903913 _slow_path_bitand,
904914 5)
905915

@@_llint_op_bitand:
907917_llint_op_bitxor:
908918 traceExecution()
909919 bitOp(
910  macro (left, right, slow) xori left, right end,
 920 macro (left, right) xori left, right end,
911921 _slow_path_bitxor,
912922 5)
913923

@@_llint_op_bitxor:
915925_llint_op_bitor:
916926 traceExecution()
917927 bitOp(
918  macro (left, right, slow) ori left, right end,
 928 macro (left, right) ori left, right end,
919929 _slow_path_bitor,
920930 5)
921931
160441

Source/JavaScriptCore/runtime/CommonSlowPaths.cpp

@@SLOW_PATH_DECL(slow_path_urshift)
417417 BEGIN();
418418 uint32_t a = OP_C(2).jsValue().toUInt32(exec);
419419 uint32_t b = OP_C(3).jsValue().toUInt32(exec);
420  RETURN(jsNumber(a >> (b & 31)));
 420 RETURN(jsNumber(static_cast<int32_t>(a >> (b & 31))));
 421}
 422
 423SLOW_PATH_DECL(slow_path_unsigned)
 424{
 425 BEGIN();
 426 uint32_t a = OP_C(2).jsValue().toUInt32(exec);
 427 RETURN(jsNumber(a));
421428}
422429
423430SLOW_PATH_DECL(slow_path_bitand)
160441

Source/JavaScriptCore/runtime/CommonSlowPaths.h

@@SLOW_PATH_HIDDEN_DECL(slow_path_mod);
188188SLOW_PATH_HIDDEN_DECL(slow_path_lshift);
189189SLOW_PATH_HIDDEN_DECL(slow_path_rshift);
190190SLOW_PATH_HIDDEN_DECL(slow_path_urshift);
 191SLOW_PATH_HIDDEN_DECL(slow_path_unsigned);
191192SLOW_PATH_HIDDEN_DECL(slow_path_bitand);
192193SLOW_PATH_HIDDEN_DECL(slow_path_bitor);
193194SLOW_PATH_HIDDEN_DECL(slow_path_bitxor);
160441