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);