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