Changeset 39261 in webkit for trunk/JavaScriptCore/jit
- Timestamp:
- Dec 12, 2008, 5:39:38 PM (16 years ago)
- Location:
- trunk/JavaScriptCore/jit
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/jit/JIT.cpp
r39252 r39261 1367 1367 } 1368 1368 1369 #define CTI_COMPILE_BINARY_OP_SLOW_CASE(name) \1370 case name: { \1371 __ link(iter->from, __ label()); \1372 emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 0, X86::ecx); \1373 emitPutCTIArgFromVirtualRegister(instruction[i + 3].u.operand, 4, X86::ecx); \1374 emitCTICall(i, Interpreter::cti_##name); \1375 emitPutVirtualRegister(instruction[i + 1].u.operand); \1376 i += 4; \1377 break; \1378 }1379 1380 1369 void JIT::privateCompileSlowCases() 1381 1370 { … … 1384 1373 1385 1374 Instruction* instruction = m_codeBlock->instructions().begin(); 1386 for (Vector<SlowCaseEntry>::iterator iter = m_slowCases.begin(); iter != m_slowCases.end(); ++iter) {1375 for (Vector<SlowCaseEntry>::iterator iter = m_slowCases.begin(); iter != m_slowCases.end();) { 1387 1376 // FIXME: enable peephole optimizations for slow cases when applicable 1388 1377 killLastResultRegister(); … … 1395 1384 switch (OpcodeID opcodeID = m_interpreter->getOpcodeID(instruction[i].u.opcode)) { 1396 1385 case op_convert_this: { 1397 __ link(iter->from, __ label());1398 __ link((++iter)->from, __ label());1386 linkSlowCase(iter); 1387 linkSlowCase(iter); 1399 1388 emitPutCTIArg(X86::eax, 0); 1400 1389 emitCTICall(i, Interpreter::cti_op_convert_this); … … 1408 1397 unsigned src2 = instruction[i + 3].u.operand; 1409 1398 if (JSValue* value = getConstantImmediateNumericArg(src1)) { 1410 J mpSrc notImm = iter->from;1411 __ link((++iter)->from, __ label());1412 __ subl_i32r(getDeTaggedConstantImmediate(value), X86::eax);1413 __ link(notImm, __ label());1399 Jump notImm = getSlowCase(iter); 1400 linkSlowCase(iter); 1401 sub32(Imm32(getDeTaggedConstantImmediate(value)), X86::eax); 1402 notImm.link(this); 1414 1403 emitPutCTIArgFromVirtualRegister(src1, 0, X86::ecx); 1415 1404 emitPutCTIArg(X86::eax, 4); … … 1417 1406 emitPutVirtualRegister(dst); 1418 1407 } else if (JSValue* value = getConstantImmediateNumericArg(src2)) { 1419 J mpSrc notImm = iter->from;1420 __ link((++iter)->from, __ label());1421 __ subl_i32r(getDeTaggedConstantImmediate(value), X86::eax);1422 __ link(notImm, __ label());1408 Jump notImm = getSlowCase(iter); 1409 linkSlowCase(iter); 1410 sub32(Imm32(getDeTaggedConstantImmediate(value)), X86::eax); 1411 notImm.link(this); 1423 1412 emitPutCTIArg(X86::eax, 0); 1424 1413 emitPutCTIArgFromVirtualRegister(src2, 4, X86::ecx); … … 1427 1416 } else { 1428 1417 OperandTypes types = OperandTypes::fromInt(instruction[i + 4].u.operand); 1429 if (types.first().mightBeNumber() && types.second().mightBeNumber()) 1430 compileBinaryArithOpSlowCase(op_add, iter, dst, src1, src2, types, i); 1431 else 1432 ASSERT_NOT_REACHED(); 1418 ASSERT(types.first().mightBeNumber() && types.second().mightBeNumber()); 1419 compileBinaryArithOpSlowCase(op_add, iter, dst, src1, src2, types, i); 1433 1420 } 1434 1421 … … 1437 1424 } 1438 1425 case op_construct_verify: { 1439 __ link(iter->from, __ label());1440 __ link((++iter)->from, __ label());1426 linkSlowCase(iter); 1427 linkSlowCase(iter); 1441 1428 emitGetVirtualRegister(instruction[i + 2].u.operand, X86::eax, i); 1442 1429 emitPutVirtualRegister(instruction[i + 1].u.operand); … … 1447 1434 case op_get_by_val: { 1448 1435 // The slow case that handles accesses to arrays (below) may jump back up to here. 1449 JmpDst beginGetByValSlow = __ label();1450 1451 J mpSrc notImm = iter->from;1452 __ link((++iter)->from, __ label());1453 __ link((++iter)->from, __ label());1436 Label beginGetByValSlow(this); 1437 1438 Jump notImm = getSlowCase(iter); 1439 linkSlowCase(iter); 1440 linkSlowCase(iter); 1454 1441 emitFastArithIntToImmNoCheck(X86::edx); 1455 __ link(notImm, __ label());1442 notImm.link(this); 1456 1443 emitPutCTIArg(X86::eax, 0); 1457 1444 emitPutCTIArg(X86::edx, 4); 1458 1445 emitCTICall(i, Interpreter::cti_op_get_by_val); 1459 1446 emitPutVirtualRegister(instruction[i + 1].u.operand); 1460 __ link( __ jmp(), m_labels[i + 4]);1447 __ link(jump(), m_labels[i + 4]); 1461 1448 1462 1449 // This is slow case that handles accesses to arrays above the fast cut-off. 1463 1450 // First, check if this is an access to the vector 1464 __ link((++iter)->from, __ label()); 1465 __ cmpl_rm(X86::edx, FIELD_OFFSET(ArrayStorage, m_vectorLength), X86::ecx); 1466 __ link(__ jbe(), beginGetByValSlow); 1451 linkSlowCase(iter); 1452 jae32(X86::edx, Address(X86::ecx, FIELD_OFFSET(ArrayStorage, m_vectorLength)), beginGetByValSlow); 1467 1453 1468 1454 // okay, missed the fast region, but it is still in the vector. Get the value. 1469 __ movl_mr(FIELD_OFFSET(ArrayStorage, m_vector[0]), X86::ecx, X86::edx, sizeof(JSValue*), X86::ecx);1455 loadPtr(BaseIndex(X86::ecx, X86::edx, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])), X86::ecx); 1470 1456 // Check whether the value loaded is zero; if so we need to return undefined. 1471 __ testl_rr(X86::ecx, X86::ecx); 1472 __ link(__ je(), beginGetByValSlow); 1473 __ movl_rr(X86::ecx, X86::eax); 1457 jzPtr(X86::ecx, beginGetByValSlow); 1458 move(X86::ecx, X86::eax); 1474 1459 emitPutVirtualRegister(instruction[i + 1].u.operand, X86::eax); 1475 1460 … … 1484 1469 case op_rshift: { 1485 1470 unsigned src2 = instruction[i + 3].u.operand; 1486 __ link(iter->from, __ label());1471 linkSlowCase(iter); 1487 1472 if (getConstantImmediateNumericArg(src2)) 1488 1473 emitPutCTIArgFromVirtualRegister(src2, 4, X86::ecx); 1489 1474 else { 1490 __ link((++iter)->from, __ label());1475 linkSlowCase(iter); 1491 1476 emitPutCTIArg(X86::ecx, 4); 1492 1477 } … … 1499 1484 } 1500 1485 case op_lshift: { 1501 J mpSrc notImm1 = iter->from;1502 J mpSrc notImm2 = (++iter)->from;1503 __ link((++iter)->from, __ label());1486 Jump notImm1 = getSlowCase(iter); 1487 Jump notImm2 = getSlowCase(iter); 1488 linkSlowCase(iter); 1504 1489 emitGetVirtualRegisters(instruction[i + 2].u.operand, X86::eax, instruction[i + 3].u.operand, X86::ecx, i); 1505 __ link(notImm1, __ label());1506 __ link(notImm2, __ label());1490 notImm1.link(this); 1491 notImm2.link(this); 1507 1492 emitPutCTIArg(X86::eax, 0); 1508 1493 emitPutCTIArg(X86::ecx, 4); … … 1516 1501 JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand); 1517 1502 if (src2imm) { 1518 __ link(iter->from, __ label());1503 linkSlowCase(iter); 1519 1504 emitPutCTIArg(X86::eax, 0); 1520 1505 emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 4, X86::ecx); 1521 1506 emitCTICall(i, Interpreter::cti_op_loop_if_less); 1522 __ testl_rr(X86::eax, X86::eax); 1523 __ link(__ jne(), m_labels[i + 3 + target]); 1507 __ link(jnz32(X86::eax), m_labels[i + 3 + target]); 1524 1508 } else { 1525 __ link(iter->from, __ label());1526 __ link((++iter)->from, __ label());1509 linkSlowCase(iter); 1510 linkSlowCase(iter); 1527 1511 emitPutCTIArg(X86::eax, 0); 1528 1512 emitPutCTIArg(X86::edx, 4); 1529 1513 emitCTICall(i, Interpreter::cti_op_loop_if_less); 1530 __ testl_rr(X86::eax, X86::eax); 1531 __ link(__ jne(), m_labels[i + 3 + target]); 1514 __ link(jnz32(X86::eax), m_labels[i + 3 + target]); 1532 1515 } 1533 1516 i += OPCODE_LENGTH(op_loop_if_less); … … 1548 1531 JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand); 1549 1532 if (src2imm) { 1550 __ link(iter->from, __ label());1533 linkSlowCase(iter); 1551 1534 emitPutCTIArg(X86::eax, 0); 1552 1535 emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 4, X86::ecx); 1553 1536 emitCTICall(i, Interpreter::cti_op_loop_if_lesseq); 1554 __ testl_rr(X86::eax, X86::eax); 1555 __ link(__ jne(), m_labels[i + 3 + target]); 1537 __ link(jnz32(X86::eax), m_labels[i + 3 + target]); 1556 1538 } else { 1557 __ link(iter->from, __ label());1558 __ link((++iter)->from, __ label());1539 linkSlowCase(iter); 1540 linkSlowCase(iter); 1559 1541 emitPutCTIArg(X86::eax, 0); 1560 1542 emitPutCTIArg(X86::edx, 4); 1561 1543 emitCTICall(i, Interpreter::cti_op_loop_if_lesseq); 1562 __ testl_rr(X86::eax, X86::eax); 1563 __ link(__ jne(), m_labels[i + 3 + target]); 1544 __ link(jnz32(X86::eax), m_labels[i + 3 + target]); 1564 1545 } 1565 1546 i += OPCODE_LENGTH(op_loop_if_lesseq); … … 1568 1549 case op_pre_inc: { 1569 1550 unsigned srcDst = instruction[i + 1].u.operand; 1570 J mpSrc notImm = iter->from;1571 __ link((++iter)->from, __ label());1572 __ subl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::eax);1573 __ link(notImm, __ label());1551 Jump notImm = getSlowCase(iter); 1552 linkSlowCase(iter); 1553 sub32(Imm32(getDeTaggedConstantImmediate(JSImmediate::oneImmediate())), X86::eax); 1554 notImm.link(this); 1574 1555 emitPutCTIArg(X86::eax, 0); 1575 1556 emitCTICall(i, Interpreter::cti_op_pre_inc); … … 1580 1561 case op_put_by_val: { 1581 1562 // Normal slow cases - either is not an immediate imm, or is an array. 1582 J mpSrc notImm = iter->from;1583 __ link((++iter)->from, __ label());1584 __ link((++iter)->from, __ label());1563 Jump notImm = getSlowCase(iter); 1564 linkSlowCase(iter); 1565 linkSlowCase(iter); 1585 1566 emitFastArithIntToImmNoCheck(X86::edx); 1586 __ link(notImm, __ label());1567 notImm.link(this); 1587 1568 emitGetVirtualRegister(instruction[i + 3].u.operand, X86::ecx, i); 1588 1569 emitPutCTIArg(X86::eax, 0); … … 1590 1571 emitPutCTIArg(X86::ecx, 8); 1591 1572 emitCTICall(i, Interpreter::cti_op_put_by_val); 1592 __ link( __ jmp(), m_labels[i + 4]);1573 __ link(jump(), m_labels[i + 4]); 1593 1574 1594 1575 // slow cases for immediate int accesses to arrays 1595 __ link((++iter)->from, __ label());1596 __ link((++iter)->from, __ label());1576 linkSlowCase(iter); 1577 linkSlowCase(iter); 1597 1578 emitGetVirtualRegister(instruction[i + 3].u.operand, X86::ecx, i); 1598 1579 emitPutCTIArg(X86::eax, 0); … … 1605 1586 } 1606 1587 case op_loop_if_true: { 1607 __ link(iter->from, __ label());1588 linkSlowCase(iter); 1608 1589 emitPutCTIArg(X86::eax, 0); 1609 1590 emitCTICall(i, Interpreter::cti_op_jtrue); 1610 __ testl_rr(X86::eax, X86::eax);1611 1591 unsigned target = instruction[i + 2].u.operand; 1612 __ link( __ jne(), m_labels[i + 2 + target]);1592 __ link(jnz32(X86::eax), m_labels[i + 2 + target]); 1613 1593 i += OPCODE_LENGTH(op_loop_if_true); 1614 1594 break; … … 1616 1596 case op_pre_dec: { 1617 1597 unsigned srcDst = instruction[i + 1].u.operand; 1618 J mpSrc notImm = iter->from;1619 __ link((++iter)->from, __ label());1620 __ addl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::eax);1621 __ link(notImm, __ label());1598 Jump notImm = getSlowCase(iter); 1599 linkSlowCase(iter); 1600 add32(Imm32(getDeTaggedConstantImmediate(JSImmediate::oneImmediate())), X86::eax); 1601 notImm.link(this); 1622 1602 emitPutCTIArg(X86::eax, 0); 1623 1603 emitCTICall(i, Interpreter::cti_op_pre_dec); … … 1630 1610 JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand); 1631 1611 if (src2imm) { 1632 __ link(iter->from, __ label());1612 linkSlowCase(iter); 1633 1613 emitPutCTIArg(X86::edx, 0); 1634 1614 emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 4, X86::ecx); 1635 1615 emitCTICall(i, Interpreter::cti_op_jless); 1636 __ testl_rr(X86::eax, X86::eax); 1637 __ link(__ je(), m_labels[i + 3 + target]); 1616 __ link(jz32(X86::eax), m_labels[i + 3 + target]); 1638 1617 } else { 1639 __ link(iter->from, __ label());1640 __ link((++iter)->from, __ label());1618 linkSlowCase(iter); 1619 linkSlowCase(iter); 1641 1620 emitPutCTIArg(X86::eax, 0); 1642 1621 emitPutCTIArg(X86::edx, 4); 1643 1622 emitCTICall(i, Interpreter::cti_op_jless); 1644 __ testl_rr(X86::eax, X86::eax); 1645 __ link(__ je(), m_labels[i + 3 + target]); 1623 __ link(jz32(X86::eax), m_labels[i + 3 + target]); 1646 1624 } 1647 1625 i += OPCODE_LENGTH(op_jnless); … … 1649 1627 } 1650 1628 case op_not: { 1651 __ link(iter->from, __ label());1652 __ xorl_i8r(JSImmediate::FullTagTypeBool, X86::eax);1629 linkSlowCase(iter); 1630 xor32(Imm32(JSImmediate::FullTagTypeBool), X86::eax); 1653 1631 emitPutCTIArg(X86::eax, 0); 1654 1632 emitCTICall(i, Interpreter::cti_op_not); … … 1658 1636 } 1659 1637 case op_jfalse: { 1660 __ link(iter->from, __ label());1638 linkSlowCase(iter); 1661 1639 emitPutCTIArg(X86::eax, 0); 1662 1640 emitCTICall(i, Interpreter::cti_op_jtrue); 1663 __ testl_rr(X86::eax, X86::eax);1664 1641 unsigned target = instruction[i + 2].u.operand; 1665 __ link( __ je(), m_labels[i + 2 + target]); // inverted!1642 __ link(jz32(X86::eax), m_labels[i + 2 + target]); // inverted! 1666 1643 i += OPCODE_LENGTH(op_jfalse); 1667 1644 break; … … 1669 1646 case op_post_inc: { 1670 1647 unsigned srcDst = instruction[i + 2].u.operand; 1671 __ link(iter->from, __ label());1672 __ link((++iter)->from, __ label());1648 linkSlowCase(iter); 1649 linkSlowCase(iter); 1673 1650 emitPutCTIArg(X86::eax, 0); 1674 1651 emitCTICall(i, Interpreter::cti_op_post_inc); … … 1679 1656 } 1680 1657 case op_bitnot: { 1681 __ link(iter->from, __ label());1658 linkSlowCase(iter); 1682 1659 emitPutCTIArg(X86::eax, 0); 1683 1660 emitCTICall(i, Interpreter::cti_op_bitnot); … … 1687 1664 } 1688 1665 case op_bitand: { 1666 linkSlowCase(iter); 1689 1667 unsigned src1 = instruction[i + 2].u.operand; 1690 1668 unsigned src2 = instruction[i + 3].u.operand; 1691 1669 unsigned dst = instruction[i + 1].u.operand; 1692 1670 if (getConstantImmediateNumericArg(src1)) { 1693 __ link(iter->from, __ label());1694 1671 emitPutCTIArgFromVirtualRegister(src1, 0, X86::ecx); 1695 1672 emitPutCTIArg(X86::eax, 4); … … 1697 1674 emitPutVirtualRegister(dst); 1698 1675 } else if (getConstantImmediateNumericArg(src2)) { 1699 __ link(iter->from, __ label());1700 1676 emitPutCTIArg(X86::eax, 0); 1701 1677 emitPutCTIArgFromVirtualRegister(src2, 4, X86::ecx); … … 1703 1679 emitPutVirtualRegister(dst); 1704 1680 } else { 1705 __ link(iter->from, __ label());1706 1681 emitPutCTIArgFromVirtualRegister(src1, 0, X86::ecx); 1707 1682 emitPutCTIArg(X86::edx, 4); … … 1713 1688 } 1714 1689 case op_jtrue: { 1715 __ link(iter->from, __ label());1690 linkSlowCase(iter); 1716 1691 emitPutCTIArg(X86::eax, 0); 1717 1692 emitCTICall(i, Interpreter::cti_op_jtrue); 1718 __ testl_rr(X86::eax, X86::eax);1719 1693 unsigned target = instruction[i + 2].u.operand; 1720 __ link( __ jne(), m_labels[i + 2 + target]);1694 __ link(jnz32(X86::eax), m_labels[i + 2 + target]); 1721 1695 i += OPCODE_LENGTH(op_jtrue); 1722 1696 break; … … 1724 1698 case op_post_dec: { 1725 1699 unsigned srcDst = instruction[i + 2].u.operand; 1726 __ link(iter->from, __ label());1727 __ link((++iter)->from, __ label());1700 linkSlowCase(iter); 1701 linkSlowCase(iter); 1728 1702 emitPutCTIArg(X86::eax, 0); 1729 1703 emitCTICall(i, Interpreter::cti_op_post_dec); … … 1734 1708 } 1735 1709 case op_bitxor: { 1736 __ link(iter->from, __ label());1710 linkSlowCase(iter); 1737 1711 emitPutCTIArg(X86::eax, 0); 1738 1712 emitPutCTIArg(X86::edx, 4); … … 1743 1717 } 1744 1718 case op_bitor: { 1745 __ link(iter->from, __ label());1719 linkSlowCase(iter); 1746 1720 emitPutCTIArg(X86::eax, 0); 1747 1721 emitPutCTIArg(X86::edx, 4); … … 1752 1726 } 1753 1727 case op_eq: { 1754 __ link(iter->from, __ label());1728 linkSlowCase(iter); 1755 1729 emitPutCTIArg(X86::eax, 0); 1756 1730 emitPutCTIArg(X86::edx, 4); … … 1761 1735 } 1762 1736 case op_neq: { 1763 __ link(iter->from, __ label());1737 linkSlowCase(iter); 1764 1738 emitPutCTIArg(X86::eax, 0); 1765 1739 emitPutCTIArg(X86::edx, 4); … … 1770 1744 } 1771 1745 case op_stricteq: { 1772 __ link(iter->from, __ label());1773 __ link((++iter)->from, __ label());1774 __ link((++iter)->from, __ label());1746 linkSlowCase(iter); 1747 linkSlowCase(iter); 1748 linkSlowCase(iter); 1775 1749 emitPutCTIArg(X86::eax, 0); 1776 1750 emitPutCTIArg(X86::edx, 4); … … 1781 1755 } 1782 1756 case op_nstricteq: { 1783 __ link(iter->from, __ label());1784 __ link((++iter)->from, __ label());1785 __ link((++iter)->from, __ label());1757 linkSlowCase(iter); 1758 linkSlowCase(iter); 1759 linkSlowCase(iter); 1786 1760 emitPutCTIArg(X86::eax, 0); 1787 1761 emitPutCTIArg(X86::edx, 4); … … 1792 1766 } 1793 1767 case op_instanceof: { 1794 __ link(iter->from, __ label());1795 __ link((++iter)->from, __ label());1796 __ link((++iter)->from, __ label());1768 linkSlowCase(iter); 1769 linkSlowCase(iter); 1770 linkSlowCase(iter); 1797 1771 emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 0, X86::ecx); 1798 1772 emitPutCTIArgFromVirtualRegister(instruction[i + 3].u.operand, 4, X86::ecx); … … 1804 1778 } 1805 1779 case op_mod: { 1806 J mpSrc notImm1 = iter->from;1807 J mpSrc notImm2 = (++iter)->from;1808 __ link((++iter)->from, __ label());1780 Jump notImm1 = getSlowCase(iter); 1781 Jump notImm2 = getSlowCase(iter); 1782 linkSlowCase(iter); 1809 1783 emitFastArithReTagImmediate(X86::eax); 1810 1784 emitFastArithReTagImmediate(X86::ecx); 1811 __ link(notImm1, __ label());1812 __ link(notImm2, __ label());1785 notImm1.link(this); 1786 notImm2.link(this); 1813 1787 emitPutCTIArg(X86::eax, 0); 1814 1788 emitPutCTIArg(X86::ecx, 4); … … 1826 1800 int32_t value; 1827 1801 if (src1Value && ((value = JSImmediate::intValue(src1Value)) > 0)) { 1828 __ link(iter->from, __ label());1829 __ link((++iter)->from, __ label());1802 linkSlowCase(iter); 1803 linkSlowCase(iter); 1830 1804 // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0. 1831 1805 emitPutCTIArgFromVirtualRegister(src1, 0, X86::ecx); … … 1834 1808 emitPutVirtualRegister(dst); 1835 1809 } else if (src2Value && ((value = JSImmediate::intValue(src2Value)) > 0)) { 1836 __ link(iter->from, __ label());1837 __ link((++iter)->from, __ label());1810 linkSlowCase(iter); 1811 linkSlowCase(iter); 1838 1812 // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0. 1839 1813 emitPutCTIArgFromVirtualRegister(src1, 0, X86::ecx); … … 1855 1829 } 1856 1830 case op_to_jsnumber: { 1857 if (linkSlowCaseIfNotJSCell(iter, instruction[i + 2].u.operand)) 1858 ++iter; 1859 __ link(iter->from, __ label()); 1831 linkSlowCaseIfNotJSCell(iter, instruction[i + 2].u.operand); 1832 linkSlowCase(iter); 1860 1833 1861 1834 emitPutCTIArg(X86::eax, 0); … … 1872 1845 } 1873 1846 1874 ASSERT_WITH_MESSAGE( (iter + 1) == m_slowCases.end() || firstTo != (iter + 1)->to,"Not enough jumps linked in slow case codegen.");1875 ASSERT_WITH_MESSAGE(firstTo == iter->to, "Too many jumps linked in slow case codegen.");1876 1877 __ link( __ jmp(), m_labels[i]);1847 ASSERT_WITH_MESSAGE(iter == m_slowCases.end() || firstTo != iter->to,"Not enough jumps linked in slow case codegen."); 1848 ASSERT_WITH_MESSAGE(firstTo == (iter - 1)->to, "Too many jumps linked in slow case codegen."); 1849 1850 __ link(jump(), m_labels[i]); 1878 1851 } 1879 1852 … … 1885 1858 { 1886 1859 #if ENABLE(CODEBLOCK_SAMPLING) 1887 __ movl_i32m(reinterpret_cast<unsigned>(m_codeBlock), m_interpreter->sampler()->codeBlockSlot());1860 storePtr(ImmPtr(m_codeBlock), m_interpreter->sampler()->codeBlockSlot()); 1888 1861 #endif 1889 1862 #if ENABLE(OPCODE_SAMPLING) 1890 __ movl_i32m(m_interpreter->sampler()->encodeSample(m_codeBlock->instructions().begin()), m_interpreter->sampler()->sampleSlot());1863 store32(Imm32(m_interpreter->sampler()->encodeSample(m_codeBlock->instructions().begin())), m_interpreter->sampler()->sampleSlot()); 1891 1864 #endif 1892 1865 … … 1895 1868 emitPutToCallFrameHeader(X86::ecx, RegisterFile::ReturnPC); 1896 1869 1897 J mpSrcslowRegisterFileCheck;1898 JmpDstafterRegisterFileCheck;1870 Jump slowRegisterFileCheck; 1871 Label afterRegisterFileCheck; 1899 1872 if (m_codeBlock->codeType() == FunctionCode) { 1900 1873 // In the case of a fast linked call, we do not set this up in the caller. … … 1903 1876 emitGetCTIParam(CTI_ARGS_registerFile, X86::eax); 1904 1877 __ leal_mr(m_codeBlock->m_numCalleeRegisters * sizeof(Register), X86::edi, X86::edx); 1905 __ cmpl_mr(FIELD_OFFSET(RegisterFile, m_end), X86::eax, X86::edx); 1906 slowRegisterFileCheck = __ jg(); 1907 afterRegisterFileCheck = __ label(); 1878 slowRegisterFileCheck = jg32(X86::edx, Address(X86::eax, FIELD_OFFSET(RegisterFile, m_end))); 1879 afterRegisterFileCheck = Label(this); 1908 1880 } 1909 1881 … … 1913 1885 1914 1886 if (m_codeBlock->codeType() == FunctionCode) { 1915 __ link(slowRegisterFileCheck, __ label());1887 slowRegisterFileCheck.link(this); 1916 1888 emitCTICall(0, Interpreter::cti_register_file_check); 1917 JmpSrc backToBody = __ jmp(); 1918 __ link(backToBody, afterRegisterFileCheck); 1889 jump(afterRegisterFileCheck); 1919 1890 } 1920 1891 … … 2171 2142 void JIT::emitGetVariableObjectRegister(RegisterID variableObject, int index, RegisterID dst) 2172 2143 { 2173 __ movl_mr(FIELD_OFFSET(JSVariableObject, d), variableObject, dst);2174 __ movl_mr(FIELD_OFFSET(JSVariableObject::JSVariableObjectData, registers), dst, dst);2175 __ movl_mr(index * sizeof(Register), dst, dst);2144 loadPtr(Address(variableObject, FIELD_OFFSET(JSVariableObject, d)), dst); 2145 loadPtr(Address(dst, FIELD_OFFSET(JSVariableObject::JSVariableObjectData, registers)), dst); 2146 loadPtr(Address(dst, index * sizeof(Register)), dst); 2176 2147 } 2177 2148 2178 2149 void JIT::emitPutVariableObjectRegister(RegisterID src, RegisterID variableObject, int index) 2179 2150 { 2180 __ movl_mr(FIELD_OFFSET(JSVariableObject, d), variableObject, variableObject);2181 __ movl_mr(FIELD_OFFSET(JSVariableObject::JSVariableObjectData, registers), variableObject, variableObject);2182 __ movl_rm(src, index * sizeof(Register), variableObject);2151 loadPtr(Address(variableObject, FIELD_OFFSET(JSVariableObject, d)), variableObject); 2152 loadPtr(Address(variableObject, FIELD_OFFSET(JSVariableObject::JSVariableObjectData, registers)), variableObject); 2153 storePtr(src, Address(variableObject, index * sizeof(Register))); 2183 2154 } 2184 2155 -
trunk/JavaScriptCore/jit/JIT.h
r39226 r39261 194 194 195 195 struct SlowCaseEntry { 196 typedef X86Assembler::JmpSrc JmpSrc; 197 198 JmpSrc from; 196 MacroAssembler::Jump from; 199 197 unsigned to; 200 198 unsigned hint; 201 199 202 SlowCaseEntry( JmpSrcf, unsigned t, unsigned h = 0)200 SlowCaseEntry(MacroAssembler::Jump f, unsigned t, unsigned h = 0) 203 201 : from(f) 204 202 , to(t) … … 434 432 void emitJumpSlowCaseIfNotJSCell(RegisterID, unsigned bytecodeIndex); 435 433 void emitJumpSlowCaseIfNotJSCell(RegisterID, unsigned bytecodeIndex, int VReg); 436 bool linkSlowCaseIfNotJSCell(const Vector<SlowCaseEntry>::iterator&, int vReg); 434 435 Jump getSlowCase(Vector<SlowCaseEntry>::iterator& iter) 436 { 437 return iter++->from; 438 } 439 void linkSlowCase(Vector<SlowCaseEntry>::iterator& iter) 440 { 441 iter->from.link(this); 442 ++iter; 443 } 444 void linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator&, int vReg); 437 445 438 446 void emitJumpSlowCaseIfNotImmNum(RegisterID, unsigned bytecodeIndex); -
trunk/JavaScriptCore/jit/JITArithmetic.cpp
r39020 r39261 298 298 void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned dst, unsigned src1, unsigned src2, OperandTypes types, unsigned i) 299 299 { 300 JmpDst here = __ label(); 301 __ link(iter->from, here); 300 linkSlowCase(iter); 302 301 if (types.second().isReusable() && isSSE2Present()) { 303 302 if (!types.first().definitelyIsNumber()) { 304 if (linkSlowCaseIfNotJSCell(++iter, src1)) 305 ++iter; 306 __ link(iter->from, here); 303 linkSlowCaseIfNotJSCell(iter, src1); 304 linkSlowCase(iter); 307 305 } 308 306 if (!types.second().definitelyIsNumber()) { 309 if (linkSlowCaseIfNotJSCell(++iter, src2)) 310 ++iter; 311 __ link(iter->from, here); 312 } 313 __ link((++iter)->from, here); 307 linkSlowCaseIfNotJSCell(iter, src2); 308 linkSlowCase(iter); 309 } 314 310 } else if (types.first().isReusable() && isSSE2Present()) { 315 311 if (!types.first().definitelyIsNumber()) { 316 if (linkSlowCaseIfNotJSCell(++iter, src1)) 317 ++iter; 318 __ link(iter->from, here); 312 linkSlowCaseIfNotJSCell(iter, src1); 313 linkSlowCase(iter); 319 314 } 320 315 if (!types.second().definitelyIsNumber()) { 321 if (linkSlowCaseIfNotJSCell(++iter, src2)) 322 ++iter; 323 __ link(iter->from, here); 324 } 325 __ link((++iter)->from, here); 326 } else 327 __ link((++iter)->from, here); 316 linkSlowCaseIfNotJSCell(iter, src2); 317 linkSlowCase(iter); 318 } 319 } 320 linkSlowCase(iter); 328 321 329 322 // additional entry point to handle -0 cases. 330 323 if (opcodeID == op_mul) 331 __ link((++iter)->from, here);324 linkSlowCase(iter); 332 325 333 326 emitPutCTIArgFromVirtualRegister(src1, 0, X86::ecx); -
trunk/JavaScriptCore/jit/JITCall.cpp
r39070 r39261 72 72 void JIT::compileOpCallInitializeCallFrame() 73 73 { 74 __ movl_rm(X86::edx, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register)), X86::edi);75 76 __ movl_mr(FIELD_OFFSET(JSFunction, m_scopeChain) + FIELD_OFFSET(ScopeChain, m_node), X86::ecx, X86::edx); // newScopeChain77 78 __ movl_i32m(asInteger(noValue()), RegisterFile::OptionalCalleeArguments * static_cast<int>(sizeof(Register)), X86::edi);79 __ movl_rm(X86::ecx, RegisterFile::Callee * static_cast<int>(sizeof(Register)), X86::edi);80 __ movl_rm(X86::edx, RegisterFile::ScopeChain * static_cast<int>(sizeof(Register)), X86::edi);74 store32(X86::edx, Address(X86::edi, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register)))); 75 76 loadPtr(Address(X86::ecx, FIELD_OFFSET(JSFunction, m_scopeChain) + FIELD_OFFSET(ScopeChain, m_node)), X86::edx); // newScopeChain 77 78 storePtr(ImmPtr(noValue()), Address(X86::edi, RegisterFile::OptionalCalleeArguments * static_cast<int>(sizeof(Register)))); 79 storePtr(X86::ecx, Address(X86::edi, RegisterFile::Callee * static_cast<int>(sizeof(Register)))); 80 storePtr(X86::edx, Address(X86::edi, RegisterFile::ScopeChain * static_cast<int>(sizeof(Register)))); 81 81 } 82 82 … … 131 131 132 132 // Handle eval 133 J mpSrcwasEval;133 Jump wasEval; 134 134 if (opcodeID == op_call_eval) { 135 135 emitGetVirtualRegister(callee, X86::ecx, i); … … 137 137 138 138 emitCTICall(i, Interpreter::cti_op_call_eval); 139 __ cmpl_i32r(asInteger(JSImmediate::impossibleValue()), X86::eax); 140 wasEval = __ jne(); 139 wasEval = jnePtr(ImmPtr(JSImmediate::impossibleValue()), X86::eax); 141 140 } 142 141 … … 150 149 // Check for JSFunctions. 151 150 emitJumpSlowCaseIfNotJSCell(X86::ecx, i); 152 __ cmpl_i32m(reinterpret_cast<unsigned>(m_interpreter->m_jsFunctionVptr), X86::ecx); 153 m_slowCases.append(SlowCaseEntry(__ jne(), i)); 151 m_slowCases.append(SlowCaseEntry(jnePtr(X86::ecx, ImmPtr(m_interpreter->m_jsFunctionVptr)), i)); 154 152 155 153 // First, in the case of a construct, allocate the new object. … … 161 159 162 160 // Speculatively roll the callframe, assuming argCount will match the arity. 163 __ movl_rm(X86::edi, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register)), X86::edi);164 __ addl_i32r(registerOffset * static_cast<int>(sizeof(Register)), X86::edi);165 __ movl_i32r(argCount, X86::edx);161 storePtr(X86::edi, Address(X86::edi, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register)))); 162 addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), X86::edi); 163 move(Imm32(argCount), X86::edx); 166 164 167 165 emitNakedCall(i, m_interpreter->m_ctiVirtualCall); 168 166 169 167 if (opcodeID == op_call_eval) 170 __ link(wasEval, __ label());168 wasEval.link(this); 171 169 172 170 // Put the return value in dst. In the interpreter, op_ret does this. … … 174 172 175 173 #if ENABLE(CODEBLOCK_SAMPLING) 176 __ movl_i32m(reinterpret_cast<unsigned>(m_codeBlock), m_interpreter->sampler()->codeBlockSlot());174 storePtr(ImmPtr(m_codeBlock), m_interpreter->sampler()->codeBlockSlot()); 177 175 #endif 178 176 } … … 182 180 int dst = instruction[1].u.operand; 183 181 184 __ link(iter->from, __ label());185 __ link((++iter)->from, __ label());182 linkSlowCase(iter); 183 linkSlowCase(iter); 186 184 187 185 // This handles host functions … … 191 189 192 190 #if ENABLE(CODEBLOCK_SAMPLING) 193 __ movl_i32m(reinterpret_cast<unsigned>(m_codeBlock), m_interpreter->sampler()->codeBlockSlot());191 storePtr(ImmPtr(m_codeBlock), m_interpreter->sampler()->codeBlockSlot()); 194 192 #endif 195 193 } … … 275 273 int registerOffset = instruction[4].u.operand; 276 274 277 __ link(iter->from, __ label());275 linkSlowCase(iter); 278 276 279 277 // The arguments have been set up on the hot path for op_call_eval -
trunk/JavaScriptCore/jit/JITInlineMethods.h
r39226 r39261 341 341 ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotJSCell(RegisterID reg, unsigned bytecodeIndex, int vReg) 342 342 { 343 if (m_codeBlock->isKnownNotImmediate(vReg)) 344 return; 345 346 emitJumpSlowCaseIfNotJSCell(reg, bytecodeIndex); 347 } 348 349 ALWAYS_INLINE bool JIT::linkSlowCaseIfNotJSCell(const Vector<SlowCaseEntry>::iterator& iter, int vReg) 350 { 351 if (m_codeBlock->isKnownNotImmediate(vReg)) 352 return false; 353 354 __ link(iter->from, __ label()); 355 return true; 343 if (!m_codeBlock->isKnownNotImmediate(vReg)) 344 emitJumpSlowCaseIfNotJSCell(reg, bytecodeIndex); 345 } 346 347 ALWAYS_INLINE void JIT::linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator& iter, int vReg) 348 { 349 if (!m_codeBlock->isKnownNotImmediate(vReg)) 350 linkSlowCase(iter); 356 351 } 357 352 -
trunk/JavaScriptCore/jit/JITPropertyAccess.cpp
r39229 r39261 47 47 #if !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) 48 48 49 void JIT::compileGetByIdHotPath(int resultVReg, int baseVReg, Identifier* ident, unsigned i, unsigned propertyAccessInstructionIndex)49 void JIT::compileGetByIdHotPath(int resultVReg, int baseVReg, Identifier* ident, unsigned i, unsigned) 50 50 { 51 51 // As for put_by_id, get_by_id requires the offset of the Structure and the offset of the access to be repatched. … … 56 56 emitGetVirtualRegister(baseVReg, X86::eax, i); 57 57 58 #ifdef NDEBUG59 UNUSED_PARAM(propertyAccessInstructionIndex);60 #endif61 62 #ifndef NDEBUG63 JmpDst coldPathBegin = __ label();64 #endif65 58 emitPutCTIArg(X86::eax, 0); 66 59 emitPutCTIArgConstant(reinterpret_cast<unsigned>(ident), 4); 67 JmpSrc call = emitCTICall(i, Interpreter::cti_op_get_by_id_generic); 68 ASSERT(X86Assembler::getDifferenceBetweenLabels(coldPathBegin, call) == repatchOffsetGetByIdSlowCaseCall); 60 emitCTICall(i, Interpreter::cti_op_get_by_id_generic); 69 61 emitPutVirtualRegister(resultVReg); 70 71 // Track the location of the call; this will be used to recover repatch information.72 m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].callReturnLocation = call;73 62 } 74 63 … … 79 68 } 80 69 81 void JIT::compilePutByIdHotPath(int baseVReg, Identifier* ident, int valueVReg, unsigned i, unsigned propertyAccessInstructionIndex)70 void JIT::compilePutByIdHotPath(int baseVReg, Identifier* ident, int valueVReg, unsigned i, unsigned) 82 71 { 83 72 // In order to be able to repatch both the Structure, and the object offset, we store one pointer, … … 90 79 emitPutCTIArg(X86::eax, 0); 91 80 emitPutCTIArg(X86::edx, 8); 92 JmpSrc call = emitCTICall(i, Interpreter::cti_op_put_by_id_generic); 93 94 // Track the location of the call; this will be used to recover repatch information. 95 m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].callReturnLocation = call; 81 emitCTICall(i, Interpreter::cti_op_put_by_id_generic); 96 82 } 97 83 … … 137 123 // the distance from the call to the head of the slow case. 138 124 139 if (linkSlowCaseIfNotJSCell(iter, baseVReg)) 140 ++iter; 141 __ link(iter->from, __ label()); 125 linkSlowCaseIfNotJSCell(iter, baseVReg); 126 linkSlowCase(iter); 142 127 143 128 #ifndef NDEBUG … … 181 166 void JIT::compilePutByIdSlowCase(int baseVReg, Identifier* ident, int, unsigned i, Vector<SlowCaseEntry>::iterator& iter, unsigned propertyAccessInstructionIndex) 182 167 { 183 if (linkSlowCaseIfNotJSCell(iter, baseVReg)) 184 ++iter; 185 __ link(iter->from, __ label()); 168 linkSlowCaseIfNotJSCell(iter, baseVReg); 169 linkSlowCase(iter); 186 170 187 171 emitPutCTIArgConstant(reinterpret_cast<unsigned>(ident), 4);
Note:
See TracChangeset
for help on using the changeset viewer.