Changeset 89772 in webkit
- Timestamp:
- Jun 26, 2011 12:30:56 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r89732 r89772 1 2011-06-26 Filip Pizlo <fpizlo@apple.com> 2 3 Reviewed by Gavin Barraclough. 4 5 DFG non-speculative JIT has potentially harmful speculations with respect to arithmetic operations. 6 https://bugs.webkit.org/show_bug.cgi?id=63347 7 8 * dfg/DFGNonSpeculativeJIT.cpp: 9 - Changed arithmetic operations to speculate in favor of integers. 10 (JSC::DFG::NonSpeculativeJIT::valueToNumber): 11 (JSC::DFG::NonSpeculativeJIT::knownConstantArithOp): 12 (JSC::DFG::NonSpeculativeJIT::basicArithOp): 13 (JSC::DFG::NonSpeculativeJIT::compile): 14 * dfg/DFGNonSpeculativeJIT.h: 15 * dfg/DFGOperations.cpp: 16 - Added slow-path routines for arithmetic that perform no speculation; the 17 non-speculative JIT will generate calls to these in cases where its 18 speculation fails. 19 * dfg/DFGOperations.h: 20 1 21 2011-06-24 Nikolas Zimmermann <nzimmermann@rim.com> 2 22 -
trunk/Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.cpp
r89643 r89772 57 57 } 58 58 59 void NonSpeculativeJIT::valueToNumber(JSValueOperand& operand, FPRReg fpr)59 void NonSpeculativeJIT::valueToNumber(JSValueOperand& operand, GPRReg gpr) 60 60 { 61 61 GPRReg jsValueGpr = operand.gpr(); 62 GPRReg tempGpr = allocate(); // FIXME: can we skip this allocation on the last use of the virtual register?63 62 64 63 JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister); … … 66 65 67 66 // First, if we get here we have a double encoded as a JSValue 68 m_jit.move(jsValueGpr, tempGpr); 69 m_jit.addPtr(GPRInfo::tagTypeNumberRegister, tempGpr); 70 m_jit.movePtrToDouble(tempGpr, fpr); 67 m_jit.move(jsValueGpr, gpr); 71 68 JITCompiler::Jump hasUnboxedDouble = m_jit.jump(); 72 69 73 70 // Next handle cells (& other JS immediates) 74 71 nonNumeric.link(&m_jit); 75 silentSpillAllRegisters( fpr, jsValueGpr);72 silentSpillAllRegisters(gpr, jsValueGpr); 76 73 m_jit.move(jsValueGpr, GPRInfo::argumentGPR1); 77 74 m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 78 75 appendCallWithExceptionCheck(dfgConvertJSValueToNumber); 79 m_jit.moveDouble(FPRInfo::returnValueFPR, fpr);80 silentFillAllRegisters( fpr);76 boxDouble(FPRInfo::returnValueFPR, gpr); 77 silentFillAllRegisters(gpr); 81 78 JITCompiler::Jump hasCalledToNumber = m_jit.jump(); 82 79 83 80 // Finally, handle integers. 84 81 isInteger.link(&m_jit); 85 m_jit. convertInt32ToDouble(jsValueGpr, fpr);82 m_jit.orPtr(GPRInfo::tagTypeNumberRegister, jsValueGpr, gpr); 86 83 hasUnboxedDouble.link(&m_jit); 87 84 hasCalledToNumber.link(&m_jit); 88 89 m_gprs.unlock(tempGpr);90 85 } 91 86 … … 166 161 } 167 162 163 void NonSpeculativeJIT::knownConstantArithOp(NodeType op, NodeIndex regChild, NodeIndex immChild, bool commute) 164 { 165 JSValueOperand regArg(this, regChild); 166 GPRReg regArgGPR = regArg.gpr(); 167 GPRTemporary result(this, regArg); 168 GPRReg resultGPR = result.gpr(); 169 170 JITCompiler::Jump notInt; 171 172 int32_t imm = valueOfInt32Constant(immChild); 173 174 if (!isKnownInteger(regChild)) 175 notInt = m_jit.branchPtr(MacroAssembler::Below, regArgGPR, GPRInfo::tagTypeNumberRegister); 176 177 m_jit.zeroExtend32ToPtr(regArgGPR, resultGPR); 178 179 JITCompiler::Jump overflow; 180 181 switch (op) { 182 case ValueAdd: 183 case ArithAdd: { 184 overflow = m_jit.branchAdd32(MacroAssembler::Overflow, Imm32(imm), resultGPR); 185 break; 186 } 187 188 case ArithSub: { 189 overflow = m_jit.branchSub32(MacroAssembler::Overflow, Imm32(imm), resultGPR); 190 break; 191 } 192 193 default: 194 ASSERT_NOT_REACHED(); 195 } 196 197 m_jit.orPtr(GPRInfo::tagTypeNumberRegister, resultGPR); 198 199 JITCompiler::Jump done = m_jit.jump(); 200 201 overflow.link(&m_jit); 202 203 if (regArgGPR == resultGPR) { 204 switch (op) { 205 case ValueAdd: 206 case ArithAdd: { 207 m_jit.sub32(Imm32(imm), regArgGPR); 208 break; 209 } 210 211 case ArithSub: { 212 m_jit.add32(Imm32(imm), regArgGPR); 213 break; 214 } 215 216 default: 217 ASSERT_NOT_REACHED(); 218 } 219 m_jit.orPtr(GPRInfo::tagTypeNumberRegister, regArgGPR); 220 } 221 222 if (!isKnownInteger(regChild)) 223 notInt.link(&m_jit); 224 225 silentSpillAllRegisters(resultGPR, regArgGPR); 226 switch (op) { 227 case ValueAdd: 228 if (commute) { 229 m_jit.move(regArgGPR, GPRInfo::argumentGPR2); 230 m_jit.move(MacroAssembler::ImmPtr(static_cast<const void*>(JSValue::encode(jsNumber(imm)))), GPRInfo::argumentGPR1); 231 } else { 232 m_jit.move(regArgGPR, GPRInfo::argumentGPR1); 233 m_jit.move(MacroAssembler::ImmPtr(static_cast<const void*>(JSValue::encode(jsNumber(imm)))), GPRInfo::argumentGPR2); 234 } 235 m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 236 appendCallWithExceptionCheck(operationValueAdd); 237 break; 238 239 case ArithAdd: 240 if (commute) { 241 m_jit.move(regArgGPR, GPRInfo::argumentGPR1); 242 m_jit.move(MacroAssembler::ImmPtr(static_cast<const void*>(JSValue::encode(jsNumber(imm)))), GPRInfo::argumentGPR0); 243 } else { 244 m_jit.move(regArgGPR, GPRInfo::argumentGPR0); 245 m_jit.move(MacroAssembler::ImmPtr(static_cast<const void*>(JSValue::encode(jsNumber(imm)))), GPRInfo::argumentGPR1); 246 } 247 m_jit.appendCall(operationArithAdd); 248 break; 249 250 case ArithSub: 251 ASSERT(!commute); 252 m_jit.move(regArgGPR, GPRInfo::argumentGPR0); 253 m_jit.move(MacroAssembler::ImmPtr(static_cast<const void*>(JSValue::encode(jsNumber(imm)))), GPRInfo::argumentGPR1); 254 m_jit.appendCall(operationArithSub); 255 break; 256 257 default: 258 ASSERT_NOT_REACHED(); 259 } 260 m_jit.move(GPRInfo::returnValueGPR, resultGPR); 261 silentFillAllRegisters(resultGPR); 262 263 done.link(&m_jit); 264 265 jsValueResult(resultGPR, m_compileIndex); 266 } 267 268 void NonSpeculativeJIT::basicArithOp(NodeType op, Node &node) 269 { 270 JSValueOperand arg1(this, node.child1); 271 JSValueOperand arg2(this, node.child2); 272 273 GPRReg arg1GPR = arg1.gpr(); 274 GPRReg arg2GPR = arg2.gpr(); 275 276 GPRTemporary temp(this, arg2); 277 GPRTemporary result(this); 278 279 GPRReg tempGPR = temp.gpr(); 280 GPRReg resultGPR = result.gpr(); 281 282 JITCompiler::JumpList slowPath; 283 JITCompiler::JumpList overflowSlowPath; 284 285 if (!isKnownInteger(node.child1)) 286 slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister)); 287 if (!isKnownInteger(node.child2)) 288 slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister)); 289 290 m_jit.zeroExtend32ToPtr(arg1GPR, resultGPR); 291 m_jit.zeroExtend32ToPtr(arg2GPR, tempGPR); 292 293 switch (op) { 294 case ValueAdd: 295 case ArithAdd: { 296 overflowSlowPath.append(m_jit.branchAdd32(MacroAssembler::Overflow, tempGPR, resultGPR)); 297 break; 298 } 299 300 case ArithSub: { 301 overflowSlowPath.append(m_jit.branchSub32(MacroAssembler::Overflow, tempGPR, resultGPR)); 302 break; 303 } 304 305 case ArithMul: { 306 overflowSlowPath.append(m_jit.branchMul32(MacroAssembler::Overflow, tempGPR, resultGPR)); 307 overflowSlowPath.append(m_jit.branchTest32(MacroAssembler::Zero, resultGPR)); 308 break; 309 } 310 311 default: 312 ASSERT_NOT_REACHED(); 313 } 314 315 m_jit.orPtr(GPRInfo::tagTypeNumberRegister, resultGPR); 316 317 JITCompiler::Jump done = m_jit.jump(); 318 319 overflowSlowPath.link(&m_jit); 320 321 if (arg2GPR == tempGPR) 322 m_jit.orPtr(GPRInfo::tagTypeNumberRegister, arg2GPR); 323 324 slowPath.link(&m_jit); 325 326 silentSpillAllRegisters(resultGPR, arg1GPR, arg2GPR); 327 if (op == ValueAdd) { 328 setupStubArguments(arg1GPR, arg2GPR); 329 m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 330 appendCallWithExceptionCheck(operationValueAdd); 331 } else { 332 setupTwoStubArgs<GPRInfo::argumentGPR0, GPRInfo::argumentGPR1>(arg1GPR, arg2GPR); 333 switch (op) { 334 case ArithAdd: 335 m_jit.appendCall(operationArithAdd); 336 break; 337 338 case ArithSub: 339 m_jit.appendCall(operationArithSub); 340 break; 341 342 case ArithMul: 343 m_jit.appendCall(operationArithMul); 344 break; 345 346 default: 347 ASSERT_NOT_REACHED(); 348 } 349 } 350 m_jit.move(GPRInfo::returnValueGPR, resultGPR); 351 silentFillAllRegisters(resultGPR); 352 353 done.link(&m_jit); 354 355 jsValueResult(resultGPR, m_compileIndex); 356 } 357 358 void NonSpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition cond, const Z_DFGOperation_EJJ& helperFunction) 359 { 360 // FIXME: should do some peephole to fuse compare/branch 361 362 JSValueOperand arg1(this, node.child1); 363 JSValueOperand arg2(this, node.child2); 364 GPRReg arg1GPR = arg1.gpr(); 365 GPRReg arg2GPR = arg2.gpr(); 366 367 GPRTemporary result(this); 368 GPRTemporary temp(this); 369 GPRReg resultGPR = result.gpr(); 370 GPRReg tempGPR = temp.gpr(); 371 372 JITCompiler::JumpList slowPath; 373 374 if (!isKnownInteger(node.child1)) 375 slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister)); 376 if (!isKnownInteger(node.child2)) 377 slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister)); 378 379 m_jit.zeroExtend32ToPtr(arg1GPR, tempGPR); 380 m_jit.zeroExtend32ToPtr(arg2GPR, resultGPR); 381 382 m_jit.compare32(cond, tempGPR, resultGPR, resultGPR); 383 384 JITCompiler::Jump haveResult = m_jit.jump(); 385 386 slowPath.link(&m_jit); 387 388 silentSpillAllRegisters(resultGPR, arg1GPR, arg2GPR); 389 setupStubArguments(arg1GPR, arg2GPR); 390 m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 391 appendCallWithExceptionCheck(helperFunction); 392 m_jit.move(GPRInfo::returnValueGPR, resultGPR); 393 silentFillAllRegisters(resultGPR); 394 395 m_jit.andPtr(TrustedImm32(static_cast<int32_t>(1)), resultGPR); 396 397 haveResult.link(&m_jit); 398 399 m_jit.or32(TrustedImm32(ValueFalse), resultGPR); 400 jsValueResult(resultGPR, m_compileIndex); 401 } 402 168 403 void NonSpeculativeJIT::compile(SpeculationCheckIndexIterator& checkIterator, Node& node) 169 404 { … … 273 508 case UInt32ToNumber: { 274 509 IntegerOperand op1(this, node.child1); 275 FPRTemporary result(this); 276 m_jit.convertInt32ToDouble(op1.gpr(), result.fpr()); 277 278 MacroAssembler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, op1.gpr(), TrustedImm32(0)); 279 m_jit.addDouble(JITCompiler::AbsoluteAddress(&twoToThe32), result.fpr()); 510 FPRTemporary boxer(this); 511 GPRTemporary result(this, op1); 512 513 JITCompiler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, op1.gpr(), TrustedImm32(0)); 514 515 m_jit.convertInt32ToDouble(op1.gpr(), boxer.fpr()); 516 m_jit.addDouble(JITCompiler::AbsoluteAddress(&twoToThe32), boxer.fpr()); 517 518 m_jit.moveDoubleToPtr(boxer.fpr(), result.gpr()); 519 m_jit.subPtr(GPRInfo::tagTypeNumberRegister, result.gpr()); 520 521 JITCompiler::Jump done = m_jit.jump(); 522 280 523 positive.link(&m_jit); 281 282 doubleResult(result.fpr(), m_compileIndex); 524 525 m_jit.orPtr(GPRInfo::tagTypeNumberRegister, op1.gpr(), result.gpr()); 526 527 done.link(&m_jit); 528 529 jsValueResult(result.gpr(), m_compileIndex); 283 530 break; 284 531 } … … 296 543 297 544 GenerationInfo& childInfo = m_generationInfo[m_jit.graph()[node.child1].virtualRegister()]; 298 if ((childInfo.registerFormat() | |DataFormatJS) == DataFormatJSDouble) {545 if ((childInfo.registerFormat() | DataFormatJS) == DataFormatJSDouble) { 299 546 DoubleOperand op1(this, node.child1); 300 547 GPRTemporary result(this); … … 315 562 ASSERT(!isDoubleConstant(node.child1)); 316 563 317 if (isKnownInteger(node.child1)) { 318 IntegerOperand op1(this, node.child1); 319 FPRTemporary result(this); 320 m_jit.convertInt32ToDouble(op1.gpr(), result.fpr()); 321 doubleResult(result.fpr(), m_compileIndex); 322 break; 323 } 324 325 GenerationInfo& childInfo = m_generationInfo[m_jit.graph()[node.child1].virtualRegister()]; 326 if ((childInfo.registerFormat() || DataFormatJS) == DataFormatJSDouble) { 327 DoubleOperand op1(this, node.child1); 328 FPRTemporary result(this, op1); 329 m_jit.moveDouble(op1.fpr(), result.fpr()); 330 doubleResult(result.fpr(), m_compileIndex); 564 if (isKnownNumeric(node.child1)) { 565 JSValueOperand op1(this, node.child1); 566 GPRTemporary result(this, op1); 567 m_jit.move(op1.gpr(), result.gpr()); 568 jsValueResult(result.gpr(), m_compileIndex); 331 569 break; 332 570 } 333 571 334 572 JSValueOperand op1(this, node.child1); 335 FPRTemporary result(this); 336 valueToNumber(op1, result.fpr()); 337 doubleResult(result.fpr(), m_compileIndex); 338 break; 339 } 340 341 case ValueAdd: { 573 GPRTemporary result(this); 574 valueToNumber(op1, result.gpr()); 575 jsValueResult(result.gpr(), m_compileIndex); 576 break; 577 } 578 579 case ValueAdd: 580 case ArithAdd: { 581 if (isInt32Constant(node.child1)) { 582 knownConstantArithOp(op, node.child2, node.child1, true); 583 break; 584 } 585 586 if (isInt32Constant(node.child2)) { 587 knownConstantArithOp(op, node.child1, node.child2, false); 588 break; 589 } 590 591 basicArithOp(op, node); 592 break; 593 } 594 595 case ArithSub: { 596 if (isInt32Constant(node.child2)) { 597 knownConstantArithOp(ArithSub, node.child1, node.child2, false); 598 break; 599 } 600 601 basicArithOp(ArithSub, node); 602 break; 603 } 604 605 case ArithMul: { 606 basicArithOp(ArithMul, node); 607 break; 608 } 609 610 case ArithDiv: { 611 JSValueOperand arg1(this, node.child1); 612 JSValueOperand arg2(this, node.child2); 613 GPRReg arg1GPR = arg1.gpr(); 614 GPRReg arg2GPR = arg2.gpr(); 615 616 flushRegisters(); 617 618 GPRResult result(this); 619 620 ASSERT(isFlushed()); 621 setupTwoStubArgs<GPRInfo::argumentGPR0, GPRInfo::argumentGPR1>(arg1GPR, arg2GPR); 622 m_jit.appendCall(operationArithDiv); 623 m_jit.move(GPRInfo::returnValueGPR, result.gpr()); 624 625 jsValueResult(result.gpr(), m_compileIndex); 626 break; 627 } 628 629 case ArithMod: { 342 630 JSValueOperand arg1(this, node.child1); 343 631 JSValueOperand arg2(this, node.child2); … … 347 635 348 636 GPRResult result(this); 349 callOperation(operationValueAdd, result.gpr(), arg1GPR, arg2GPR); 637 638 ASSERT(isFlushed()); 639 setupTwoStubArgs<GPRInfo::argumentGPR0, GPRInfo::argumentGPR1>(arg1GPR, arg2GPR); 640 m_jit.appendCall(operationArithMod); 641 m_jit.move(GPRInfo::returnValueGPR, result.gpr()); 350 642 351 643 jsValueResult(result.gpr(), m_compileIndex); 352 break;353 }354 355 case ArithAdd: {356 DoubleOperand op1(this, node.child1);357 DoubleOperand op2(this, node.child2);358 FPRTemporary result(this, op1, op2);359 360 FPRReg reg1 = op1.fpr();361 FPRReg reg2 = op2.fpr();362 m_jit.addDouble(reg1, reg2, result.fpr());363 364 doubleResult(result.fpr(), m_compileIndex);365 break;366 }367 368 case ArithSub: {369 DoubleOperand op1(this, node.child1);370 DoubleOperand op2(this, node.child2);371 FPRTemporary result(this, op1);372 373 FPRReg reg1 = op1.fpr();374 FPRReg reg2 = op2.fpr();375 m_jit.subDouble(reg1, reg2, result.fpr());376 377 doubleResult(result.fpr(), m_compileIndex);378 break;379 }380 381 case ArithMul: {382 DoubleOperand op1(this, node.child1);383 DoubleOperand op2(this, node.child2);384 FPRTemporary result(this, op1, op2);385 386 FPRReg reg1 = op1.fpr();387 FPRReg reg2 = op2.fpr();388 m_jit.mulDouble(reg1, reg2, result.fpr());389 390 doubleResult(result.fpr(), m_compileIndex);391 break;392 }393 394 case ArithDiv: {395 DoubleOperand op1(this, node.child1);396 DoubleOperand op2(this, node.child2);397 FPRTemporary result(this, op1);398 399 FPRReg reg1 = op1.fpr();400 FPRReg reg2 = op2.fpr();401 m_jit.divDouble(reg1, reg2, result.fpr());402 403 doubleResult(result.fpr(), m_compileIndex);404 break;405 }406 407 case ArithMod: {408 DoubleOperand arg1(this, node.child1);409 DoubleOperand arg2(this, node.child2);410 FPRReg arg1FPR = arg1.fpr();411 FPRReg arg2FPR = arg2.fpr();412 flushRegisters();413 414 FPRResult result(this);415 callOperation(fmod, result.fpr(), arg1FPR, arg2FPR);416 417 doubleResult(result.fpr(), m_compileIndex);418 644 break; 419 645 } … … 421 647 case LogicalNot: { 422 648 JSValueOperand arg1(this, node.child1); 649 GPRTemporary result(this); 650 423 651 GPRReg arg1GPR = arg1.gpr(); 424 flushRegisters(); 425 426 GPRResult result(this); 427 callOperation(dfgConvertJSValueToBoolean, result.gpr(), arg1GPR); 428 429 // If we add a DataFormatBool, we should use it here. 430 m_jit.xor32(TrustedImm32(ValueTrue), result.gpr()); 431 jsValueResult(result.gpr(), m_compileIndex); 432 break; 433 } 434 435 case CompareLess: { 436 JSValueOperand arg1(this, node.child1); 437 JSValueOperand arg2(this, node.child2); 438 GPRReg arg1GPR = arg1.gpr(); 439 GPRReg arg2GPR = arg2.gpr(); 440 flushRegisters(); 441 442 GPRResult result(this); 443 callOperation(operationCompareLess, result.gpr(), arg1GPR, arg2GPR); 444 m_jit.or32(TrustedImm32(ValueFalse), result.gpr()); 445 446 jsValueResult(result.gpr(), m_compileIndex); 447 break; 448 } 449 450 case CompareLessEq: { 451 JSValueOperand arg1(this, node.child1); 452 JSValueOperand arg2(this, node.child2); 453 GPRReg arg1GPR = arg1.gpr(); 454 GPRReg arg2GPR = arg2.gpr(); 455 flushRegisters(); 456 457 GPRResult result(this); 458 callOperation(operationCompareLessEq, result.gpr(), arg1GPR, arg2GPR); 459 m_jit.or32(TrustedImm32(ValueFalse), result.gpr()); 460 461 jsValueResult(result.gpr(), m_compileIndex); 462 break; 463 } 464 465 case CompareEq: { 466 JSValueOperand arg1(this, node.child1); 467 JSValueOperand arg2(this, node.child2); 468 GPRReg arg1GPR = arg1.gpr(); 469 GPRReg arg2GPR = arg2.gpr(); 470 flushRegisters(); 471 472 GPRResult result(this); 473 callOperation(operationCompareEq, result.gpr(), arg1GPR, arg2GPR); 474 m_jit.or32(TrustedImm32(ValueFalse), result.gpr()); 475 476 jsValueResult(result.gpr(), m_compileIndex); 477 break; 478 } 479 480 case CompareStrictEq: { 481 JSValueOperand arg1(this, node.child1); 482 JSValueOperand arg2(this, node.child2); 483 GPRReg arg1GPR = arg1.gpr(); 484 GPRReg arg2GPR = arg2.gpr(); 485 flushRegisters(); 486 487 GPRResult result(this); 488 callOperation(operationCompareStrictEq, result.gpr(), arg1GPR, arg2GPR); 489 m_jit.or32(TrustedImm32(ValueFalse), result.gpr()); 490 491 jsValueResult(result.gpr(), m_compileIndex); 492 break; 493 } 652 GPRReg resultGPR = result.gpr(); 653 654 m_jit.move(arg1GPR, resultGPR); 655 m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR); 656 JITCompiler::Jump fastCase = m_jit.branchTestPtr(JITCompiler::Zero, resultGPR, TrustedImm32(static_cast<int32_t>(~1))); 657 658 silentSpillAllRegisters(resultGPR, arg1GPR); 659 m_jit.move(arg1GPR, GPRInfo::argumentGPR1); 660 m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 661 appendCallWithExceptionCheck(dfgConvertJSValueToBoolean); 662 m_jit.move(GPRInfo::returnValueGPR, resultGPR); 663 silentFillAllRegisters(resultGPR); 664 665 fastCase.link(&m_jit); 666 667 m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR); 668 jsValueResult(resultGPR, m_compileIndex); 669 break; 670 } 671 672 case CompareLess: 673 compare(node, MacroAssembler::LessThan, operationCompareLess); 674 break; 675 676 case CompareLessEq: 677 compare(node, MacroAssembler::LessThanOrEqual, operationCompareLessEq); 678 break; 679 680 case CompareEq: 681 compare(node, MacroAssembler::Equal, operationCompareEq); 682 break; 683 684 case CompareStrictEq: 685 compare(node, MacroAssembler::Equal, operationCompareStrictEq); 686 break; 494 687 495 688 case GetByVal: { -
trunk/Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.h
r87364 r89772 88 88 // These methods are used to plant calls out to C++ 89 89 // helper routines to convert between types. 90 void valueToNumber(JSValueOperand&, FPRReg result);90 void valueToNumber(JSValueOperand&, GPRReg result); 91 91 void valueToInt32(JSValueOperand&, GPRReg result); 92 92 void numberToInt32(FPRReg, GPRReg result); … … 99 99 m_entryLocations.append(EntryLocation(entry, this)); 100 100 } 101 101 102 // internal helpers for add/sub/mul operations 103 void knownConstantArithOp(NodeType op, NodeIndex regChild, NodeIndex immChild, bool commute); 104 void basicArithOp(NodeType op, Node&); 105 void compare(Node&, MacroAssembler::RelationalCondition, const Z_DFGOperation_EJJ&); 106 102 107 EntryLocationVector m_entryLocations; 103 108 }; -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r88975 r89772 139 139 } 140 140 141 EncodedJSValue operationArithAdd(EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) 142 { 143 double num1 = JSValue::decode(encodedOp1).uncheckedGetNumber(); 144 double num2 = JSValue::decode(encodedOp2).uncheckedGetNumber(); 145 return JSValue::encode(jsNumber(num1 + num2)); 146 } 147 148 EncodedJSValue operationArithSub(EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) 149 { 150 double num1 = JSValue::decode(encodedOp1).uncheckedGetNumber(); 151 double num2 = JSValue::decode(encodedOp2).uncheckedGetNumber(); 152 return JSValue::encode(jsNumber(num1 - num2)); 153 } 154 155 EncodedJSValue operationArithMul(EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) 156 { 157 double num1 = JSValue::decode(encodedOp1).uncheckedGetNumber(); 158 double num2 = JSValue::decode(encodedOp2).uncheckedGetNumber(); 159 return JSValue::encode(jsNumber(num1 * num2)); 160 } 161 162 EncodedJSValue operationArithDiv(EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) 163 { 164 double num1 = JSValue::decode(encodedOp1).uncheckedGetNumber(); 165 double num2 = JSValue::decode(encodedOp2).uncheckedGetNumber(); 166 return JSValue::encode(jsNumber(num1 / num2)); 167 } 168 169 EncodedJSValue operationArithMod(EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) 170 { 171 double num1 = JSValue::decode(encodedOp1).uncheckedGetNumber(); 172 double num2 = JSValue::decode(encodedOp2).uncheckedGetNumber(); 173 return JSValue::encode(jsNumber(fmod(num1, num2))); 174 } 175 141 176 static inline EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index) 142 177 { -
trunk/Source/JavaScriptCore/dfg/DFGOperations.h
r88280 r89772 50 50 EncodedJSValue operationConvertThis(ExecState*, EncodedJSValue encodedOp1); 51 51 EncodedJSValue operationValueAdd(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); 52 EncodedJSValue operationArithAdd(EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); 53 EncodedJSValue operationArithSub(EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); 54 EncodedJSValue operationArithMul(EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); 55 EncodedJSValue operationArithDiv(EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); 56 EncodedJSValue operationArithMod(EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); 52 57 EncodedJSValue operationGetByVal(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty); 53 58 EncodedJSValue operationGetById(ExecState*, EncodedJSValue encodedBase, Identifier*);
Note: See TracChangeset
for help on using the changeset viewer.