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

src/share/vm/opto/library_call.cpp

Print this page




3206   generate_negative_guard(end,   bailout, &end);
3207 
3208   Node* length = end;
3209   if (_gvn.type(start) != TypeInt::ZERO) {
3210     length = _gvn.transform( new (C, 3) SubINode(end, start) );
3211   }
3212 
3213   // Bail out if length is negative.
3214   // ...Not needed, since the new_array will throw the right exception.
3215   //generate_negative_guard(length, bailout, &length);
3216 
3217   if (bailout->req() > 1) {
3218     PreserveJVMState pjvms(this);
3219     set_control( _gvn.transform(bailout) );
3220     _sp += nargs;  // push the arguments back on the stack
3221     uncommon_trap(Deoptimization::Reason_intrinsic,
3222                   Deoptimization::Action_maybe_recompile);
3223   }
3224 
3225   if (!stopped()) {





3226     // How many elements will we copy from the original?
3227     // The answer is MinI(orig_length - start, length).
3228     Node* orig_tail = _gvn.transform( new(C, 3) SubINode(orig_length, start) );
3229     Node* moved = generate_min_max(vmIntrinsics::_min, orig_tail, length);
3230 
3231     const bool raw_mem_only = true;
3232     Node* newcopy = new_array(klass_node, length, nargs, raw_mem_only);
3233 
3234     // Generate a direct call to the right arraycopy function(s).
3235     // We know the copy is disjoint but we might not know if the
3236     // oop stores need checking.
3237     // Extreme case:  Arrays.copyOf((Integer[])x, 10, String[].class).
3238     // This will fail a store-check if x contains any non-nulls.
3239     bool disjoint_bases = true;
3240     bool length_never_negative = true;
3241     generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT,
3242                        original, start, newcopy, intcon(0), moved,
3243                        disjoint_bases, length_never_negative);


3244 
3245     push(newcopy);
3246   }
3247 
3248   C->set_has_split_ifs(true); // Has chance for split-if optimization
3249 
3250   return true;
3251 }
3252 
3253 
3254 //----------------------generate_virtual_guard---------------------------
3255 // Helper for hashCode and clone.  Peeks inside the vtable to avoid a call.
3256 Node* LibraryCallKit::generate_virtual_guard(Node* obj_klass,
3257                                              RegionNode* slow_region) {
3258   ciMethod* method = callee();
3259   int vtable_index = method->vtable_index();
3260   // Get the methodOop out of the appropriate vtable entry.
3261   int entry_offset  = (instanceKlass::vtable_start_offset() +
3262                      vtable_index*vtableEntry::size()) * wordSize +
3263                      vtableEntry::method_offset_in_bytes();


4008   // paths into result_reg:
4009   enum {
4010     _slow_path = 1,     // out-of-line call to clone method (virtual or not)
4011     _objArray_path,     // plain array allocation, plus arrayof_oop_arraycopy
4012     _array_path,        // plain array allocation, plus arrayof_long_arraycopy
4013     _instance_path,     // plain instance allocation, plus arrayof_long_arraycopy
4014     PATH_LIMIT
4015   };
4016   RegionNode* result_reg = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT);
4017   PhiNode*    result_val = new(C, PATH_LIMIT) PhiNode(result_reg,
4018                                                       TypeInstPtr::NOTNULL);
4019   PhiNode*    result_i_o = new(C, PATH_LIMIT) PhiNode(result_reg, Type::ABIO);
4020   PhiNode*    result_mem = new(C, PATH_LIMIT) PhiNode(result_reg, Type::MEMORY,
4021                                                       TypePtr::BOTTOM);
4022   record_for_igvn(result_reg);
4023 
4024   const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM;
4025   int raw_adr_idx = Compile::AliasIdxRaw;
4026   const bool raw_mem_only = true;
4027 





