Mercurial > hg > truffle
diff src/cpu/x86/vm/templateTable_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 | ba764ed4b6f2 |
children | 6aae2f9d0294 |
line wrap: on
line diff
--- a/src/cpu/x86/vm/templateTable_x86_64.cpp Wed Jun 04 13:51:09 2008 -0700 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Jun 05 15:57:56 2008 -0700 @@ -113,6 +113,69 @@ // Miscelaneous helper routines +// Store an oop (or NULL) at the address described by obj. +// If val == noreg this means store a NULL + +static void do_oop_store(InterpreterMacroAssembler* _masm, + Address obj, + Register val, + BarrierSet::Name barrier, + bool precise) { + assert(val == noreg || val == rax, "parameter is just for looks"); + switch (barrier) { +#ifndef SERIALGC + case BarrierSet::G1SATBCT: + case BarrierSet::G1SATBCTLogging: + { + // flatten object address if needed + if (obj.index() == noreg && obj.disp() == 0) { + if (obj.base() != rdx) { + __ movq(rdx, obj.base()); + } + } else { + __ leaq(rdx, obj); + } + __ g1_write_barrier_pre(rdx, r8, rbx, val != noreg); + if (val == noreg) { + __ store_heap_oop(Address(rdx, 0), NULL_WORD); + } else { + __ store_heap_oop(Address(rdx, 0), val); + __ g1_write_barrier_post(rdx, val, r8, rbx); + } + + } + break; +#endif // SERIALGC + case BarrierSet::CardTableModRef: + case BarrierSet::CardTableExtension: + { + if (val == noreg) { + __ store_heap_oop(obj, NULL_WORD); + } else { + __ store_heap_oop(obj, val); + // flatten object address if needed + if (!precise || (obj.index() == noreg && obj.disp() == 0)) { + __ store_check(obj.base()); + } else { + __ leaq(rdx, obj); + __ store_check(rdx); + } + } + } + break; + case BarrierSet::ModRef: + case BarrierSet::Other: + if (val == noreg) { + __ store_heap_oop(obj, NULL_WORD); + } else { + __ store_heap_oop(obj, val); + } + break; + default : + ShouldNotReachHere(); + + } +} Address TemplateTable::at_bcp(int offset) { assert(_desc->uses_bcp(), "inconsistent uses_bcp information"); @@ -558,8 +621,8 @@ // rdx: array index_check(rdx, rax); // kills rbx __ load_heap_oop(rax, Address(rdx, rax, - UseCompressedOops ? Address::times_4 : Address::times_8, - arrayOopDesc::base_offset_in_bytes(T_OBJECT))); + UseCompressedOops ? Address::times_4 : Address::times_8, + arrayOopDesc::base_offset_in_bytes(T_OBJECT))); } void TemplateTable::baload() { @@ -864,6 +927,11 @@ __ movq(rax, at_tos()); // value __ movl(rcx, at_tos_p1()); // index __ movq(rdx, at_tos_p2()); // array + + Address element_address(rdx, rcx, + UseCompressedOops? Address::times_4 : Address::times_8, + arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + index_check(rdx, rcx); // kills rbx // do array store check - check for NULL value first __ testq(rax, rax); @@ -877,9 +945,7 @@ sizeof(oopDesc) + objArrayKlass::element_klass_offset_in_bytes())); // Compress array + index*oopSize + 12 into a single register. Frees rcx. - __ leaq(rdx, Address(rdx, rcx, - UseCompressedOops ? Address::times_4 : Address::times_8, - arrayOopDesc::base_offset_in_bytes(T_OBJECT))); + __ leaq(rdx, element_address); // Generate subtype check. Blows rcx, rdi // Superklass in rax. Subklass in rbx. @@ -891,18 +957,20 @@ // Come here on success __ bind(ok_is_subtype); - __ movq(rax, at_tos()); // Value - __ store_heap_oop(Address(rdx, 0), rax); - __ store_check(rdx); + + // Get the value we will store + __ movq(rax, at_tos()); + + // Now store using the appropriate barrier + do_oop_store(_masm, Address(rdx, 0), rax, _bs->kind(), true); __ jmp(done); // Have a NULL in rax, rdx=array, ecx=index. Store NULL at ary[idx] __ bind(is_null); __ profile_null_seen(rbx); - __ store_heap_oop(Address(rdx, rcx, - UseCompressedOops ? Address::times_4 : Address::times_8, - arrayOopDesc::base_offset_in_bytes(T_OBJECT)), - rax); + + // Store a NULL + do_oop_store(_masm, element_address, noreg, _bs->kind(), true); // Pop stack arguments __ bind(done); @@ -2394,8 +2462,10 @@ // atos __ pop(atos); if (!is_static) pop_and_check_object(obj); - __ store_heap_oop(field, rax); - __ store_check(obj, field); // Need to mark card + + // Store into the field + do_oop_store(_masm, field, rax, _bs->kind(), false); + if (!is_static) { patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx); } @@ -2582,8 +2652,7 @@ // access field switch (bytecode()) { case Bytecodes::_fast_aputfield: - __ store_heap_oop(field, rax); - __ store_check(rcx, field); + do_oop_store(_masm, field, rax, _bs->kind(), false); break; case Bytecodes::_fast_lputfield: __ movq(field, rax); @@ -2789,7 +2858,7 @@ __ andl(recv, 0xFF); if (TaggedStackInterpreter) __ shll(recv, 1); // index*2 __ movq(recv, Address(rsp, recv, Address::times_8, - -Interpreter::expr_offset_in_bytes(1))); + -Interpreter::expr_offset_in_bytes(1))); __ verify_oop(recv); } @@ -3042,8 +3111,6 @@ Label initialize_header; Label initialize_object; // including clearing the fields Label allocate_shared; - ExternalAddress top((address)Universe::heap()->top_addr()); - ExternalAddress end((address)Universe::heap()->end_addr()); __ get_cpool_and_tags(rsi, rax); // get instanceKlass @@ -3104,6 +3171,9 @@ if (allow_shared_alloc) { __ bind(allocate_shared); + ExternalAddress top((address)Universe::heap()->top_addr()); + ExternalAddress end((address)Universe::heap()->end_addr()); + const Register RtopAddr = rscratch1; const Register RendAddr = rscratch2;