Mercurial > hg > graal-compiler
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, |