1.1 --- a/src/share/vm/oops/objArrayKlass.cpp Wed Jun 04 13:51:09 2008 -0700 1.2 +++ b/src/share/vm/oops/objArrayKlass.cpp Thu Jun 05 15:57:56 2008 -0700 1.3 @@ -86,14 +86,18 @@ 1.4 1.5 const size_t word_len = objArrayOopDesc::array_size(length); 1.6 1.7 - // For performance reasons, we assume we are using a card marking write 1.8 - // barrier. The assert will fail if this is not the case. 1.9 BarrierSet* bs = Universe::heap()->barrier_set(); 1.10 + // For performance reasons, we assume we are that the write barrier we 1.11 + // are using has optimized modes for arrays of references. At least one 1.12 + // of the asserts below will fail if this is not the case. 1.13 assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt"); 1.14 + assert(bs->has_write_ref_array_pre_opt(), "For pre-barrier as well."); 1.15 1.16 + MemRegion dst_mr = MemRegion((HeapWord*)dst, word_len); 1.17 if (s == d) { 1.18 // since source and destination are equal we do not need conversion checks. 1.19 assert(length > 0, "sanity check"); 1.20 + bs->write_ref_array_pre(dst_mr); 1.21 Copy::conjoint_oops_atomic(src, dst, length); 1.22 } else { 1.23 // We have to make sure all elements conform to the destination array 1.24 @@ -101,6 +105,7 @@ 1.25 klassOop stype = objArrayKlass::cast(s->klass())->element_klass(); 1.26 if (stype == bound || Klass::cast(stype)->is_subtype_of(bound)) { 1.27 // elements are guaranteed to be subtypes, so no check necessary 1.28 + bs->write_ref_array_pre(dst_mr); 1.29 Copy::conjoint_oops_atomic(src, dst, length); 1.30 } else { 1.31 // slow case: need individual subtype checks 1.32 @@ -110,8 +115,13 @@ 1.33 for (T* p = dst; from < end; from++, p++) { 1.34 // XXX this is going to be slow. 1.35 T element = *from; 1.36 - if (oopDesc::is_null(element) || 1.37 - Klass::cast(oopDesc::decode_heap_oop_not_null(element)->klass())->is_subtype_of(bound)) { 1.38 + // even slower now 1.39 + bool element_is_null = oopDesc::is_null(element); 1.40 + oop new_val = element_is_null ? oop(NULL) 1.41 + : oopDesc::decode_heap_oop_not_null(element); 1.42 + if (element_is_null || 1.43 + Klass::cast((new_val->klass()))->is_subtype_of(bound)) { 1.44 + bs->write_ref_field_pre(p, new_val); 1.45 *p = *from; 1.46 } else { 1.47 // We must do a barrier to cover the partial copy. 1.48 @@ -401,11 +411,11 @@ 1.49 } 1.50 1.51 ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayKlass_OOP_OOP_ITERATE_DEFN) 1.52 -ALL_OOP_OOP_ITERATE_CLOSURES_3(ObjArrayKlass_OOP_OOP_ITERATE_DEFN) 1.53 +ALL_OOP_OOP_ITERATE_CLOSURES_2(ObjArrayKlass_OOP_OOP_ITERATE_DEFN) 1.54 ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_m) 1.55 -ALL_OOP_OOP_ITERATE_CLOSURES_3(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_m) 1.56 +ALL_OOP_OOP_ITERATE_CLOSURES_2(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_m) 1.57 ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_r) 1.58 -ALL_OOP_OOP_ITERATE_CLOSURES_3(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_r) 1.59 +ALL_OOP_OOP_ITERATE_CLOSURES_2(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_r) 1.60 1.61 int objArrayKlass::oop_adjust_pointers(oop obj) { 1.62 assert(obj->is_objArray(), "obj must be obj array");