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 PreserveReexecuteAndSP preexecsp(this);
3231 _sp += nargs;
3232 jvms()->set_reexecute(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 PreserveReexecuteAndSP preexecsp(this);
4040 _sp += nargs;
4041 jvms()->set_reexecute(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
|