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