src/share/vm/opto/library_call.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File
*** old/src/share/vm/opto/library_call.cpp	Thu Oct 23 13:31:09 2014
--- new/src/share/vm/opto/library_call.cpp	Thu Oct 23 13:31:08 2014

*** 4387,4398 **** --- 4387,4401 ---- const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; ArrayCopyNode* ac = ArrayCopyNode::make(this, false, src, NULL, dest, NULL, countx, false); ac->set_clonebasic(); Node* n = _gvn.transform(ac); assert(n == ac, "cannot disappear"); + if (n == ac) { set_predefined_output_for_runtime_call(ac, ac->in(TypeFunc::Memory), raw_adr_type); + } else { + set_all_memory(n); + } // If necessary, emit some card marks afterwards. (Non-arrays only.) if (card_mark) { assert(!is_array, ""); // Put in store barrier for any and all oops we are sticking
*** 4453,4462 **** --- 4456,4485 ---- jvms()->set_should_reexecute(true); Node* obj = null_check_receiver(); if (stopped()) return true; + const TypeOopPtr* obj_type = _gvn.type(obj)->is_oopptr(); + + // If we are going to clone an instance, we need its exact type to + // know the number and types of fields to convert the clone to + // loads/stores. Maybe a speculative type can help us. + if (!obj_type->klass_is_exact() && + obj_type->speculative_type() != NULL && + obj_type->speculative_type()->is_instance_klass()) { + ciInstanceKlass* spec_ik = obj_type->speculative_type()->as_instance_klass(); + if (spec_ik->nof_nonstatic_fields() <= ArrayCopyLoadStoreMaxElem && + !spec_ik->has_injected_fields()) { + ciKlass* k = obj_type->klass(); + if (!k->is_instance_klass() || + k->as_instance_klass()->is_interface() || + k->as_instance_klass()->has_subklass()) { + obj = maybe_cast_profiled_obj(obj, obj_type->speculative_type(), false); + } + } + } + Node* obj_klass = load_object_klass(obj); const TypeKlassPtr* tklass = _gvn.type(obj_klass)->isa_klassptr(); const TypeOopPtr* toop = ((tklass != NULL) ? tklass->as_instance_type() : TypeInstPtr::NOTNULL);
*** 4629,4639 **** --- 4652,4662 ---- // (3) src and dest must not be null. // always do this here because we need the JVM state for uncommon traps src = null_check(src, T_ARRAY); dest = null_check(dest, T_ARRAY); ! bool notest = false; ! bool validated = false; const Type* src_type = _gvn.type(src); const Type* dest_type = _gvn.type(dest); const TypeAryPtr* top_src = src_type->isa_aryptr(); const TypeAryPtr* top_dest = dest_type->isa_aryptr();
*** 4733,4743 **** --- 4756,4766 ---- } } if (!too_many_traps(Deoptimization::Reason_intrinsic) && !src->is_top() && !dest->is_top()) { // validate arguments: enables transformation the ArrayCopyNode ! notest = true; ! validated = true; RegionNode* slow_region = new RegionNode(1); record_for_igvn(slow_region); // (1) src and dest are arrays.
*** 4793,4809 **** --- 4816,4834 ---- // so the compiler has a chance to eliminate them: during macro expansion, // we have to set their control (CastPP nodes are eliminated). load_object_klass(src), load_object_klass(dest), load_array_length(src), load_array_length(dest)); if (notest) { ac->set_arraycopy_notest(); } + ac->set_arraycopy(validated); Node* n = _gvn.transform(ac); assert(n == ac, "cannot disappear"); + if (n == ac) { ac->connect_outputs(this); + } else { + assert(validated, "shouldn't transform if all arguments not validated"); + set_all_memory(n); + } return true; }

src/share/vm/opto/library_call.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File