< prev index next >

src/hotspot/share/opto/graphKit.cpp

Print this page




3607   // Kill monitor from debug info
3608   map()->pop_monitor( );
3609 }
3610 
3611 //-------------------------------get_layout_helper-----------------------------
3612 // If the given klass is a constant or known to be an array,
3613 // fetch the constant layout helper value into constant_value
3614 // and return (Node*)NULL.  Otherwise, load the non-constant
3615 // layout helper value, and return the node which represents it.
3616 // This two-faced routine is useful because allocation sites
3617 // almost always feature constant types.
3618 Node* GraphKit::get_layout_helper(Node* klass_node, jint& constant_value) {
3619   const TypeKlassPtr* inst_klass = _gvn.type(klass_node)->isa_klassptr();
3620   if (!StressReflectiveCode && inst_klass != NULL) {
3621     ciKlass* klass = inst_klass->klass();
3622     assert(klass != NULL, "klass should not be NULL");
3623     bool    xklass = inst_klass->klass_is_exact();
3624     bool can_be_flattened = false;
3625     if (ValueArrayFlatten && klass->is_obj_array_klass()) {
3626       ciKlass* elem = klass->as_obj_array_klass()->element_klass();
3627       can_be_flattened = elem->is_java_lang_Object() || elem->is_interface();
3628     }
3629     if (xklass || (klass->is_array_klass() && !can_be_flattened)) {
3630       jint lhelper = klass->layout_helper();
3631       if (lhelper != Klass::_lh_neutral_value) {
3632         constant_value = lhelper;
3633         return (Node*) NULL;
3634       }
3635     }
3636   }
3637   constant_value = Klass::_lh_neutral_value;  // put in a known value
3638   Node* lhp = basic_plus_adr(klass_node, klass_node, in_bytes(Klass::layout_helper_offset()));
3639   return make_load(NULL, lhp, TypeInt::INT, T_INT, MemNode::unordered);
3640 }
3641 
3642 // We just put in an allocate/initialize with a big raw-memory effect.
3643 // Hook selected additional alias categories on the initialization.
3644 static void hook_memory_on_init(GraphKit& kit, int alias_idx,
3645                                 MergeMemNode* init_in_merge,
3646                                 Node* init_out_raw) {
3647   DEBUG_ONLY(Node* init_in_raw = init_in_merge->base_memory());


3997   set_all_memory(mem); // Create new memory state
3998 
3999   if (initial_slow_test->is_Bool()) {
4000     // Hide it behind a CMoveI, or else PhaseIdealLoop::split_up will get sick.
4001     initial_slow_test = initial_slow_test->as_Bool()->as_int_value(&_gvn);
4002   }
4003 
4004   const TypeOopPtr* ary_type = _gvn.type(klass_node)->is_klassptr()->as_instance_type();
4005   const TypeAryPtr* ary_ptr = ary_type->isa_aryptr();
4006   const Type* elem = NULL;
4007   ciKlass* elem_klass = NULL;
4008 
4009   // Compute default value and storage properties for value type arrays:
4010   // - null-ok:              MyValue.box[] (ciObjArrayKlass "[LMyValue")
4011   // - null-free:            MyValue.val[] (ciObjArrayKlass "[QMyValue")
4012   // - null-free, flattened: MyValue.val[] (ciValueArrayKlass "[QMyValue")
4013   Node* storage_properties = NULL;
4014   Node* default_value = NULL;
4015   Node* raw_default_value = NULL;
4016   int props_shift = UseCompressedClassPointers ? oopDesc::narrow_storage_props_shift : oopDesc::wide_storage_props_shift;
4017   if (ary_ptr != NULL) {
4018     // Array type is known
4019     elem = ary_ptr->elem();
4020     ciArrayKlass* ary_klass = ary_ptr->klass()->as_array_klass();
4021     elem_klass = ary_klass->element_klass();
4022 
4023     ArrayStorageProperties props = ary_klass->storage_properties();
4024     if (!props.is_empty() && elem_klass->is_valuetype()) {
4025       if (props.is_null_free() && !props.is_flattened()) {
4026         default_value = ValueTypeNode::default_oop(gvn(), elem_klass->as_value_klass());
4027         if (elem->isa_narrowoop()) {
4028           default_value = _gvn.transform(new EncodePNode(default_value, elem));
4029           raw_default_value = raw_default_for_coops(default_value, *this);
4030         } else {
4031           raw_default_value = _gvn.transform(new CastP2XNode(control(), default_value));
4032         }
4033       }
4034       storage_properties = MakeConX(props.encode<NOT_LP64(jint) LP64_ONLY(jlong)>(props_shift));
4035     }
4036   }
4037 
4038   if (EnableValhalla && (elem == NULL || (elem_klass != NULL && elem_klass->is_java_lang_Object() && !ary_type->klass_is_exact()))) {

4039     // Array type is not known, compute default value and storage properties for initialization.
4040     assert(raw_default_value == NULL && storage_properties == NULL, "shouldn't be set yet");
4041     assert(elem_mirror != NULL, "should not be null");
4042 
4043     Node* r = new RegionNode(4);
4044     raw_default_value = new PhiNode(r, TypeX_X);
4045     storage_properties = new PhiNode(r, TypeX_X);
4046 
4047     Node* empty     = MakeConX(ArrayStorageProperties::empty.encode<NOT_LP64(jint) LP64_ONLY(jlong)>(props_shift));
4048     Node* null_free = MakeConX(ArrayStorageProperties::null_free.encode<NOT_LP64(jint) LP64_ONLY(jlong)>(props_shift));
4049     Node* flat      = MakeConX(ArrayStorageProperties::flattened_and_null_free.encode<NOT_LP64(jint) LP64_ONLY(jlong)>(props_shift));
4050 
4051     // Check if element mirror is a value mirror
4052     Node* p = basic_plus_adr(elem_mirror, java_lang_Class::value_mirror_offset_in_bytes());
4053     Node* value_mirror = access_load_at(elem_mirror, p, _gvn.type(p)->is_ptr(), TypeInstPtr::MIRROR->cast_to_ptr_type(TypePtr::BotPTR), T_OBJECT, IN_HEAP);
4054     Node* cmp = _gvn.transform(new CmpPNode(elem_mirror, value_mirror));
4055     Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::eq));
4056     IfNode* iff = create_and_map_if(control(), bol, PROB_FAIR, COUNT_UNKNOWN);
4057 
4058     // Not a value mirror but a box mirror or not a value type array, initialize with all zero




