From 8dc3eb94be5546c0d912a2973322aa4c75f4ca16 Mon Sep 17 00:00:00 2001 From: coleenp Date: Sun, 13 Apr 2008 17:43:42 -0400 Subject: 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold --- src/share/vm/c1/c1_Runtime1.cpp | 72 +++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 28 deletions(-) (limited to 'src/share/vm/c1/c1_Runtime1.cpp') diff --git a/src/share/vm/c1/c1_Runtime1.cpp b/src/share/vm/c1/c1_Runtime1.cpp index 8fe439557..8f42fe143 100644 --- a/src/share/vm/c1/c1_Runtime1.cpp +++ b/src/share/vm/c1/c1_Runtime1.cpp @@ -1074,6 +1074,43 @@ JRT_LEAF(void, Runtime1::trace_block_entry(jint block_id)) JRT_END +// Array copy return codes. +enum { + ac_failed = -1, // arraycopy failed + ac_ok = 0 // arraycopy succeeded +}; + + +template int obj_arraycopy_work(oopDesc* src, T* src_addr, + oopDesc* dst, T* dst_addr, + int length) { + + // For performance reasons, we assume we are using a card marking write + // barrier. The assert will fail if this is not the case. + // Note that we use the non-virtual inlineable variant of write_ref_array. + BarrierSet* bs = Universe::heap()->barrier_set(); + assert(bs->has_write_ref_array_opt(), + "Barrier set must have ref array opt"); + if (src == dst) { + // same object, no check + Copy::conjoint_oops_atomic(src_addr, dst_addr, length); + bs->write_ref_array(MemRegion((HeapWord*)dst_addr, + (HeapWord*)(dst_addr + length))); + return ac_ok; + } else { + klassOop bound = objArrayKlass::cast(dst->klass())->element_klass(); + klassOop stype = objArrayKlass::cast(src->klass())->element_klass(); + if (stype == bound || Klass::cast(stype)->is_subtype_of(bound)) { + // Elements are guaranteed to be subtypes, so no check necessary + Copy::conjoint_oops_atomic(src_addr, dst_addr, length); + bs->write_ref_array(MemRegion((HeapWord*)dst_addr, + (HeapWord*)(dst_addr + length))); + return ac_ok; + } + } + return ac_failed; +} + // fast and direct copy of arrays; returning -1, means that an exception may be thrown // and we did not copy anything JRT_LEAF(int, Runtime1::arraycopy(oopDesc* src, int src_pos, oopDesc* dst, int dst_pos, int length)) @@ -1081,11 +1118,6 @@ JRT_LEAF(int, Runtime1::arraycopy(oopDesc* src, int src_pos, oopDesc* dst, int d _generic_arraycopy_cnt++; // Slow-path oop array copy #endif - enum { - ac_failed = -1, // arraycopy failed - ac_ok = 0 // arraycopy succeeded - }; - if (src == NULL || dst == NULL || src_pos < 0 || dst_pos < 0 || length < 0) return ac_failed; if (!dst->is_array() || !src->is_array()) return ac_failed; if ((unsigned int) arrayOop(src)->length() < (unsigned int)src_pos + (unsigned int)length) return ac_failed; @@ -1105,30 +1137,14 @@ JRT_LEAF(int, Runtime1::arraycopy(oopDesc* src, int src_pos, oopDesc* dst, int d memmove(dst_addr, src_addr, length << l2es); return ac_ok; } else if (src->is_objArray() && dst->is_objArray()) { - oop* src_addr = objArrayOop(src)->obj_at_addr(src_pos); - oop* dst_addr = objArrayOop(dst)->obj_at_addr(dst_pos); - // For performance reasons, we assume we are using a card marking write - // barrier. The assert will fail if this is not the case. - // Note that we use the non-virtual inlineable variant of write_ref_array. - BarrierSet* bs = Universe::heap()->barrier_set(); - assert(bs->has_write_ref_array_opt(), - "Barrier set must have ref array opt"); - if (src == dst) { - // same object, no check - Copy::conjoint_oops_atomic(src_addr, dst_addr, length); - bs->write_ref_array(MemRegion((HeapWord*)dst_addr, - (HeapWord*)(dst_addr + length))); - return ac_ok; + if (UseCompressedOops) { // will need for tiered + narrowOop *src_addr = objArrayOop(src)->obj_at_addr(src_pos); + narrowOop *dst_addr = objArrayOop(dst)->obj_at_addr(dst_pos); + return obj_arraycopy_work(src, src_addr, dst, dst_addr, length); } else { - klassOop bound = objArrayKlass::cast(dst->klass())->element_klass(); - klassOop stype = objArrayKlass::cast(src->klass())->element_klass(); - if (stype == bound || Klass::cast(stype)->is_subtype_of(bound)) { - // Elements are guaranteed to be subtypes, so no check necessary - Copy::conjoint_oops_atomic(src_addr, dst_addr, length); - bs->write_ref_array(MemRegion((HeapWord*)dst_addr, - (HeapWord*)(dst_addr + length))); - return ac_ok; - } + oop *src_addr = objArrayOop(src)->obj_at_addr(src_pos); + oop *dst_addr = objArrayOop(dst)->obj_at_addr(dst_pos); + return obj_arraycopy_work(src, src_addr, dst, dst_addr, length); } } return ac_failed; -- cgit v1.2.3