src/cpu/x86/vm/stubGenerator_x86_64.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/cpu/x86/vm/stubGenerator_x86_64.cpp Mon Feb 28 18:56:38 2011
--- new/src/cpu/x86/vm/stubGenerator_x86_64.cpp Mon Feb 28 18:56:37 2011
*** 1158,1186 ****
--- 1158,1187 ----
// Generate code for an array write pre barrier
//
// addr - starting address
// count - element count
+ // tmp - scratch register
//
// Destroy no registers!
//
! void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
BarrierSet* bs = Universe::heap()->barrier_set();
switch (bs->kind()) {
case BarrierSet::G1SATBCT:
case BarrierSet::G1SATBCTLogging:
{
+ // With G1, don't generate the call if we statically know that the target in uninitialized
+ if (!dest_uninitialized) {
__ pusha(); // push registers
if (count == c_rarg0) {
if (addr == c_rarg1) {
// exactly backwards!!
__ xchgptr(c_rarg1, c_rarg0);
} else {
__ movptr(c_rarg1, count);
__ movptr(c_rarg0, addr);
}
} else {
__ movptr(c_rarg0, addr);
__ movptr(c_rarg1, count);
}
__ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
*** 1767,1777 ****
--- 1768,1779 ----
//
// Side Effects:
// disjoint_int_copy_entry is set to the no-overlap entry point
// used by generate_conjoint_int_oop_copy().
//
- address generate_disjoint_int_oop_copy(bool aligned, bool is_oop, address* entry, const char *name) {
+ const char *name, bool dest_uninitialized = false) {
__ align(CodeEntryAlignment);
StubCodeMark mark(this, "StubRoutines", name);
address start = __ pc();
Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes, L_exit;
*** 1797,1807 ****
--- 1799,1809 ----
setup_arg_regs(); // from => rdi, to => rsi, count => rdx
// r9 and r10 may be used to save non-volatile registers
if (is_oop) {
__ movq(saved_to, to);
! gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
}
// 'from', 'to' and 'count' are now valid
__ movptr(dword_count, count);
__ shrptr(count, 1); // count => qword_count
*** 1858,1868 ****
--- 1860,1871 ----
// If 'from' and/or 'to' are aligned on 4-byte boundaries, we let
// the hardware handle it. The two dwords within qwords that span
// cache line boundaries will still be loaded and stored atomicly.
//
address generate_conjoint_int_oop_copy(bool aligned, bool is_oop, address nooverlap_target,
! address *entry, const char *name) {
! address *entry, const char *name,
+ bool dest_uninitialized = false) {
__ align(CodeEntryAlignment);
StubCodeMark mark(this, "StubRoutines", name);
address start = __ pc();
Label L_copy_32_bytes, L_copy_8_bytes, L_copy_2_bytes, L_exit;
*** 1885,1895 ****
--- 1888,1898 ----
setup_arg_regs(); // from => rdi, to => rsi, count => rdx
// r9 and r10 may be used to save non-volatile registers
if (is_oop) {
// no registers are destroyed by this call
! gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
}
assert_clean_int(count, rax); // Make sure 'count' is clean int.
// 'from', 'to' and 'count' are now valid
__ movptr(dword_count, count);
*** 1951,1961 ****
--- 1954,1965 ----
//
// Side Effects:
// disjoint_oop_copy_entry or disjoint_long_copy_entry is set to the
// no-overlap entry point used by generate_conjoint_long_oop_copy().
//
- address generate_disjoint_long_oop_copy(bool aligned, bool is_oop, address *entry, const char *name) {
+ const char *name, bool dest_uninitialized = false) {
__ align(CodeEntryAlignment);
StubCodeMark mark(this, "StubRoutines", name);
address start = __ pc();
Label L_copy_32_bytes, L_copy_8_bytes, L_exit;
*** 1981,1991 ****
--- 1985,1995 ----
setup_arg_regs(); // from => rdi, to => rsi, count => rdx
// r9 and r10 may be used to save non-volatile registers
// 'from', 'to' and 'qword_count' are now valid
if (is_oop) {
// no registers are destroyed by this call
! gen_write_ref_array_pre_barrier(to, qword_count, dest_uninitialized);
}
// Copy from low to high addresses. Use 'to' as scratch.
__ lea(end_from, Address(from, qword_count, Address::times_8, -8));
__ lea(end_to, Address(to, qword_count, Address::times_8, -8));
*** 2036,2047 ****
--- 2040,2052 ----
// Inputs:
// c_rarg0 - source array address
// c_rarg1 - destination array address
// c_rarg2 - element count, treated as ssize_t, can be zero
//
- address generate_conjoint_long_oop_copy(bool aligned, bool is_oop, address nooverlap_target,
! address *entry, const char *name) {
! address nooverlap_target, address *entry,
+ const char *name, bool dest_uninitialized = false) {
__ align(CodeEntryAlignment);
StubCodeMark mark(this, "StubRoutines", name);
address start = __ pc();
Label L_copy_32_bytes, L_copy_8_bytes, L_exit;
*** 2065,2075 ****
--- 2070,2080 ----
// 'from', 'to' and 'qword_count' are now valid
if (is_oop) {
// Save to and count for store barrier
__ movptr(saved_count, qword_count);
// No registers are destroyed by this call
! gen_write_ref_array_pre_barrier(to, saved_count, dest_uninitialized);
}
__ jmp(L_copy_32_bytes);
// Copy trailing qwords
*** 2144,2154 ****
--- 2149,2160 ----
//
// Output:
// rax == 0 - success
// rax == -1^K - failure, where K is partial transfer count
//
! address generate_checkcast_copy(const char *name, address *entry) {
! address generate_checkcast_copy(const char *name, address *entry,
+ bool dest_uninitialized = false) {
Label L_load_element, L_store_element, L_do_card_marks, L_done;
// Input registers (after setup_arg_regs)
const Register from = rdi; // source array address
*** 2238,2248 ****
--- 2244,2254 ----
Address end_to_addr(to, length, TIMES_OOP, 0);
// Loop-variant addresses. They assume post-incremented count < 0.
Address from_element_addr(end_from, count, TIMES_OOP, 0);
Address to_element_addr(end_to, count, TIMES_OOP, 0);
! gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
// Copy from low to high addresses, indexed from the end of each array.
__ lea(end_from, end_from_addr);
__ lea(end_to, end_to_addr);
__ movptr(r14_length, length); // save a copy of the length
*** 2748,2765 ****
--- 2754,2786 ----
if (UseCompressedOops) {
StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_int_oop_copy(false, true, &entry,
"oop_disjoint_arraycopy");
StubRoutines::_oop_arraycopy = generate_conjoint_int_oop_copy(false, true, entry,
&entry_oop_arraycopy, "oop_arraycopy");
+ StubRoutines::_oop_disjoint_arraycopy_uninit = generate_disjoint_int_oop_copy(false, true, &entry,
+ "oop_disjoint_arraycopy_uninit",
+ /*dest_uninitialized*/true);
+ StubRoutines::_oop_arraycopy_uninit = generate_conjoint_int_oop_copy(false, true, entry,
+ NULL, "oop_arraycopy_uninit",
+ /*dest_uninitialized*/true);
} else {
StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_long_oop_copy(false, true, &entry,
"oop_disjoint_arraycopy");
StubRoutines::_oop_arraycopy = generate_conjoint_long_oop_copy(false, true, entry,
&entry_oop_arraycopy, "oop_arraycopy");
+ StubRoutines::_oop_disjoint_arraycopy_uninit = generate_disjoint_long_oop_copy(false, true, &entry,
+ "oop_disjoint_arraycopy_uninit",
+ /*dest_uninitialized*/true);
+ StubRoutines::_oop_arraycopy_uninit = generate_conjoint_long_oop_copy(false, true, entry,
+ NULL, "oop_arraycopy_uninit",
+ /*dest_uninitialized*/true);
}
StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy);
+ StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy("checkcast_arraycopy_uninit", NULL,
+ /*dest_uninitialized*/true);
+
StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy",
entry_jbyte_arraycopy,
entry_jshort_arraycopy,
entry_jint_arraycopy,
entry_jlong_arraycopy);
*** 2792,2801 ****
--- 2813,2825 ----
StubRoutines::_arrayof_jlong_disjoint_arraycopy = StubRoutines::_jlong_disjoint_arraycopy;
StubRoutines::_arrayof_jlong_arraycopy = StubRoutines::_jlong_arraycopy;
StubRoutines::_arrayof_oop_disjoint_arraycopy = StubRoutines::_oop_disjoint_arraycopy;
StubRoutines::_arrayof_oop_arraycopy = StubRoutines::_oop_arraycopy;
+
+ StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit = StubRoutines::_oop_disjoint_arraycopy_uninit;
+ StubRoutines::_arrayof_oop_arraycopy_uninit = StubRoutines::_oop_arraycopy_uninit;
}
void generate_math_stubs() {
{
StubCodeMark mark(this, "StubRoutines", "log");
src/cpu/x86/vm/stubGenerator_x86_64.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File