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();
3264   Node* entry_addr  = basic_plus_adr(obj_klass, entry_offset);


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;
4048         generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT,
4049                            obj, intcon(0), alloc_obj, intcon(0),
4050                            obj_length,
4051                            disjoint_bases, length_never_negative);
4052         result_reg->init_req(_objArray_path, control());
4053         result_val->init_req(_objArray_path, alloc_obj);
4054         result_i_o ->set_req(_objArray_path, i_o());
4055         result_mem ->set_req(_objArray_path, reset_memory());


4111 
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 




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     Node *newcopy;
3227     //set the original stack and the reexecute bit for the interpreter to reexecute
3228     //the bytecode that invokes Arrays.copyOf if deoptimization happens
3229     {
3230       PreserveReexecuteState preexecs(this);
3231       _sp += nargs;
3232       jvms()->set_reexecute(JVMState::RE_True);
3233 
3234       // How many elements will we copy from the original?
3235       // The answer is MinI(orig_length - start, length).
3236       Node* orig_tail = _gvn.transform( new(C, 3) SubINode(orig_length, start) );
3237       Node* moved = generate_min_max(vmIntrinsics::_min, orig_tail, length);
3238 
3239       const bool raw_mem_only = true;
3240       newcopy = new_array(klass_node, length, 0, raw_mem_only);
3241 
3242       // Generate a direct call to the right arraycopy function(s).
3243       // We know the copy is disjoint but we might not know if the
3244       // oop stores need checking.
3245       // Extreme case:  Arrays.copyOf((Integer[])x, 10, String[].class).
3246       // This will fail a store-check if x contains any non-nulls.
3247       bool disjoint_bases = true;
3248       bool length_never_negative = true;
3249       generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT,
3250                          original, start, newcopy, intcon(0), moved,
3251                          disjoint_bases, length_never_negative);
3252     } //original reexecute and sp are set back here
3253     push(newcopy);
3254   }
3255 
3256   C->set_has_split_ifs(true); // Has chance for split-if optimization
3257 
3258   return true;
3259 }
3260 
3261 
3262 //----------------------generate_virtual_guard---------------------------
3263 // Helper for hashCode and clone.  Peeks inside the vtable to avoid a call.
3264 Node* LibraryCallKit::generate_virtual_guard(Node* obj_klass,
3265                                              RegionNode* slow_region) {
3266   ciMethod* method = callee();
3267   int vtable_index = method->vtable_index();
3268   // Get the methodOop out of the appropriate vtable entry.
3269   int entry_offset  = (instanceKlass::vtable_start_offset() +
3270                      vtable_index*vtableEntry::size()) * wordSize +
3271                      vtableEntry::method_offset_in_bytes();
3272   Node* entry_addr  = basic_plus_adr(obj_klass, entry_offset);


4016   // paths into result_reg:
4017   enum {
4018     _slow_path = 1,     // out-of-line call to clone method (virtual or not)
4019     _objArray_path,     // plain array allocation, plus arrayof_oop_arraycopy
4020     _array_path,        // plain array allocation, plus arrayof_long_arraycopy
4021     _instance_path,     // plain instance allocation, plus arrayof_long_arraycopy
4022     PATH_LIMIT
4023   };
4024   RegionNode* result_reg = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT);
4025   PhiNode*    result_val = new(C, PATH_LIMIT) PhiNode(result_reg,
4026                                                       TypeInstPtr::NOTNULL);
4027   PhiNode*    result_i_o = new(C, PATH_LIMIT) PhiNode(result_reg, Type::ABIO);
4028   PhiNode*    result_mem = new(C, PATH_LIMIT) PhiNode(result_reg, Type::MEMORY,
4029                                                       TypePtr::BOTTOM);
4030   record_for_igvn(result_reg);
4031 
4032   const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM;
4033   int raw_adr_idx = Compile::AliasIdxRaw;
4034   const bool raw_mem_only = true;
4035 
4036   //set the original stack and the reexecute bit for the interpreter to reexecute
4037   //the bytecode that invokes Object.clone if deoptimization happens
4038   {
4039     PreserveReexecuteState preexecs(this);
4040     _sp += nargs;
4041     jvms()->set_reexecute(JVMState::RE_True);
4042 
4043     Node* array_ctl = generate_array_guard(obj_klass, (RegionNode*)NULL);
4044     if (array_ctl != NULL) {
4045       // It's an array.
4046       PreserveJVMState pjvms(this);
4047       set_control(array_ctl);
4048       Node* obj_length = load_array_length(obj);
4049       Node* obj_size = NULL;
4050       Node* alloc_obj = new_array(obj_klass, obj_length, 0,
4051                                   raw_mem_only, &obj_size);
4052 
4053       if (!use_ReduceInitialCardMarks()) {
4054         // If it is an oop array, it requires very special treatment,
4055         // because card marking is required on each card of the array.
4056         Node* is_obja = generate_objArray_guard(obj_klass, (RegionNode*)NULL);
4057         if (is_obja != NULL) {
4058           PreserveJVMState pjvms2(this);
4059           set_control(is_obja);
4060           // Generate a direct call to the right arraycopy function(s).
4061           bool disjoint_bases = true;
4062           bool length_never_negative = true;
4063           generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT,
4064                              obj, intcon(0), alloc_obj, intcon(0),
4065                              obj_length,
4066                              disjoint_bases, length_never_negative);
4067           result_reg->init_req(_objArray_path, control());
4068           result_val->init_req(_objArray_path, alloc_obj);
4069           result_i_o ->set_req(_objArray_path, i_o());
4070           result_mem ->set_req(_objArray_path, reset_memory());


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


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