src/share/vm/opto/library_call.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
hotspot Cdiff src/share/vm/opto/library_call.cpp
src/share/vm/opto/library_call.cpp
Print this page
rev 7687 : 6912521: System.arraycopy works slower than the simple loop for little lengths
Summary: convert small array copies to series of loads and stores
Reviewed-by:
*** 3947,3968 ****
// We know the copy is disjoint but we might not know if the
// oop stores need checking.
// Extreme case: Arrays.copyOf((Integer[])x, 10, String[].class).
// This will fail a store-check if x contains any non-nulls.
! Node* alloc = tightly_coupled_allocation(newcopy, NULL);
! ArrayCopyNode* ac = ArrayCopyNode::make(this, true, original, start, newcopy, intcon(0), moved, alloc != NULL,
load_object_klass(original), klass_node);
if (!is_copyOfRange) {
! ac->set_copyof();
} else {
! ac->set_copyofrange();
}
Node* n = _gvn.transform(ac);
! assert(n == ac, "cannot disappear");
ac->connect_outputs(this);
}
} // original reexecute is set back here
C->set_has_split_ifs(true); // Has chance for split-if optimization
if (!stopped()) {
--- 3947,4000 ----
// We know the copy is disjoint but we might not know if the
// oop stores need checking.
// Extreme case: Arrays.copyOf((Integer[])x, 10, String[].class).
// This will fail a store-check if x contains any non-nulls.
! if (_gvn.type(klass_node)->singleton()) {
! ciKlass* subk = _gvn.type(load_object_klass(original))->is_klassptr()->klass();
! ciKlass* superk = _gvn.type(klass_node)->is_klassptr()->klass();
! int test = C->static_subtype_check(superk, subk);
! if (test != Compile::SSC_always_true && test != Compile::SSC_always_false) {
! const TypeOopPtr* t_original = _gvn.type(original)->is_oopptr();
! if (t_original->speculative_type() != NULL) {
! original = maybe_cast_profiled_obj(original, t_original->speculative_type(), true);
! }
! }
! }
!
! bool validated = false;
! // Reason_class_check rather than Reason_intrinsic because we
! // want to intrinsify even if this traps.
! if (!too_many_traps(Deoptimization::Reason_class_check)) {
! Node* not_subtype_ctrl = gen_subtype_check(load_object_klass(original),
! klass_node);
!
! if (not_subtype_ctrl != top()) {
! PreserveJVMState pjvms(this);
! set_control(not_subtype_ctrl);
! uncommon_trap(Deoptimization::Reason_class_check,
! Deoptimization::Action_make_not_entrant);
! assert(stopped(), "Should be stopped");
! }
! validated = true;
! }
!
! ArrayCopyNode* ac = ArrayCopyNode::make(this, true, original, start, newcopy, intcon(0), moved, true,
load_object_klass(original), klass_node);
if (!is_copyOfRange) {
! ac->set_copyof(validated);
} else {
! ac->set_copyofrange(validated);
}
Node* n = _gvn.transform(ac);
! if (n == ac) {
ac->connect_outputs(this);
+ } else {
+ assert(validated, "shouldn't transform if all arguments not validated");
+ set_all_memory(n);
+ }
}
} // original reexecute is set back here
C->set_has_split_ifs(true); // Has chance for split-if optimization
if (!stopped()) {
src/share/vm/opto/library_call.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File