1472 } |
1472 } |
1473 |
1473 |
1474 sd(last_java_sp, Address(thread, JavaThread::last_Java_sp_offset())); |
1474 sd(last_java_sp, Address(thread, JavaThread::last_Java_sp_offset())); |
1475 } |
1475 } |
1476 |
1476 |
|
1477 |
1477 ////////////////////////////////////////////////////////////////////////////////// |
1478 ////////////////////////////////////////////////////////////////////////////////// |
1478 #if INCLUDE_ALL_GCS |
1479 #if INCLUDE_ALL_GCS |
1479 |
1480 |
1480 void MacroAssembler::g1_write_barrier_pre(Register obj, |
1481 void MacroAssembler::g1_write_barrier_pre(Register obj, |
1481 #ifndef _LP64 |
1482 Register pre_val, |
1482 Register thread, |
1483 Register thread, |
1483 #endif |
|
1484 Register tmp, |
1484 Register tmp, |
1485 Register tmp2, |
1485 bool tosca_live, |
1486 bool tosca_live) { |
1486 bool expand_call) { |
1487 Unimplemented(); |
1487 |
|
1488 // If expand_call is true then we expand the call_VM_leaf macro |
|
1489 // directly to skip generating the check by |
|
1490 // InterpreterMacroAssembler::call_VM_leaf_base that checks _last_sp. |
|
1491 |
|
1492 #ifdef _LP64 |
|
1493 assert(thread == TREG, "must be"); |
|
1494 #endif // _LP64 |
|
1495 |
|
1496 Label done; |
|
1497 Label runtime; |
|
1498 |
|
1499 assert(pre_val != noreg, "check this code"); |
|
1500 |
|
1501 if (obj != noreg) { |
|
1502 assert_different_registers(obj, pre_val, tmp); |
|
1503 assert(pre_val != V0, "check this code"); |
|
1504 } |
|
1505 |
|
1506 Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() + |
|
1507 PtrQueue::byte_offset_of_active())); |
|
1508 Address index(thread, in_bytes(JavaThread::satb_mark_queue_offset() + |
|
1509 PtrQueue::byte_offset_of_index())); |
|
1510 Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() + |
|
1511 PtrQueue::byte_offset_of_buf())); |
|
1512 |
|
1513 |
|
1514 // Is marking active? |
|
1515 if (in_bytes(PtrQueue::byte_width_of_active()) == 4) { |
|
1516 //cmpl(in_progress, 0); |
|
1517 lw(AT, in_progress); |
|
1518 } else { |
|
1519 assert(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption"); |
|
1520 //cmpb(in_progress, 0); |
|
1521 lb(AT, in_progress); |
|
1522 } |
|
1523 //jcc(Assembler::equal, done); |
|
1524 beq(AT, R0, done); |
|
1525 nop(); |
|
1526 |
|
1527 // Do we need to load the previous value? |
|
1528 if (obj != noreg) { |
|
1529 load_heap_oop(pre_val, Address(obj, 0)); |
|
1530 } |
|
1531 |
|
1532 // Is the previous value null? |
|
1533 //cmpptr(pre_val, (int32_t) NULL_WORD); |
|
1534 //jcc(Assembler::equal, done); |
|
1535 beq(pre_val, R0, done); |
|
1536 nop(); |
|
1537 |
|
1538 // Can we store original value in the thread's buffer? |
|
1539 // Is index == 0? |
|
1540 // (The index field is typed as size_t.) |
|
1541 |
|
1542 //movptr(tmp, index); // tmp := *index_adr |
|
1543 ld(tmp, index); |
|
1544 //cmpptr(tmp, 0); // tmp == 0? |
|
1545 //jcc(Assembler::equal, runtime); // If yes, goto runtime |
|
1546 beq(tmp, R0, runtime); |
|
1547 nop(); |
|
1548 |
|
1549 //subptr(tmp, wordSize); // tmp := tmp - wordSize |
|
1550 //movptr(index, tmp); // *index_adr := tmp |
|
1551 //addptr(tmp, buffer); // tmp := tmp + *buffer_adr |
|
1552 daddiu(tmp, tmp, -1 * wordSize); |
|
1553 sd(tmp, index); |
|
1554 ld(AT, buffer); |
|
1555 daddu(tmp, tmp, AT); |
|
1556 |
|
1557 // Record the previous value |
|
1558 //movptr(Address(tmp, 0), pre_val); |
|
1559 //jmp(done); |
|
1560 sd(pre_val, tmp, 0); |
|
1561 beq(R0, R0, done); |
|
1562 nop(); |
|
1563 |
|
1564 bind(runtime); |
|
1565 // save the live input values |
|
1566 //if(tosca_live) push(rax); |
|
1567 if(tosca_live) push(V0); |
|
1568 |
|
1569 //if (obj != noreg && obj != rax) |
|
1570 if (obj != noreg && obj != V0) |
|
1571 push(obj); |
|
1572 |
|
1573 //if (pre_val != rax) |
|
1574 if (pre_val != V0) |
|
1575 push(pre_val); |
|
1576 |
|
1577 // Calling the runtime using the regular call_VM_leaf mechanism generates |
|
1578 // code (generated by InterpreterMacroAssember::call_VM_leaf_base) |
|
1579 // that checks that the *(ebp+frame::interpreter_frame_last_sp) == NULL. |
|
1580 // |
|
1581 // If we care generating the pre-barrier without a frame (e.g. in the |
|
1582 // intrinsified Reference.get() routine) then ebp might be pointing to |
|
1583 // the caller frame and so this check will most likely fail at runtime. |
|
1584 // |
|
1585 // Expanding the call directly bypasses the generation of the check. |
|
1586 // So when we do not have have a full interpreter frame on the stack |
|
1587 // expand_call should be passed true. |
|
1588 |
|
1589 NOT_LP64( push(thread); ) |
|
1590 |
|
1591 if (expand_call) { |
|
1592 //LP64_ONLY( assert(pre_val != c_rarg1, "smashed arg"); ) |
|
1593 LP64_ONLY( assert(pre_val != A1, "smashed arg"); ) |
|
1594 //pass_arg1(this, thread); |
|
1595 if (thread != A1) move(A1, thread); |
|
1596 //pass_arg0(this, pre_val); |
|
1597 if (pre_val != A0) move(A0, pre_val); |
|
1598 MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), 2); |
|
1599 } else { |
|
1600 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), pre_val, thread); |
|
1601 } |
|
1602 |
|
1603 NOT_LP64( pop(thread); ) |
|
1604 |
|
1605 // save the live input values |
|
1606 //if (pre_val != rax) |
|
1607 if (pre_val != V0) |
|
1608 pop(pre_val); |
|
1609 |
|
1610 //if (obj != noreg && obj != rax) |
|
1611 if (obj != noreg && obj != V0) |
|
1612 pop(obj); |
|
1613 |
|
1614 //if(tosca_live) pop(rax); |
|
1615 if(tosca_live) pop(V0); |
|
1616 |
|
1617 bind(done); |
1488 } |
1618 } |
1489 |
1619 |
1490 void MacroAssembler::g1_write_barrier_post(Register store_addr, |
1620 void MacroAssembler::g1_write_barrier_post(Register store_addr, |
1491 Register new_val, |
1621 Register new_val, |
1492 #ifndef _LP64 |
|
1493 Register thread, |
1622 Register thread, |
1494 #endif |
|
1495 Register tmp, |
1623 Register tmp, |
1496 Register tmp2) { |
1624 Register tmp2) { |
1497 |
1625 assert(tmp == AT, "must be"); |
1498 Unimplemented(); |
1626 assert(tmp2 == AT, "must be"); |
|
1627 #ifdef _LP64 |
|
1628 assert(thread == TREG, "must be"); |
|
1629 #endif // _LP64 |
|
1630 |
|
1631 Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() + |
|
1632 PtrQueue::byte_offset_of_index())); |
|
1633 Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() + |
|
1634 PtrQueue::byte_offset_of_buf())); |
|
1635 |
|
1636 BarrierSet* bs = Universe::heap()->barrier_set(); |
|
1637 CardTableModRefBS* ct = (CardTableModRefBS*)bs; |
|
1638 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); |
|
1639 |
|
1640 Label done; |
|
1641 Label runtime; |
|
1642 |
|
1643 // Does store cross heap regions? |
|
1644 |
|
1645 //movptr(tmp, store_addr); |
|
1646 //xorptr(tmp, new_val); |
|
1647 //shrptr(tmp, HeapRegion::LogOfHRGrainBytes); |
|
1648 //jcc(Assembler::equal, done); |
|
1649 xorr(AT, store_addr, new_val); |
|
1650 dsrl(AT, AT, HeapRegion::LogOfHRGrainBytes); |
|
1651 beq(AT, R0, done); |
|
1652 nop(); |
|
1653 |
|
1654 |
|
1655 // crosses regions, storing NULL? |
|
1656 |
|
1657 //cmpptr(new_val, (int32_t) NULL_WORD); |
|
1658 //jcc(Assembler::equal, done); |
|
1659 beq(new_val, R0, done); |
|
1660 nop(); |
|
1661 |
|
1662 // storing region crossing non-NULL, is card already dirty? |
|
1663 |
|
1664 const Register card_addr = tmp; |
|
1665 const Register cardtable = tmp2; |
|
1666 |
|
1667 //movptr(card_addr, store_addr); |
|
1668 //shrptr(card_addr, CardTableModRefBS::card_shift); |
|
1669 move(card_addr, store_addr); |
|
1670 dsrl(card_addr, card_addr, CardTableModRefBS::card_shift); |
|
1671 // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT |
|
1672 // a valid address and therefore is not properly handled by the relocation code. |
|
1673 //movptr(cardtable, (intptr_t)ct->byte_map_base); |
|
1674 //addptr(card_addr, cardtable); |
|
1675 set64(cardtable, (intptr_t)ct->byte_map_base); |
|
1676 daddu(card_addr, card_addr, cardtable); |
|
1677 |
|
1678 //cmpb(Address(card_addr, 0), (int)G1SATBCardTableModRefBS::g1_young_card_val()); |
|
1679 //jcc(Assembler::equal, done); |
|
1680 lb(AT, card_addr, 0); |
|
1681 daddiu(AT, AT, -1 * (int)G1SATBCardTableModRefBS::g1_young_card_val()); |
|
1682 beq(AT, R0, done); |
|
1683 nop(); |
|
1684 |
|
1685 //membar(Assembler::Membar_mask_bits(Assembler::StoreLoad)); |
|
1686 //cmpb(Address(card_addr, 0), (int)CardTableModRefBS::dirty_card_val()); |
|
1687 //jcc(Assembler::equal, done); |
|
1688 sync(); |
|
1689 lb(AT, card_addr, 0); |
|
1690 daddiu(AT, AT, -1 * (int)(int)CardTableModRefBS::dirty_card_val()); |
|
1691 beq(AT, R0, done); |
|
1692 nop(); |
|
1693 |
|
1694 |
|
1695 // storing a region crossing, non-NULL oop, card is clean. |
|
1696 // dirty card and log. |
|
1697 |
|
1698 //movb(Address(card_addr, 0), (int)CardTableModRefBS::dirty_card_val()); |
|
1699 move(AT, (int)CardTableModRefBS::dirty_card_val()); |
|
1700 sb(AT, card_addr, 0); |
|
1701 |
|
1702 //cmpl(queue_index, 0); |
|
1703 //jcc(Assembler::equal, runtime); |
|
1704 //subl(queue_index, wordSize); |
|
1705 //movptr(tmp2, buffer); |
|
1706 lw(AT, queue_index); |
|
1707 beq(AT, R0, runtime); |
|
1708 nop(); |
|
1709 daddiu(AT, AT, -1 * wordSize); |
|
1710 sw(AT, queue_index); |
|
1711 ld(tmp2, buffer); |
|
1712 #ifdef _LP64 |
|
1713 //movslq(rscratch1, queue_index); |
|
1714 //addq(tmp2, rscratch1); |
|
1715 //movq(Address(tmp2, 0), card_addr); |
|
1716 ld(AT, queue_index); |
|
1717 daddu(tmp2, tmp2, AT); |
|
1718 sd(card_addr, tmp2, 0); |
|
1719 #else |
|
1720 //addl(tmp2, queue_index); |
|
1721 //movl(Address(tmp2, 0), card_addr); |
|
1722 lw(AT, queue_index); |
|
1723 addu32(tmp2, tmp2, AT); |
|
1724 sw(card_addr, tmp2, 0); |
|
1725 #endif |
|
1726 //jmp(done); |
|
1727 beq(R0, R0, done); |
|
1728 nop(); |
|
1729 |
|
1730 bind(runtime); |
|
1731 // save the live input values |
|
1732 push(store_addr); |
|
1733 push(new_val); |
|
1734 #ifdef _LP64 |
|
1735 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, TREG); |
|
1736 #else |
|
1737 push(thread); |
|
1738 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, thread); |
|
1739 pop(thread); |
|
1740 #endif |
|
1741 pop(new_val); |
|
1742 pop(store_addr); |
|
1743 |
|
1744 bind(done); |
1499 } |
1745 } |
1500 |
1746 |
1501 #endif // INCLUDE_ALL_GCS |
1747 #endif // INCLUDE_ALL_GCS |
1502 ////////////////////////////////////////////////////////////////////////////////// |
1748 ////////////////////////////////////////////////////////////////////////////////// |
1503 |
1749 |