Changeset 245047 in webkit
- Timestamp:
- May 7, 2019, 6:23:22 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 4 edited
-
JSTests/ChangeLog (modified) (1 diff)
-
JSTests/stress/do-not-perform-bytecode-peephole-optimization-in-jump-target.js (added)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (modified) (5 diffs)
-
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r245040 r245047 1 2019-05-07 Yusuke Suzuki <ysuzuki@apple.com> 2 3 JSC: A bug in BytecodeGenerator::emitEqualityOpImpl 4 https://bugs.webkit.org/show_bug.cgi?id=197479 5 6 Reviewed by Saam Barati. 7 8 * stress/do-not-perform-bytecode-peephole-optimization-in-jump-target.js: Added. 9 (shouldBe): 10 1 11 2019-05-07 Yusuke Suzuki <ysuzuki@apple.com> 2 12 -
trunk/Source/JavaScriptCore/ChangeLog
r245040 r245047 1 2019-05-07 Yusuke Suzuki <ysuzuki@apple.com> 2 3 JSC: A bug in BytecodeGenerator::emitEqualityOpImpl 4 https://bugs.webkit.org/show_bug.cgi?id=197479 5 6 Reviewed by Saam Barati. 7 8 Our peephole optimization in BytecodeGenerator is (1) rewinding the previous instruction and (2) emit optimized instruction instead. 9 If we have jump target between the previous instruction and the subsequent instruction, this peephole optimization breaks the jump target. 10 To prevent it, we had a mechanism disabling peephole optimization, setting m_lastOpcodeID = op_end and checking m_lastOpcodeID when performing 11 peephole optimization. However, BytecodeGenerator::emitEqualityOpImpl checks `m_lastInstruction->is<OpTypeof>` instead of `m_lastOpcodeID == op_typeof`, 12 and miss `op_end` case. 13 14 This patch makes the following changes. 15 16 1. Add canDoPeepholeOptimization method to clarify the intent of `m_lastInstruction = op_end`. 17 2. Check canDoPeepholeOptimization status before performing peephole optimization in emitJumpIfTrue, emitJumpIfFalse, and emitEqualityOpImpl. 18 3. Add `ASSERT(canDoPeepholeOptimization())` in fuseCompareAndJump and fuseTestAndJmp to ensure that peephole optimization is allowed. 19 20 * bytecompiler/BytecodeGenerator.cpp: 21 (JSC::BytecodeGenerator::fuseCompareAndJump): 22 (JSC::BytecodeGenerator::fuseTestAndJmp): 23 (JSC::BytecodeGenerator::emitJumpIfTrue): 24 (JSC::BytecodeGenerator::emitJumpIfFalse): 25 (JSC::BytecodeGenerator::emitEqualityOpImpl): 26 * bytecompiler/BytecodeGenerator.h: 27 (JSC::BytecodeGenerator::canDoPeepholeOptimization const): 28 1 29 2019-05-07 Yusuke Suzuki <ysuzuki@apple.com> 2 30 -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r245040 r245047 1407 1407 bool BytecodeGenerator::fuseCompareAndJump(RegisterID* cond, Label& target, bool swapOperands) 1408 1408 { 1409 ASSERT(canDoPeepholeOptimization()); 1409 1410 auto binop = m_lastInstruction->as<BinOp>(); 1410 1411 if (cond->index() == binop.m_dst.offset() && cond->isTemporary() && !cond->refCount()) { … … 1423 1424 bool BytecodeGenerator::fuseTestAndJmp(RegisterID* cond, Label& target) 1424 1425 { 1426 ASSERT(canDoPeepholeOptimization()); 1425 1427 auto unop = m_lastInstruction->as<UnaryOp>(); 1426 1428 if (cond->index() == unop.m_dst.offset() && cond->isTemporary() && !cond->refCount()) { … … 1435 1437 void BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label& target) 1436 1438 { 1437 1438 if (m_lastOpcodeID == op_less) { 1439 if (fuseCompareAndJump<OpLess, OpJless>(cond, target)) 1440 return; 1441 } else if (m_lastOpcodeID == op_lesseq) { 1442 if (fuseCompareAndJump<OpLesseq, OpJlesseq>(cond, target)) 1443 return; 1444 } else if (m_lastOpcodeID == op_greater) { 1445 if (fuseCompareAndJump<OpGreater, OpJgreater>(cond, target)) 1446 return; 1447 } else if (m_lastOpcodeID == op_greatereq) { 1448 if (fuseCompareAndJump<OpGreatereq, OpJgreatereq>(cond, target)) 1449 return; 1450 } else if (m_lastOpcodeID == op_eq) { 1451 if (fuseCompareAndJump<OpEq, OpJeq>(cond, target)) 1452 return; 1453 } else if (m_lastOpcodeID == op_stricteq) { 1454 if (fuseCompareAndJump<OpStricteq, OpJstricteq>(cond, target)) 1455 return; 1456 } else if (m_lastOpcodeID == op_neq) { 1457 if (fuseCompareAndJump<OpNeq, OpJneq>(cond, target)) 1458 return; 1459 } else if (m_lastOpcodeID == op_nstricteq) { 1460 if (fuseCompareAndJump<OpNstricteq, OpJnstricteq>(cond, target)) 1461 return; 1462 } else if (m_lastOpcodeID == op_below) { 1463 if (fuseCompareAndJump<OpBelow, OpJbelow>(cond, target)) 1464 return; 1465 } else if (m_lastOpcodeID == op_beloweq) { 1466 if (fuseCompareAndJump<OpBeloweq, OpJbeloweq>(cond, target)) 1467 return; 1468 } else if (m_lastOpcodeID == op_eq_null && target.isForward()) { 1469 if (fuseTestAndJmp<OpEqNull, OpJeqNull>(cond, target)) 1470 return; 1471 } else if (m_lastOpcodeID == op_neq_null && target.isForward()) { 1472 if (fuseTestAndJmp<OpNeqNull, OpJneqNull>(cond, target)) 1473 return; 1439 if (canDoPeepholeOptimization()) { 1440 if (m_lastOpcodeID == op_less) { 1441 if (fuseCompareAndJump<OpLess, OpJless>(cond, target)) 1442 return; 1443 } else if (m_lastOpcodeID == op_lesseq) { 1444 if (fuseCompareAndJump<OpLesseq, OpJlesseq>(cond, target)) 1445 return; 1446 } else if (m_lastOpcodeID == op_greater) { 1447 if (fuseCompareAndJump<OpGreater, OpJgreater>(cond, target)) 1448 return; 1449 } else if (m_lastOpcodeID == op_greatereq) { 1450 if (fuseCompareAndJump<OpGreatereq, OpJgreatereq>(cond, target)) 1451 return; 1452 } else if (m_lastOpcodeID == op_eq) { 1453 if (fuseCompareAndJump<OpEq, OpJeq>(cond, target)) 1454 return; 1455 } else if (m_lastOpcodeID == op_stricteq) { 1456 if (fuseCompareAndJump<OpStricteq, OpJstricteq>(cond, target)) 1457 return; 1458 } else if (m_lastOpcodeID == op_neq) { 1459 if (fuseCompareAndJump<OpNeq, OpJneq>(cond, target)) 1460 return; 1461 } else if (m_lastOpcodeID == op_nstricteq) { 1462 if (fuseCompareAndJump<OpNstricteq, OpJnstricteq>(cond, target)) 1463 return; 1464 } else if (m_lastOpcodeID == op_below) { 1465 if (fuseCompareAndJump<OpBelow, OpJbelow>(cond, target)) 1466 return; 1467 } else if (m_lastOpcodeID == op_beloweq) { 1468 if (fuseCompareAndJump<OpBeloweq, OpJbeloweq>(cond, target)) 1469 return; 1470 } else if (m_lastOpcodeID == op_eq_null && target.isForward()) { 1471 if (fuseTestAndJmp<OpEqNull, OpJeqNull>(cond, target)) 1472 return; 1473 } else if (m_lastOpcodeID == op_neq_null && target.isForward()) { 1474 if (fuseTestAndJmp<OpNeqNull, OpJneqNull>(cond, target)) 1475 return; 1476 } 1474 1477 } 1475 1478 … … 1479 1482 void BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label& target) 1480 1483 { 1481 if (m_lastOpcodeID == op_less && target.isForward()) { 1482 if (fuseCompareAndJump<OpLess, OpJnless>(cond, target)) 1483 return; 1484 } else if (m_lastOpcodeID == op_lesseq && target.isForward()) { 1485 if (fuseCompareAndJump<OpLesseq, OpJnlesseq>(cond, target)) 1486 return; 1487 } else if (m_lastOpcodeID == op_greater && target.isForward()) { 1488 if (fuseCompareAndJump<OpGreater, OpJngreater>(cond, target)) 1489 return; 1490 } else if (m_lastOpcodeID == op_greatereq && target.isForward()) { 1491 if (fuseCompareAndJump<OpGreatereq, OpJngreatereq>(cond, target)) 1492 return; 1493 } else if (m_lastOpcodeID == op_eq && target.isForward()) { 1494 if (fuseCompareAndJump<OpEq, OpJneq>(cond, target)) 1495 return; 1496 } else if (m_lastOpcodeID == op_stricteq && target.isForward()) { 1497 if (fuseCompareAndJump<OpStricteq, OpJnstricteq>(cond, target)) 1498 return; 1499 } else if (m_lastOpcodeID == op_neq && target.isForward()) { 1500 if (fuseCompareAndJump<OpNeq, OpJeq>(cond, target)) 1501 return; 1502 } else if (m_lastOpcodeID == op_nstricteq && target.isForward()) { 1503 if (fuseCompareAndJump<OpNstricteq, OpJstricteq>(cond, target)) 1504 return; 1505 } else if (m_lastOpcodeID == op_below && target.isForward()) { 1506 if (fuseCompareAndJump<OpBelow, OpJbeloweq>(cond, target, true)) 1507 return; 1508 } else if (m_lastOpcodeID == op_beloweq && target.isForward()) { 1509 if (fuseCompareAndJump<OpBeloweq, OpJbelow>(cond, target, true)) 1510 return; 1511 } else if (m_lastOpcodeID == op_not) { 1512 if (fuseTestAndJmp<OpNot, OpJtrue>(cond, target)) 1513 return; 1514 } else if (m_lastOpcodeID == op_eq_null && target.isForward()) { 1515 if (fuseTestAndJmp<OpEqNull, OpJneqNull>(cond, target)) 1516 return; 1517 } else if (m_lastOpcodeID == op_neq_null && target.isForward()) { 1518 if (fuseTestAndJmp<OpNeqNull, OpJeqNull>(cond, target)) 1519 return; 1484 if (canDoPeepholeOptimization()) { 1485 if (m_lastOpcodeID == op_less && target.isForward()) { 1486 if (fuseCompareAndJump<OpLess, OpJnless>(cond, target)) 1487 return; 1488 } else if (m_lastOpcodeID == op_lesseq && target.isForward()) { 1489 if (fuseCompareAndJump<OpLesseq, OpJnlesseq>(cond, target)) 1490 return; 1491 } else if (m_lastOpcodeID == op_greater && target.isForward()) { 1492 if (fuseCompareAndJump<OpGreater, OpJngreater>(cond, target)) 1493 return; 1494 } else if (m_lastOpcodeID == op_greatereq && target.isForward()) { 1495 if (fuseCompareAndJump<OpGreatereq, OpJngreatereq>(cond, target)) 1496 return; 1497 } else if (m_lastOpcodeID == op_eq && target.isForward()) { 1498 if (fuseCompareAndJump<OpEq, OpJneq>(cond, target)) 1499 return; 1500 } else if (m_lastOpcodeID == op_stricteq && target.isForward()) { 1501 if (fuseCompareAndJump<OpStricteq, OpJnstricteq>(cond, target)) 1502 return; 1503 } else if (m_lastOpcodeID == op_neq && target.isForward()) { 1504 if (fuseCompareAndJump<OpNeq, OpJeq>(cond, target)) 1505 return; 1506 } else if (m_lastOpcodeID == op_nstricteq && target.isForward()) { 1507 if (fuseCompareAndJump<OpNstricteq, OpJstricteq>(cond, target)) 1508 return; 1509 } else if (m_lastOpcodeID == op_below && target.isForward()) { 1510 if (fuseCompareAndJump<OpBelow, OpJbeloweq>(cond, target, true)) 1511 return; 1512 } else if (m_lastOpcodeID == op_beloweq && target.isForward()) { 1513 if (fuseCompareAndJump<OpBeloweq, OpJbelow>(cond, target, true)) 1514 return; 1515 } else if (m_lastOpcodeID == op_not) { 1516 if (fuseTestAndJmp<OpNot, OpJtrue>(cond, target)) 1517 return; 1518 } else if (m_lastOpcodeID == op_eq_null && target.isForward()) { 1519 if (fuseTestAndJmp<OpEqNull, OpJneqNull>(cond, target)) 1520 return; 1521 } else if (m_lastOpcodeID == op_neq_null && target.isForward()) { 1522 if (fuseTestAndJmp<OpNeqNull, OpJeqNull>(cond, target)) 1523 return; 1524 } 1520 1525 } 1521 1526 … … 1725 1730 bool BytecodeGenerator::emitEqualityOpImpl(RegisterID* dst, RegisterID* src1, RegisterID* src2) 1726 1731 { 1732 if (!canDoPeepholeOptimization()) 1733 return false; 1734 1727 1735 if (m_lastInstruction->is<OpTypeof>()) { 1728 1736 auto op = m_lastInstruction->as<OpTypeof>(); -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r245040 r245047 1026 1026 RegisterID* emitMove(RegisterID* dst, RegisterID* src); 1027 1027 1028 bool canDoPeepholeOptimization() const { return m_lastOpcodeID != op_end; } 1029 1028 1030 public: 1029 1031 bool isSuperUsedInInnerArrowFunction();
Note:
See TracChangeset
for help on using the changeset viewer.