4028   Node* array_ctl = generate_array_guard(obj_klass, (RegionNode*)NULL);
4029   if (array_ctl != NULL) {
4030     // It's an array.
4031     PreserveJVMState pjvms(this);
4032     set_control(array_ctl);
4033     Node* obj_length = load_array_length(obj);
4034     Node* obj_size = NULL;
4035     Node* alloc_obj = new_array(obj_klass, obj_length, nargs,
4036                                 raw_mem_only, &obj_size);
4037 
4038     if (!use_ReduceInitialCardMarks()) {
4039       // If it is an oop array, it requires very special treatment,
4040       // because card marking is required on each card of the array.
4041       Node* is_obja = generate_objArray_guard(obj_klass, (RegionNode*)NULL);
4042       if (is_obja != NULL) {
4043         PreserveJVMState pjvms2(this);
4044         set_control(is_obja);
4045         // Generate a direct call to the right arraycopy function(s).
4046         bool disjoint_bases = true;
4047         bool length_never_negative = true;


4112     // Present the results of the slow call.
4113     result_reg->init_req(_instance_path, control());
4114     result_val->init_req(_instance_path, alloc_obj);
4115     result_i_o ->set_req(_instance_path, i_o());
4116     result_mem ->set_req(_instance_path, reset_memory());
4117   }
4118 
4119   // Generate code for the slow case.  We make a call to clone().
4120   set_control(_gvn.transform(slow_region));
4121   if (!stopped()) {
4122     PreserveJVMState pjvms(this);
4123     CallJavaNode* slow_call = generate_method_call(vmIntrinsics::_clone, is_virtual);
4124     Node* slow_result = set_results_for_java_call(slow_call);
4125     // this->control() comes from set_results_for_java_call
4126     result_reg->init_req(_slow_path, control());
4127     result_val->init_req(_slow_path, slow_result);
4128     result_i_o ->set_req(_slow_path, i_o());
4129     result_mem ->set_req(_slow_path, reset_memory());
4130   }
4131 



4132   // Return the combined state.
4133   set_control(    _gvn.transform(result_reg) );
4134   set_i_o(        _gvn.transform(result_i_o) );
4135   set_all_memory( _gvn.transform(result_mem) );
4136 
4137   push(_gvn.transform(result_val));
4138 
4139   return true;
4140 }
4141 
4142 
4143 // constants for computing the copy function
4144 enum {
4145   COPYFUNC_UNALIGNED = 0,
4146   COPYFUNC_ALIGNED = 1,                 // src, dest aligned to HeapWordSize
4147   COPYFUNC_CONJOINT = 0,
4148   COPYFUNC_DISJOINT = 2                 // src != dest, or transfer can descend
4149 };
4150 
4151 // Note:  The condition "disjoint" applies also for overlapping copies




3206   generate_negative_guard(end,   bailout, &end);
3207 
3208   Node* length = end;
3209   if (_gvn.type(start) != TypeInt::ZERO) {
3210     length = _gvn.transform( new (C, 3) SubINode(end, start) );
3211   }
3212 
3213   // Bail out if length is negative.
3214   // ...Not needed, since the new_array will throw the right exception.
3215   //generate_negative_guard(length, bailout, &length);
3216 
3217   if (bailout->req() > 1) {
3218     PreserveJVMState pjvms(this);
3219     set_control( _gvn.transform(bailout) );
3220     _sp += nargs;  // push the arguments back on the stack
3221     uncommon_trap(Deoptimization::Reason_intrinsic,
3222                   Deoptimization::Action_maybe_recompile);
3223   }
3224 
3225   if (!stopped()) {
3226     //set the original stack and the restart bit for deopt to restart
3227     _sp += nargs;
3228     assert(!jvms()->is_restart(), "restart should not have been set (?)");
3229     jvms()->set_restart(true);
3230 
3231     // How many elements will we copy from the original?
3232     // The answer is MinI(orig_length - start, length).
3233     Node* orig_tail = _gvn.transform( new(C, 3) SubINode(orig_length, start) );
3234     Node* moved = generate_min_max(vmIntrinsics::_min, orig_tail, length);
3235 
3236     const bool raw_mem_only = true;
3237     Node* newcopy = new_array(klass_node, length, 0, raw_mem_only);
3238 
3239     // Generate a direct call to the right arraycopy function(s).
3240     // We know the copy is disjoint but we might not know if the
3241     // oop stores need checking.
3242     // Extreme case:  Arrays.copyOf((Integer[])x, 10, String[].class).
3243     // This will fail a store-check if x contains any non-nulls.
3244     bool disjoint_bases = true;
3245     bool length_never_negative = true;
3246     generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT,
3247                        original, start, newcopy, intcon(0), moved,
3248                        disjoint_bases, length_never_negative);
3249     _sp -= nargs;
3250     jvms()->set_restart(false);
3251 
3252     push(newcopy);
3253   }
3254 
3255   C->set_has_split_ifs(true); // Has chance for split-if optimization
3256 
3257   return true;
3258 }
3259 
3260 
3261 //----------------------generate_virtual_guard---------------------------
3262 // Helper for hashCode and clone.  Peeks inside the vtable to avoid a call.
3263 Node* LibraryCallKit::generate_virtual_guard(Node* obj_klass,
3264                                              RegionNode* slow_region) {
3265   ciMethod* method = callee();
3266   int vtable_index = method->vtable_index();
3267   // Get the methodOop out of the appropriate vtable entry.
3268   int entry_offset  = (instanceKlass::vtable_start_offset() +
3269                      vtable_index*vtableEntry::size()) * wordSize +
3270                      vtableEntry::method_offset_in_bytes();


4015   // paths into result_reg:
4016   enum {
4017     _slow_path = 1,     // out-of-line call to clone method (virtual or not)
4018     _objArray_path,     // plain array allocation, plus arrayof_oop_arraycopy
4019     _array_path,        // plain array allocation, plus arrayof_long_arraycopy
4020     _instance_path,     // plain instance allocation, plus arrayof_long_arraycopy
4021     PATH_LIMIT
4022   };
4023   RegionNode* result_reg = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT);
4024   PhiNode*    result_val = new(C, PATH_LIMIT) PhiNode(result_reg,
4025                                                       TypeInstPtr::NOTNULL);
4026   PhiNode*    result_i_o = new(C, PATH_LIMIT) PhiNode(result_reg, Type::ABIO);
4027   PhiNode*    result_mem = new(C, PATH_LIMIT) PhiNode(result_reg, Type::MEMORY,
4028                                                       TypePtr::BOTTOM);
4029   record_for_igvn(result_reg);
4030 
4031   const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM;
4032   int raw_adr_idx = Compile::AliasIdxRaw;
4033   const bool raw_mem_only = true;
4034 
4035   //set the original stack and the restart bit for deopt to restart
4036   _sp += nargs;
4037   assert(!jvms()->is_restart(), "restart should not have been set (?)");
4038   jvms()->set_restart(true);
4039 
4040   Node* array_ctl = generate_array_guard(obj_klass, (RegionNode*)NULL);
4041   if (array_ctl != NULL) {
4042     // It's an array.
4043     PreserveJVMState pjvms(this);
4044     set_control(array_ctl);
4045     Node* obj_length = load_array_length(obj);
4046     Node* obj_size = NULL;
4047     Node* alloc_obj = new_array(obj_klass, obj_length, nargs,
4048                                 raw_mem_only, &obj_size);
4049 
4050     if (!use_ReduceInitialCardMarks()) {
4051       // If it is an oop array, it requires very special treatment,
4052       // because card marking is required on each card of the array.
4053       Node* is_obja = generate_objArray_guard(obj_klass, (RegionNode*)NULL);
4054       if (is_obja != NULL) {
4055         PreserveJVMState pjvms2(this);
4056         set_control(is_obja);
4057         // Generate a direct call to the right arraycopy function(s).
4058         bool disjoint_bases = true;
4059         bool length_never_negative = true;


4124     // Present the results of the slow call.
4125     result_reg->init_req(_instance_path, control());
4126     result_val->init_req(_instance_path, alloc_obj);
4127     result_i_o ->set_req(_instance_path, i_o());
4128     result_mem ->set_req(_instance_path, reset_memory());
4129   }
4130 
4131   // Generate code for the slow case.  We make a call to clone().
4132   set_control(_gvn.transform(slow_region));
4133   if (!stopped()) {
4134     PreserveJVMState pjvms(this);
4135     CallJavaNode* slow_call = generate_method_call(vmIntrinsics::_clone, is_virtual);
4136     Node* slow_result = set_results_for_java_call(slow_call);
4137     // this->control() comes from set_results_for_java_call
4138     result_reg->init_req(_slow_path, control());
4139     result_val->init_req(_slow_path, slow_result);
4140     result_i_o ->set_req(_slow_path, i_o());
4141     result_mem ->set_req(_slow_path, reset_memory());
4142   }
4143 
4144   _sp -= nargs;
4145   jvms()->set_restart(false);
4146 
4147   // Return the combined state.
4148   set_control(    _gvn.transform(result_reg) );
4149   set_i_o(        _gvn.transform(result_i_o) );
4150   set_all_memory( _gvn.transform(result_mem) );
4151 
4152   push(_gvn.transform(result_val));
4153 
4154   return true;
4155 }
4156 
4157 
4158 // constants for computing the copy function
4159 enum {
4160   COPYFUNC_UNALIGNED = 0,
4161   COPYFUNC_ALIGNED = 1,                 // src, dest aligned to HeapWordSize
4162   COPYFUNC_CONJOINT = 0,
4163   COPYFUNC_DISJOINT = 2                 // src != dest, or transfer can descend
4164 };
4165 
4166 // Note:  The condition "disjoint" applies also for overlapping copies


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