1.1 --- a/src/share/vm/opto/library_call.cpp Fri Jul 31 12:04:07 2009 -0700 1.2 +++ b/src/share/vm/opto/library_call.cpp Fri Jul 31 17:12:33 2009 -0700 1.3 @@ -3222,24 +3222,32 @@ 1.4 } 1.5 1.6 if (!stopped()) { 1.7 - // How many elements will we copy from the original? 1.8 - // The answer is MinI(orig_length - start, length). 1.9 - Node* orig_tail = _gvn.transform( new(C, 3) SubINode(orig_length, start) ); 1.10 - Node* moved = generate_min_max(vmIntrinsics::_min, orig_tail, length); 1.11 - 1.12 - const bool raw_mem_only = true; 1.13 - Node* newcopy = new_array(klass_node, length, nargs, raw_mem_only); 1.14 - 1.15 - // Generate a direct call to the right arraycopy function(s). 1.16 - // We know the copy is disjoint but we might not know if the 1.17 - // oop stores need checking. 1.18 - // Extreme case: Arrays.copyOf((Integer[])x, 10, String[].class). 1.19 - // This will fail a store-check if x contains any non-nulls. 1.20 - bool disjoint_bases = true; 1.21 - bool length_never_negative = true; 1.22 - generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT, 1.23 - original, start, newcopy, intcon(0), moved, 1.24 - disjoint_bases, length_never_negative); 1.25 + Node *newcopy; 1.26 + //set the original stack and the reexecute bit for the interpreter to reexecute 1.27 + //the bytecode that invokes Arrays.copyOf if deoptimization happens 1.28 + { PreserveReexecuteState preexecs(this); 1.29 + _sp += nargs; 1.30 + jvms()->set_should_reexecute(true); 1.31 + 1.32 + // How many elements will we copy from the original? 1.33 + // The answer is MinI(orig_length - start, length). 1.34 + Node* orig_tail = _gvn.transform( new(C, 3) SubINode(orig_length, start) ); 1.35 + Node* moved = generate_min_max(vmIntrinsics::_min, orig_tail, length); 1.36 + 1.37 + const bool raw_mem_only = true; 1.38 + newcopy = new_array(klass_node, length, 0, raw_mem_only); 1.39 + 1.40 + // Generate a direct call to the right arraycopy function(s). 1.41 + // We know the copy is disjoint but we might not know if the 1.42 + // oop stores need checking. 1.43 + // Extreme case: Arrays.copyOf((Integer[])x, 10, String[].class). 1.44 + // This will fail a store-check if x contains any non-nulls. 1.45 + bool disjoint_bases = true; 1.46 + bool length_never_negative = true; 1.47 + generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT, 1.48 + original, start, newcopy, intcon(0), moved, 1.49 + disjoint_bases, length_never_negative); 1.50 + } //original reexecute and sp are set back here 1.51 1.52 push(newcopy); 1.53 } 1.54 @@ -4024,109 +4032,116 @@ 1.55 int raw_adr_idx = Compile::AliasIdxRaw; 1.56 const bool raw_mem_only = true; 1.57 1.58 - Node* array_ctl = generate_array_guard(obj_klass, (RegionNode*)NULL); 1.59 - if (array_ctl != NULL) { 1.60 - // It's an array. 1.61 - PreserveJVMState pjvms(this); 1.62 - set_control(array_ctl); 1.63 - Node* obj_length = load_array_length(obj); 1.64 - Node* obj_size = NULL; 1.65 - Node* alloc_obj = new_array(obj_klass, obj_length, nargs, 1.66 - raw_mem_only, &obj_size); 1.67 - 1.68 - if (!use_ReduceInitialCardMarks()) { 1.69 - // If it is an oop array, it requires very special treatment, 1.70 - // because card marking is required on each card of the array. 1.71 - Node* is_obja = generate_objArray_guard(obj_klass, (RegionNode*)NULL); 1.72 - if (is_obja != NULL) { 1.73 - PreserveJVMState pjvms2(this); 1.74 - set_control(is_obja); 1.75 - // Generate a direct call to the right arraycopy function(s). 1.76 - bool disjoint_bases = true; 1.77 - bool length_never_negative = true; 1.78 - generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT, 1.79 - obj, intcon(0), alloc_obj, intcon(0), 1.80 - obj_length, 1.81 - disjoint_bases, length_never_negative); 1.82 - result_reg->init_req(_objArray_path, control()); 1.83 - result_val->init_req(_objArray_path, alloc_obj); 1.84 - result_i_o ->set_req(_objArray_path, i_o()); 1.85 - result_mem ->set_req(_objArray_path, reset_memory()); 1.86 + //set the original stack and the reexecute bit for the interpreter to reexecute 1.87 + //the bytecode that invokes Object.clone if deoptimization happens 1.88 + { PreserveReexecuteState preexecs(this); 1.89 + _sp += nargs; 1.90 + jvms()->set_should_reexecute(true); 1.91 + 1.92 + Node* array_ctl = generate_array_guard(obj_klass, (RegionNode*)NULL); 1.93 + if (array_ctl != NULL) { 1.94 + // It's an array. 1.95 + PreserveJVMState pjvms(this); 1.96 + set_control(array_ctl); 1.97 + Node* obj_length = load_array_length(obj); 1.98 + Node* obj_size = NULL; 1.99 + Node* alloc_obj = new_array(obj_klass, obj_length, 0, 1.100 + raw_mem_only, &obj_size); 1.101 + 1.102 + if (!use_ReduceInitialCardMarks()) { 1.103 + // If it is an oop array, it requires very special treatment, 1.104 + // because card marking is required on each card of the array. 1.105 + Node* is_obja = generate_objArray_guard(obj_klass, (RegionNode*)NULL); 1.106 + if (is_obja != NULL) { 1.107 + PreserveJVMState pjvms2(this); 1.108 + set_control(is_obja); 1.109 + // Generate a direct call to the right arraycopy function(s). 1.110 + bool disjoint_bases = true; 1.111 + bool length_never_negative = true; 1.112 + generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT, 1.113 + obj, intcon(0), alloc_obj, intcon(0), 1.114 + obj_length, 1.115 + disjoint_bases, length_never_negative); 1.116 + result_reg->init_req(_objArray_path, control()); 1.117 + result_val->init_req(_objArray_path, alloc_obj); 1.118 + result_i_o ->set_req(_objArray_path, i_o()); 1.119 + result_mem ->set_req(_objArray_path, reset_memory()); 1.120 + } 1.121 + } 1.122 + // We can dispense with card marks if we know the allocation 1.123 + // comes out of eden (TLAB)... In fact, ReduceInitialCardMarks 1.124 + // causes the non-eden paths to simulate a fresh allocation, 1.125 + // insofar that no further card marks are required to initialize 1.126 + // the object. 1.127 + 1.128 + // Otherwise, there are no card marks to worry about. 1.129 + 1.130 + if (!stopped()) { 1.131 + copy_to_clone(obj, alloc_obj, obj_size, true, false); 1.132 + 1.133 + // Present the results of the copy. 1.134 + result_reg->init_req(_array_path, control()); 1.135 + result_val->init_req(_array_path, alloc_obj); 1.136 + result_i_o ->set_req(_array_path, i_o()); 1.137 + result_mem ->set_req(_array_path, reset_memory()); 1.138 } 1.139 } 1.140 - // We can dispense with card marks if we know the allocation 1.141 - // comes out of eden (TLAB)... In fact, ReduceInitialCardMarks 1.142 - // causes the non-eden paths to simulate a fresh allocation, 1.143 - // insofar that no further card marks are required to initialize 1.144 - // the object. 1.145 - 1.146 - // Otherwise, there are no card marks to worry about. 1.147 - 1.148 + 1.149 + // We only go to the instance fast case code if we pass a number of guards. 1.150 + // The paths which do not pass are accumulated in the slow_region. 1.151 + RegionNode* slow_region = new (C, 1) RegionNode(1); 1.152 + record_for_igvn(slow_region); 1.153 if (!stopped()) { 1.154 - copy_to_clone(obj, alloc_obj, obj_size, true, false); 1.155 - 1.156 - // Present the results of the copy. 1.157 - result_reg->init_req(_array_path, control()); 1.158 - result_val->init_req(_array_path, alloc_obj); 1.159 - result_i_o ->set_req(_array_path, i_o()); 1.160 - result_mem ->set_req(_array_path, reset_memory()); 1.161 + // It's an instance (we did array above). Make the slow-path tests. 1.162 + // If this is a virtual call, we generate a funny guard. We grab 1.163 + // the vtable entry corresponding to clone() from the target object. 1.164 + // If the target method which we are calling happens to be the 1.165 + // Object clone() method, we pass the guard. We do not need this 1.166 + // guard for non-virtual calls; the caller is known to be the native 1.167 + // Object clone(). 1.168 + if (is_virtual) { 1.169 + generate_virtual_guard(obj_klass, slow_region); 1.170 + } 1.171 + 1.172 + // The object must be cloneable and must not have a finalizer. 1.173 + // Both of these conditions may be checked in a single test. 1.174 + // We could optimize the cloneable test further, but we don't care. 1.175 + generate_access_flags_guard(obj_klass, 1.176 + // Test both conditions: 1.177 + JVM_ACC_IS_CLONEABLE | JVM_ACC_HAS_FINALIZER, 1.178 + // Must be cloneable but not finalizer: 1.179 + JVM_ACC_IS_CLONEABLE, 1.180 + slow_region); 1.181 } 1.182 - } 1.183 - 1.184 - // We only go to the instance fast case code if we pass a number of guards. 1.185 - // The paths which do not pass are accumulated in the slow_region. 1.186 - RegionNode* slow_region = new (C, 1) RegionNode(1); 1.187 - record_for_igvn(slow_region); 1.188 - if (!stopped()) { 1.189 - // It's an instance (we did array above). Make the slow-path tests. 1.190 - // If this is a virtual call, we generate a funny guard. We grab 1.191 - // the vtable entry corresponding to clone() from the target object. 1.192 - // If the target method which we are calling happens to be the 1.193 - // Object clone() method, we pass the guard. We do not need this 1.194 - // guard for non-virtual calls; the caller is known to be the native 1.195 - // Object clone(). 1.196 - if (is_virtual) { 1.197 - generate_virtual_guard(obj_klass, slow_region); 1.198 + 1.199 + if (!stopped()) { 1.200 + // It's an instance, and it passed the slow-path tests. 1.201 + PreserveJVMState pjvms(this); 1.202 + Node* obj_size = NULL; 1.203 + Node* alloc_obj = new_instance(obj_klass, NULL, raw_mem_only, &obj_size); 1.204 + 1.205 + copy_to_clone(obj, alloc_obj, obj_size, false, !use_ReduceInitialCardMarks()); 1.206 + 1.207 + // Present the results of the slow call. 1.208 + result_reg->init_req(_instance_path, control()); 1.209 + result_val->init_req(_instance_path, alloc_obj); 1.210 + result_i_o ->set_req(_instance_path, i_o()); 1.211 + result_mem ->set_req(_instance_path, reset_memory()); 1.212 } 1.213 1.214 - // The object must be cloneable and must not have a finalizer. 1.215 - // Both of these conditions may be checked in a single test. 1.216 - // We could optimize the cloneable test further, but we don't care. 1.217 - generate_access_flags_guard(obj_klass, 1.218 - // Test both conditions: 1.219 - JVM_ACC_IS_CLONEABLE | JVM_ACC_HAS_FINALIZER, 1.220 - // Must be cloneable but not finalizer: 1.221 - JVM_ACC_IS_CLONEABLE, 1.222 - slow_region); 1.223 - } 1.224 - 1.225 - if (!stopped()) { 1.226 - // It's an instance, and it passed the slow-path tests. 1.227 - PreserveJVMState pjvms(this); 1.228 - Node* obj_size = NULL; 1.229 - Node* alloc_obj = new_instance(obj_klass, NULL, raw_mem_only, &obj_size); 1.230 - 1.231 - copy_to_clone(obj, alloc_obj, obj_size, false, !use_ReduceInitialCardMarks()); 1.232 - 1.233 - // Present the results of the slow call. 1.234 - result_reg->init_req(_instance_path, control()); 1.235 - result_val->init_req(_instance_path, alloc_obj); 1.236 - result_i_o ->set_req(_instance_path, i_o()); 1.237 - result_mem ->set_req(_instance_path, reset_memory()); 1.238 - } 1.239 - 1.240 - // Generate code for the slow case. We make a call to clone(). 1.241 - set_control(_gvn.transform(slow_region)); 1.242 - if (!stopped()) { 1.243 - PreserveJVMState pjvms(this); 1.244 - CallJavaNode* slow_call = generate_method_call(vmIntrinsics::_clone, is_virtual); 1.245 - Node* slow_result = set_results_for_java_call(slow_call); 1.246 - // this->control() comes from set_results_for_java_call 1.247 - result_reg->init_req(_slow_path, control()); 1.248 - result_val->init_req(_slow_path, slow_result); 1.249 - result_i_o ->set_req(_slow_path, i_o()); 1.250 - result_mem ->set_req(_slow_path, reset_memory()); 1.251 - } 1.252 + // Generate code for the slow case. We make a call to clone(). 1.253 + set_control(_gvn.transform(slow_region)); 1.254 + if (!stopped()) { 1.255 + PreserveJVMState pjvms(this); 1.256 + CallJavaNode* slow_call = generate_method_call(vmIntrinsics::_clone, is_virtual); 1.257 + Node* slow_result = set_results_for_java_call(slow_call); 1.258 + // this->control() comes from set_results_for_java_call 1.259 + result_reg->init_req(_slow_path, control()); 1.260 + result_val->init_req(_slow_path, slow_result); 1.261 + result_i_o ->set_req(_slow_path, i_o()); 1.262 + result_mem ->set_req(_slow_path, reset_memory()); 1.263 + } 1.264 + } //original reexecute and sp are set back here 1.265 1.266 // Return the combined state. 1.267 set_control( _gvn.transform(result_reg) );