comparison src/cpu/x86/vm/assembler_x86_64.cpp @ 342:37f87013dfd8

6711316: Open source the Garbage-First garbage collector Summary: First mercurial integration of the code for the Garbage-First garbage collector. Reviewed-by: apetrusenko, iveresov, jmasa, sgoldman, tonyp, ysr
author ysr
date Thu, 05 Jun 2008 15:57:56 -0700
parents b130b98db9cf
children 6aae2f9d0294
comparison
equal deleted inserted replaced
189:0b27f3512f9e 342:37f87013dfd8
4403 movq(c_rarg2, arg_3); 4403 movq(c_rarg2, arg_3);
4404 } 4404 }
4405 call_VM_leaf(entry_point, 3); 4405 call_VM_leaf(entry_point, 3);
4406 } 4406 }
4407 4407
4408 /////////////////////////////////////////////////////////////////////////////
4409 #ifndef SERIALGC
4410
4411 void MacroAssembler::g1_write_barrier_pre(Register obj, Register tmp, Register tmp2, bool tosca_live ) {
4412 Address in_progress(r15_thread, in_bytes(JavaThread::satb_mark_queue_offset() +
4413 PtrQueue::byte_offset_of_active()));
4414
4415 Address index(r15_thread, in_bytes(JavaThread::satb_mark_queue_offset() +
4416 PtrQueue::byte_offset_of_index()));
4417 Address buffer(r15_thread, in_bytes(JavaThread::satb_mark_queue_offset() +
4418 PtrQueue::byte_offset_of_buf()));
4419
4420
4421 Label done;
4422 Label runtime;
4423
4424 // if (!marking_in_progress) goto done;
4425 if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
4426 cmpl(in_progress, 0);
4427 } else {
4428 assert(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption");
4429 cmpb(in_progress, 0);
4430 }
4431 jcc(Assembler::equal, done);
4432
4433 // if (x.f == NULL) goto done;
4434 cmpq(Address(obj, 0), (int)NULL_WORD);
4435 jcc(Assembler::equal, done);
4436
4437 // Can we store original value in the thread's buffer?
4438
4439 movslq(tmp, index);
4440 movq(tmp2, Address(obj, 0));
4441 cmpq(tmp, 0);
4442 jcc(Assembler::equal, runtime);
4443 subq(tmp, wordSize);
4444 movl(index, tmp);
4445 addq(tmp, buffer);
4446 movq(Address(tmp, 0), tmp2);
4447 jmp(done);
4448 bind(runtime);
4449 // save live inputs
4450 if (tosca_live) pushq(rax);
4451 pushq(obj);
4452 movq(c_rarg0, Address(obj, 0));
4453 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), c_rarg0, r15_thread);
4454 popq(obj);
4455 if (tosca_live) popq(rax);
4456 bind(done);
4457 }
4458
4459 void MacroAssembler::g1_write_barrier_post(Register store_addr,
4460 Register new_val,
4461 Register tmp,
4462 Register tmp2) {
4463
4464 Address index(r15_thread, in_bytes(JavaThread::dirty_card_queue_offset() +
4465 PtrQueue::byte_offset_of_index()));
4466 Address buffer(r15_thread, in_bytes(JavaThread::dirty_card_queue_offset() +
4467 PtrQueue::byte_offset_of_buf()));
4468 BarrierSet* bs = Universe::heap()->barrier_set();
4469 CardTableModRefBS* ct = (CardTableModRefBS*)bs;
4470 Label done;
4471 Label runtime;
4472
4473 // Does store cross heap regions?
4474
4475 movq(tmp, store_addr);
4476 xorq(tmp, new_val);
4477 shrq(tmp, HeapRegion::LogOfHRGrainBytes);
4478 jcc(Assembler::equal, done);
4479
4480 // crosses regions, storing NULL?
4481
4482 cmpq(new_val, (int)NULL_WORD);
4483 jcc(Assembler::equal, done);
4484
4485 // storing region crossing non-NULL, is card already dirty?
4486 const Register card_addr = tmp;
4487
4488 movq(card_addr, store_addr);
4489 shrq(card_addr, CardTableModRefBS::card_shift);
4490
4491 ExternalAddress cardtable((address) ct->byte_map_base);
4492 lea(tmp2, cardtable);
4493
4494 // get the address of the card
4495 addq(card_addr, tmp2);
4496
4497 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
4498 cmpb(Address(card_addr, 0), 0);
4499 jcc(Assembler::equal, done);
4500
4501 // storing region crossing non-NULL, card is clean.
4502 // dirty card and log.
4503
4504 movb(Address(card_addr, 0), 0);
4505
4506 cmpl(index, 0);
4507 jcc(Assembler::equal, runtime);
4508 subl(index, wordSize);
4509 movq(tmp2, buffer);
4510 movslq(rscratch1, index);
4511 addq(tmp2, rscratch1);
4512 // log the card
4513 movq(Address(tmp2, 0), card_addr);
4514 jmp(done);
4515
4516 bind(runtime);
4517 // save live inputs
4518 pushq(store_addr);
4519 pushq(new_val);
4520 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, r15_thread);
4521 popq(new_val);
4522 popq(store_addr);
4523
4524 bind(done);
4525
4526
4527 }
4528
4529 #endif // SERIALGC
4530 /////////////////////////////////////////////////////////////////////////////
4408 4531
4409 // Calls to C land 4532 // Calls to C land
4410 // 4533 //
4411 // When entering C land, the rbp & rsp of the last Java frame have to 4534 // When entering C land, the rbp & rsp of the last Java frame have to
4412 // be recorded in the (thread-local) JavaThread object. When leaving C 4535 // be recorded in the (thread-local) JavaThread object. When leaving C
4800 int con_size_in_bytes, 4923 int con_size_in_bytes,
4801 Register t1, 4924 Register t1,
4802 Label& slow_case) { 4925 Label& slow_case) {
4803 assert(obj == rax, "obj must be in rax for cmpxchg"); 4926 assert(obj == rax, "obj must be in rax for cmpxchg");
4804 assert_different_registers(obj, var_size_in_bytes, t1); 4927 assert_different_registers(obj, var_size_in_bytes, t1);
4805 Register end = t1; 4928 if (CMSIncrementalMode || !Universe::heap()->supports_inline_contig_alloc()) {
4806 Label retry; 4929 jmp(slow_case);
4807 bind(retry); 4930 } else {
4808 ExternalAddress heap_top((address) Universe::heap()->top_addr()); 4931 Register end = t1;
4809 movptr(obj, heap_top); 4932 Label retry;
4810 if (var_size_in_bytes == noreg) { 4933 bind(retry);
4811 leaq(end, Address(obj, con_size_in_bytes)); 4934 ExternalAddress heap_top((address) Universe::heap()->top_addr());
4812 } else { 4935 movptr(obj, heap_top);
4813 leaq(end, Address(obj, var_size_in_bytes, Address::times_1)); 4936 if (var_size_in_bytes == noreg) {
4814 } 4937 leaq(end, Address(obj, con_size_in_bytes));
4815 // if end < obj then we wrapped around => object too long => slow case 4938 } else {
4816 cmpq(end, obj); 4939 leaq(end, Address(obj, var_size_in_bytes, Address::times_1));
4817 jcc(Assembler::below, slow_case); 4940 }
4818 cmpptr(end, ExternalAddress((address) Universe::heap()->end_addr())); 4941 // if end < obj then we wrapped around => object too long => slow case
4819 4942 cmpq(end, obj);
4820 jcc(Assembler::above, slow_case); 4943 jcc(Assembler::below, slow_case);
4821 // Compare obj with the top addr, and if still equal, store the new 4944 cmpptr(end, ExternalAddress((address) Universe::heap()->end_addr()));
4822 // top addr in end at the address of the top addr pointer. Sets ZF 4945
4823 // if was equal, and clears it otherwise. Use lock prefix for 4946 jcc(Assembler::above, slow_case);
4824 // atomicity on MPs. 4947 // Compare obj with the top addr, and if still equal, store the new
4825 if (os::is_MP()) { 4948 // top addr in end at the address of the top addr pointer. Sets ZF
4826 lock(); 4949 // if was equal, and clears it otherwise. Use lock prefix for
4827 } 4950 // atomicity on MPs.
4828 cmpxchgptr(end, heap_top); 4951 if (os::is_MP()) {
4829 // if someone beat us on the allocation, try again, otherwise continue 4952 lock();
4830 jcc(Assembler::notEqual, retry); 4953 }
4954 cmpxchgptr(end, heap_top);
4955 // if someone beat us on the allocation, try again, otherwise continue
4956 jcc(Assembler::notEqual, retry);
4957 }
4831 } 4958 }
4832 4959
4833 // Defines obj, preserves var_size_in_bytes, okay for t2 == var_size_in_bytes. 4960 // Defines obj, preserves var_size_in_bytes, okay for t2 == var_size_in_bytes.
4834 void MacroAssembler::tlab_allocate(Register obj, 4961 void MacroAssembler::tlab_allocate(Register obj,
4835 Register var_size_in_bytes, 4962 Register var_size_in_bytes,