3607   // Kill monitor from debug info
3608   map()->pop_monitor( );
3609 }
3610 
3611 //-------------------------------get_layout_helper-----------------------------
3612 // If the given klass is a constant or known to be an array,
3613 // fetch the constant layout helper value into constant_value
3614 // and return (Node*)NULL.  Otherwise, load the non-constant
3615 // layout helper value, and return the node which represents it.
3616 // This two-faced routine is useful because allocation sites
3617 // almost always feature constant types.
3618 Node* GraphKit::get_layout_helper(Node* klass_node, jint& constant_value) {
3619   const TypeKlassPtr* inst_klass = _gvn.type(klass_node)->isa_klassptr();
3620   if (!StressReflectiveCode && inst_klass != NULL) {
3621     ciKlass* klass = inst_klass->klass();
3622     assert(klass != NULL, "klass should not be NULL");
3623     bool    xklass = inst_klass->klass_is_exact();
3624     bool can_be_flattened = false;
3625     if (ValueArrayFlatten && klass->is_obj_array_klass()) {
3626       ciKlass* elem = klass->as_obj_array_klass()->element_klass();
3627       can_be_flattened = elem->is_java_lang_Object() || elem->is_interface() || (elem->is_valuetype() && !klass->as_array_klass()->storage_properties().is_null_free());
3628     }
3629     if (xklass || (klass->is_array_klass() && !can_be_flattened)) {
3630       jint lhelper = klass->layout_helper();
3631       if (lhelper != Klass::_lh_neutral_value) {
3632         constant_value = lhelper;
3633         return (Node*) NULL;
3634       }
3635     }
3636   }
3637   constant_value = Klass::_lh_neutral_value;  // put in a known value
3638   Node* lhp = basic_plus_adr(klass_node, klass_node, in_bytes(Klass::layout_helper_offset()));
3639   return make_load(NULL, lhp, TypeInt::INT, T_INT, MemNode::unordered);
3640 }
3641 
3642 // We just put in an allocate/initialize with a big raw-memory effect.
3643 // Hook selected additional alias categories on the initialization.
3644 static void hook_memory_on_init(GraphKit& kit, int alias_idx,
3645                                 MergeMemNode* init_in_merge,
3646                                 Node* init_out_raw) {
3647   DEBUG_ONLY(Node* init_in_raw = init_in_merge->base_memory());


3997   set_all_memory(mem); // Create new memory state
3998 
3999   if (initial_slow_test->is_Bool()) {
4000     // Hide it behind a CMoveI, or else PhaseIdealLoop::split_up will get sick.
4001     initial_slow_test = initial_slow_test->as_Bool()->as_int_value(&_gvn);
4002   }
4003 
4004   const TypeOopPtr* ary_type = _gvn.type(klass_node)->is_klassptr()->as_instance_type();
4005   const TypeAryPtr* ary_ptr = ary_type->isa_aryptr();
4006   const Type* elem = NULL;
4007   ciKlass* elem_klass = NULL;
4008 
4009   // Compute default value and storage properties for value type arrays:
4010   // - null-ok:              MyValue.box[] (ciObjArrayKlass "[LMyValue")
4011   // - null-free:            MyValue.val[] (ciObjArrayKlass "[QMyValue")
4012   // - null-free, flattened: MyValue.val[] (ciValueArrayKlass "[QMyValue")
4013   Node* storage_properties = NULL;
4014   Node* default_value = NULL;
4015   Node* raw_default_value = NULL;
4016   int props_shift = UseCompressedClassPointers ? oopDesc::narrow_storage_props_shift : oopDesc::wide_storage_props_shift;
4017   if (ary_ptr != NULL && ary_ptr->klass_is_exact()) {
4018     // Array type is known
4019     elem = ary_ptr->elem();
4020     ciArrayKlass* ary_klass = ary_ptr->klass()->as_array_klass();
4021     elem_klass = ary_klass->element_klass();
4022 
4023     ArrayStorageProperties props = ary_klass->storage_properties();
4024     if (!props.is_empty() && elem_klass->is_valuetype()) {
4025       if (props.is_null_free() && !props.is_flattened()) {
4026         default_value = ValueTypeNode::default_oop(gvn(), elem_klass->as_value_klass());
4027         if (elem->isa_narrowoop()) {
4028           default_value = _gvn.transform(new EncodePNode(default_value, elem));
4029           raw_default_value = raw_default_for_coops(default_value, *this);
4030         } else {
4031           raw_default_value = _gvn.transform(new CastP2XNode(control(), default_value));
4032         }
4033       }
4034       storage_properties = MakeConX(props.encode<NOT_LP64(jint) LP64_ONLY(jlong)>(props_shift));
4035     }
4036   }
4037 
4038   if (EnableValhalla && (elem == NULL || (elem_klass != NULL && (elem_klass->is_java_lang_Object() || elem_klass->is_valuetype()) &&
4039                                           !ary_type->klass_is_exact()))) {
4040     // Array type is not known, compute default value and storage properties for initialization.
4041     assert(raw_default_value == NULL && storage_properties == NULL, "shouldn't be set yet");
4042     assert(elem_mirror != NULL, "should not be null");
4043 
4044     Node* r = new RegionNode(4);
4045     raw_default_value = new PhiNode(r, TypeX_X);
4046     storage_properties = new PhiNode(r, TypeX_X);
4047 
4048     Node* empty     = MakeConX(ArrayStorageProperties::empty.encode<NOT_LP64(jint) LP64_ONLY(jlong)>(props_shift));
4049     Node* null_free = MakeConX(ArrayStorageProperties::null_free.encode<NOT_LP64(jint) LP64_ONLY(jlong)>(props_shift));
4050     Node* flat      = MakeConX(ArrayStorageProperties::flattened_and_null_free.encode<NOT_LP64(jint) LP64_ONLY(jlong)>(props_shift));
4051 
4052     // Check if element mirror is a value mirror
4053     Node* p = basic_plus_adr(elem_mirror, java_lang_Class::value_mirror_offset_in_bytes());
4054     Node* value_mirror = access_load_at(elem_mirror, p, _gvn.type(p)->is_ptr(), TypeInstPtr::MIRROR->cast_to_ptr_type(TypePtr::BotPTR), T_OBJECT, IN_HEAP);
4055     Node* cmp = _gvn.transform(new CmpPNode(elem_mirror, value_mirror));
4056     Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::eq));
4057     IfNode* iff = create_and_map_if(control(), bol, PROB_FAIR, COUNT_UNKNOWN);
4058 
4059     // Not a value mirror but a box mirror or not a value type array, initialize with all zero


< prev index next >