Mercurial > hg > truffle
comparison src/cpu/x86/vm/assembler_x86.cpp @ 362:f8199438385b
Merge
author | apetrusenko |
---|---|
date | Wed, 17 Sep 2008 16:49:18 +0400 |
parents | src/cpu/x86/vm/assembler_x86_32.cpp@1ee8caae33af src/cpu/x86/vm/assembler_x86_32.cpp@dc7f315e41f7 |
children | 2649e5276dd7 |
comparison
equal
deleted
inserted
replaced
316:5fa96a5a7e76 | 362:f8199438385b |
---|---|
5933 int con_size_in_bytes, | 5933 int con_size_in_bytes, |
5934 Register t1, | 5934 Register t1, |
5935 Label& slow_case) { | 5935 Label& slow_case) { |
5936 assert(obj == rax, "obj must be in rax, for cmpxchg"); | 5936 assert(obj == rax, "obj must be in rax, for cmpxchg"); |
5937 assert_different_registers(obj, var_size_in_bytes, t1); | 5937 assert_different_registers(obj, var_size_in_bytes, t1); |
5938 Register end = t1; | 5938 if (CMSIncrementalMode || !Universe::heap()->supports_inline_contig_alloc()) { |
5939 Label retry; | 5939 jmp(slow_case); |
5940 bind(retry); | 5940 } else { |
5941 ExternalAddress heap_top((address) Universe::heap()->top_addr()); | 5941 Register end = t1; |
5942 movptr(obj, heap_top); | 5942 Label retry; |
5943 if (var_size_in_bytes == noreg) { | 5943 bind(retry); |
5944 lea(end, Address(obj, con_size_in_bytes)); | 5944 ExternalAddress heap_top((address) Universe::heap()->top_addr()); |
5945 } else { | 5945 movptr(obj, heap_top); |
5946 lea(end, Address(obj, var_size_in_bytes, Address::times_1)); | 5946 if (var_size_in_bytes == noreg) { |
5947 } | 5947 lea(end, Address(obj, con_size_in_bytes)); |
5948 // if end < obj then we wrapped around => object too long => slow case | 5948 } else { |
5949 cmpptr(end, obj); | 5949 lea(end, Address(obj, var_size_in_bytes, Address::times_1)); |
5950 jcc(Assembler::below, slow_case); | 5950 } |
5951 cmpptr(end, ExternalAddress((address) Universe::heap()->end_addr())); | 5951 // if end < obj then we wrapped around => object too long => slow case |
5952 jcc(Assembler::above, slow_case); | 5952 cmpptr(end, obj); |
5953 // Compare obj with the top addr, and if still equal, store the new top addr in | 5953 jcc(Assembler::below, slow_case); |
5954 // end at the address of the top addr pointer. Sets ZF if was equal, and clears | 5954 cmpptr(end, ExternalAddress((address) Universe::heap()->end_addr())); |
5955 // it otherwise. Use lock prefix for atomicity on MPs. | 5955 jcc(Assembler::above, slow_case); |
5956 locked_cmpxchgptr(end, heap_top); | 5956 // Compare obj with the top addr, and if still equal, store the new top addr in |
5957 jcc(Assembler::notEqual, retry); | 5957 // end at the address of the top addr pointer. Sets ZF if was equal, and clears |
5958 // it otherwise. Use lock prefix for atomicity on MPs. | |
5959 locked_cmpxchgptr(end, heap_top); | |
5960 jcc(Assembler::notEqual, retry); | |
5961 } | |
5958 } | 5962 } |
5959 | 5963 |
5960 void MacroAssembler::enter() { | 5964 void MacroAssembler::enter() { |
5961 push(rbp); | 5965 push(rbp); |
5962 mov(rbp, rsp); | 5966 mov(rbp, rsp); |
6488 } else { | 6492 } else { |
6489 shll(reg, 16); | 6493 shll(reg, 16); |
6490 sarl(reg, 16); | 6494 sarl(reg, 16); |
6491 } | 6495 } |
6492 } | 6496 } |
6497 | |
6498 ////////////////////////////////////////////////////////////////////////////////// | |
6499 #ifndef SERIALGC | |
6500 | |
6501 void MacroAssembler::g1_write_barrier_pre(Register obj, | |
6502 #ifndef _LP64 | |
6503 Register thread, | |
6504 #endif | |
6505 Register tmp, | |
6506 Register tmp2, | |
6507 bool tosca_live) { | |
6508 LP64_ONLY(Register thread = r15_thread;) | |
6509 Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() + | |
6510 PtrQueue::byte_offset_of_active())); | |
6511 | |
6512 Address index(thread, in_bytes(JavaThread::satb_mark_queue_offset() + | |
6513 PtrQueue::byte_offset_of_index())); | |
6514 Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() + | |
6515 PtrQueue::byte_offset_of_buf())); | |
6516 | |
6517 | |
6518 Label done; | |
6519 Label runtime; | |
6520 | |
6521 // if (!marking_in_progress) goto done; | |
6522 if (in_bytes(PtrQueue::byte_width_of_active()) == 4) { | |
6523 cmpl(in_progress, 0); | |
6524 } else { | |
6525 assert(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption"); | |
6526 cmpb(in_progress, 0); | |
6527 } | |
6528 jcc(Assembler::equal, done); | |
6529 | |
6530 // if (x.f == NULL) goto done; | |
6531 cmpptr(Address(obj, 0), NULL_WORD); | |
6532 jcc(Assembler::equal, done); | |
6533 | |
6534 // Can we store original value in the thread's buffer? | |
6535 | |
6536 LP64_ONLY(movslq(tmp, index);) | |
6537 movptr(tmp2, Address(obj, 0)); | |
6538 #ifdef _LP64 | |
6539 cmpq(tmp, 0); | |
6540 #else | |
6541 cmpl(index, 0); | |
6542 #endif | |
6543 jcc(Assembler::equal, runtime); | |
6544 #ifdef _LP64 | |
6545 subq(tmp, wordSize); | |
6546 movl(index, tmp); | |
6547 addq(tmp, buffer); | |
6548 #else | |
6549 subl(index, wordSize); | |
6550 movl(tmp, buffer); | |
6551 addl(tmp, index); | |
6552 #endif | |
6553 movptr(Address(tmp, 0), tmp2); | |
6554 jmp(done); | |
6555 bind(runtime); | |
6556 // save the live input values | |
6557 if(tosca_live) push(rax); | |
6558 push(obj); | |
6559 #ifdef _LP64 | |
6560 movq(c_rarg0, Address(obj, 0)); | |
6561 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), c_rarg0, r15_thread); | |
6562 #else | |
6563 push(thread); | |
6564 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), tmp2, thread); | |
6565 pop(thread); | |
6566 #endif | |
6567 pop(obj); | |
6568 if(tosca_live) pop(rax); | |
6569 bind(done); | |
6570 | |
6571 } | |
6572 | |
6573 void MacroAssembler::g1_write_barrier_post(Register store_addr, | |
6574 Register new_val, | |
6575 #ifndef _LP64 | |
6576 Register thread, | |
6577 #endif | |
6578 Register tmp, | |
6579 Register tmp2) { | |
6580 | |
6581 LP64_ONLY(Register thread = r15_thread;) | |
6582 Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() + | |
6583 PtrQueue::byte_offset_of_index())); | |
6584 Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() + | |
6585 PtrQueue::byte_offset_of_buf())); | |
6586 BarrierSet* bs = Universe::heap()->barrier_set(); | |
6587 CardTableModRefBS* ct = (CardTableModRefBS*)bs; | |
6588 Label done; | |
6589 Label runtime; | |
6590 | |
6591 // Does store cross heap regions? | |
6592 | |
6593 movptr(tmp, store_addr); | |
6594 xorptr(tmp, new_val); | |
6595 shrptr(tmp, HeapRegion::LogOfHRGrainBytes); | |
6596 jcc(Assembler::equal, done); | |
6597 | |
6598 // crosses regions, storing NULL? | |
6599 | |
6600 cmpptr(new_val, (int32_t) NULL_WORD); | |
6601 jcc(Assembler::equal, done); | |
6602 | |
6603 // storing region crossing non-NULL, is card already dirty? | |
6604 | |
6605 ExternalAddress cardtable((address) ct->byte_map_base); | |
6606 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); | |
6607 #ifdef _LP64 | |
6608 const Register card_addr = tmp; | |
6609 | |
6610 movq(card_addr, store_addr); | |
6611 shrq(card_addr, CardTableModRefBS::card_shift); | |
6612 | |
6613 lea(tmp2, cardtable); | |
6614 | |
6615 // get the address of the card | |
6616 addq(card_addr, tmp2); | |
6617 #else | |
6618 const Register card_index = tmp; | |
6619 | |
6620 movl(card_index, store_addr); | |
6621 shrl(card_index, CardTableModRefBS::card_shift); | |
6622 | |
6623 Address index(noreg, card_index, Address::times_1); | |
6624 const Register card_addr = tmp; | |
6625 lea(card_addr, as_Address(ArrayAddress(cardtable, index))); | |
6626 #endif | |
6627 cmpb(Address(card_addr, 0), 0); | |
6628 jcc(Assembler::equal, done); | |
6629 | |
6630 // storing a region crossing, non-NULL oop, card is clean. | |
6631 // dirty card and log. | |
6632 | |
6633 movb(Address(card_addr, 0), 0); | |
6634 | |
6635 cmpl(queue_index, 0); | |
6636 jcc(Assembler::equal, runtime); | |
6637 subl(queue_index, wordSize); | |
6638 movptr(tmp2, buffer); | |
6639 #ifdef _LP64 | |
6640 movslq(rscratch1, queue_index); | |
6641 addq(tmp2, rscratch1); | |
6642 movq(Address(tmp2, 0), card_addr); | |
6643 #else | |
6644 addl(tmp2, queue_index); | |
6645 movl(Address(tmp2, 0), card_index); | |
6646 #endif | |
6647 jmp(done); | |
6648 | |
6649 bind(runtime); | |
6650 // save the live input values | |
6651 push(store_addr); | |
6652 push(new_val); | |
6653 #ifdef _LP64 | |
6654 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, r15_thread); | |
6655 #else | |
6656 push(thread); | |
6657 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, thread); | |
6658 pop(thread); | |
6659 #endif | |
6660 pop(new_val); | |
6661 pop(store_addr); | |
6662 | |
6663 bind(done); | |
6664 | |
6665 } | |
6666 | |
6667 #endif // SERIALGC | |
6668 ////////////////////////////////////////////////////////////////////////////////// | |
6669 | |
6493 | 6670 |
6494 void MacroAssembler::store_check(Register obj) { | 6671 void MacroAssembler::store_check(Register obj) { |
6495 // Does a store check for the oop in register obj. The content of | 6672 // Does a store check for the oop in register obj. The content of |
6496 // register obj is destroyed afterwards. | 6673 // register obj is destroyed afterwards. |
6497 store_check_part_1(obj); | 6674 store_check_part_1(obj); |