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 7589 : 6700100: optimize inline_native_clone() for small objects with exact klass
Summary: optimize small instance clones as loads/stores
Reviewed-by:
*** 4473,4484 ****
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");
set_predefined_output_for_runtime_call(ac, ac->in(TypeFunc::Memory), raw_adr_type);
// 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
--- 4473,4487 ----
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);
! 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
*** 4539,4548 ****
--- 4542,4571 ----
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);
*** 4741,4751 ****
sfpt->set_i_o(map()->i_o());
sfpt->set_memory(map()->memory());
}
! bool notest = 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();
--- 4764,4774 ----
sfpt->set_i_o(map()->i_o());
sfpt->set_memory(map()->memory());
}
! 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();
*** 4845,4855 ****
}
}
if (!too_many_traps(Deoptimization::Reason_intrinsic) && !src->is_top() && !dest->is_top()) {
// validate arguments: enables transformation the ArrayCopyNode
! notest = true;
RegionNode* slow_region = new RegionNode(1);
record_for_igvn(slow_region);
// (1) src and dest are arrays.
--- 4868,4878 ----
}
}
if (!too_many_traps(Deoptimization::Reason_intrinsic) && !src->is_top() && !dest->is_top()) {
// validate arguments: enables transformation the ArrayCopyNode
! validated = true;
RegionNode* slow_region = new RegionNode(1);
record_for_igvn(slow_region);
// (1) src and dest are arrays.
*** 4920,4936 ****
// 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();
! }
Node* n = _gvn.transform(ac);
! assert(n == ac, "cannot disappear");
ac->connect_outputs(this);
return true;
}
--- 4943,4961 ----
// 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));
! ac->set_arraycopy(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);
+ }
return true;
}
src/share/vm/opto/library_call.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File