src/cpu/mips/vm/macroAssembler_mips.cpp

changeset 8000
1510f9dcc0fa
parent 7997
6cbff0651f1a
child 8001
76b73e112cb7
equal deleted inserted replaced
7999:b57e01e9f81e 8000:1510f9dcc0fa
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

mercurial