Tue, 04 Aug 2009 21:32:08 -0700
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
Summary: Improvement on reexecute implementation to fix the assertion failure
Reviewed-by: kvn, never
src/share/vm/opto/library_call.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/opto/library_call.cpp Tue Aug 04 17:11:17 2009 -0700 1.2 +++ b/src/share/vm/opto/library_call.cpp Tue Aug 04 21:32:08 2009 -0700 1.3 @@ -3169,65 +3169,62 @@ 1.4 Node* end = is_copyOfRange? argument(2): argument(1); 1.5 Node* array_type_mirror = is_copyOfRange? argument(3): argument(2); 1.6 1.7 - _sp += nargs; // set original stack for use by uncommon_trap 1.8 - array_type_mirror = do_null_check(array_type_mirror, T_OBJECT); 1.9 - original = do_null_check(original, T_OBJECT); 1.10 - _sp -= nargs; 1.11 - 1.12 - // Check if a null path was taken unconditionally. 1.13 - if (stopped()) return true; 1.14 - 1.15 - Node* orig_length = load_array_length(original); 1.16 - 1.17 - Node* klass_node = load_klass_from_mirror(array_type_mirror, false, nargs, 1.18 - NULL, 0); 1.19 - _sp += nargs; // set original stack for use by uncommon_trap 1.20 - klass_node = do_null_check(klass_node, T_OBJECT); 1.21 - _sp -= nargs; 1.22 - 1.23 - RegionNode* bailout = new (C, 1) RegionNode(1); 1.24 - record_for_igvn(bailout); 1.25 - 1.26 - // Despite the generic type of Arrays.copyOf, the mirror might be int, int[], etc. 1.27 - // Bail out if that is so. 1.28 - Node* not_objArray = generate_non_objArray_guard(klass_node, bailout); 1.29 - if (not_objArray != NULL) { 1.30 - // Improve the klass node's type from the new optimistic assumption: 1.31 - ciKlass* ak = ciArrayKlass::make(env()->Object_klass()); 1.32 - const Type* akls = TypeKlassPtr::make(TypePtr::NotNull, ak, 0/*offset*/); 1.33 - Node* cast = new (C, 2) CastPPNode(klass_node, akls); 1.34 - cast->init_req(0, control()); 1.35 - klass_node = _gvn.transform(cast); 1.36 - } 1.37 - 1.38 - // Bail out if either start or end is negative. 1.39 - generate_negative_guard(start, bailout, &start); 1.40 - generate_negative_guard(end, bailout, &end); 1.41 - 1.42 - Node* length = end; 1.43 - if (_gvn.type(start) != TypeInt::ZERO) { 1.44 - length = _gvn.transform( new (C, 3) SubINode(end, start) ); 1.45 - } 1.46 - 1.47 - // Bail out if length is negative. 1.48 - // ...Not needed, since the new_array will throw the right exception. 1.49 - //generate_negative_guard(length, bailout, &length); 1.50 - 1.51 - if (bailout->req() > 1) { 1.52 - PreserveJVMState pjvms(this); 1.53 - set_control( _gvn.transform(bailout) ); 1.54 - _sp += nargs; // push the arguments back on the stack 1.55 - uncommon_trap(Deoptimization::Reason_intrinsic, 1.56 - Deoptimization::Action_maybe_recompile); 1.57 - } 1.58 - 1.59 - if (!stopped()) { 1.60 - Node *newcopy; 1.61 - //set the original stack and the reexecute bit for the interpreter to reexecute 1.62 - //the bytecode that invokes Arrays.copyOf if deoptimization happens 1.63 - { PreserveReexecuteState preexecs(this); 1.64 - _sp += nargs; 1.65 - jvms()->set_should_reexecute(true); 1.66 + Node* newcopy; 1.67 + 1.68 + //set the original stack and the reexecute bit for the interpreter to reexecute 1.69 + //the bytecode that invokes Arrays.copyOf if deoptimization happens 1.70 + { PreserveReexecuteState preexecs(this); 1.71 + _sp += nargs; 1.72 + jvms()->set_should_reexecute(true); 1.73 + 1.74 + array_type_mirror = do_null_check(array_type_mirror, T_OBJECT); 1.75 + original = do_null_check(original, T_OBJECT); 1.76 + 1.77 + // Check if a null path was taken unconditionally. 1.78 + if (stopped()) return true; 1.79 + 1.80 + Node* orig_length = load_array_length(original); 1.81 + 1.82 + Node* klass_node = load_klass_from_mirror(array_type_mirror, false, 0, 1.83 + NULL, 0); 1.84 + klass_node = do_null_check(klass_node, T_OBJECT); 1.85 + 1.86 + RegionNode* bailout = new (C, 1) RegionNode(1); 1.87 + record_for_igvn(bailout); 1.88 + 1.89 + // Despite the generic type of Arrays.copyOf, the mirror might be int, int[], etc. 1.90 + // Bail out if that is so. 1.91 + Node* not_objArray = generate_non_objArray_guard(klass_node, bailout); 1.92 + if (not_objArray != NULL) { 1.93 + // Improve the klass node's type from the new optimistic assumption: 1.94 + ciKlass* ak = ciArrayKlass::make(env()->Object_klass()); 1.95 + const Type* akls = TypeKlassPtr::make(TypePtr::NotNull, ak, 0/*offset*/); 1.96 + Node* cast = new (C, 2) CastPPNode(klass_node, akls); 1.97 + cast->init_req(0, control()); 1.98 + klass_node = _gvn.transform(cast); 1.99 + } 1.100 + 1.101 + // Bail out if either start or end is negative. 1.102 + generate_negative_guard(start, bailout, &start); 1.103 + generate_negative_guard(end, bailout, &end); 1.104 + 1.105 + Node* length = end; 1.106 + if (_gvn.type(start) != TypeInt::ZERO) { 1.107 + length = _gvn.transform( new (C, 3) SubINode(end, start) ); 1.108 + } 1.109 + 1.110 + // Bail out if length is negative. 1.111 + // ...Not needed, since the new_array will throw the right exception. 1.112 + //generate_negative_guard(length, bailout, &length); 1.113 + 1.114 + if (bailout->req() > 1) { 1.115 + PreserveJVMState pjvms(this); 1.116 + set_control( _gvn.transform(bailout) ); 1.117 + uncommon_trap(Deoptimization::Reason_intrinsic, 1.118 + Deoptimization::Action_maybe_recompile); 1.119 + } 1.120 + 1.121 + if (!stopped()) { 1.122 1.123 // How many elements will we copy from the original? 1.124 // The answer is MinI(orig_length - start, length). 1.125 @@ -3247,8 +3244,10 @@ 1.126 generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT, 1.127 original, start, newcopy, intcon(0), moved, 1.128 disjoint_bases, length_never_negative); 1.129 - } //original reexecute and sp are set back here 1.130 - 1.131 + } 1.132 + } //original reexecute and sp are set back here 1.133 + 1.134 + if(!stopped()) { 1.135 push(newcopy); 1.136 } 1.137 1.138 @@ -4000,43 +3999,49 @@ 1.139 // 1.140 bool LibraryCallKit::inline_native_clone(bool is_virtual) { 1.141 int nargs = 1; 1.142 - Node* obj = null_check_receiver(callee()); 1.143 - if (stopped()) return true; 1.144 - Node* obj_klass = load_object_klass(obj); 1.145 - const TypeKlassPtr* tklass = _gvn.type(obj_klass)->isa_klassptr(); 1.146 - const TypeOopPtr* toop = ((tklass != NULL) 1.147 - ? tklass->as_instance_type() 1.148 - : TypeInstPtr::NOTNULL); 1.149 - 1.150 - // Conservatively insert a memory barrier on all memory slices. 1.151 - // Do not let writes into the original float below the clone. 1.152 - insert_mem_bar(Op_MemBarCPUOrder); 1.153 - 1.154 - // paths into result_reg: 1.155 - enum { 1.156 - _slow_path = 1, // out-of-line call to clone method (virtual or not) 1.157 - _objArray_path, // plain array allocation, plus arrayof_oop_arraycopy 1.158 - _array_path, // plain array allocation, plus arrayof_long_arraycopy 1.159 - _instance_path, // plain instance allocation, plus arrayof_long_arraycopy 1.160 - PATH_LIMIT 1.161 - }; 1.162 - RegionNode* result_reg = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT); 1.163 - PhiNode* result_val = new(C, PATH_LIMIT) PhiNode(result_reg, 1.164 - TypeInstPtr::NOTNULL); 1.165 - PhiNode* result_i_o = new(C, PATH_LIMIT) PhiNode(result_reg, Type::ABIO); 1.166 - PhiNode* result_mem = new(C, PATH_LIMIT) PhiNode(result_reg, Type::MEMORY, 1.167 - TypePtr::BOTTOM); 1.168 - record_for_igvn(result_reg); 1.169 - 1.170 - const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; 1.171 - int raw_adr_idx = Compile::AliasIdxRaw; 1.172 - const bool raw_mem_only = true; 1.173 + PhiNode* result_val; 1.174 1.175 //set the original stack and the reexecute bit for the interpreter to reexecute 1.176 //the bytecode that invokes Object.clone if deoptimization happens 1.177 { PreserveReexecuteState preexecs(this); 1.178 + jvms()->set_should_reexecute(true); 1.179 + 1.180 + //null_check_receiver will adjust _sp (push and pop) 1.181 + Node* obj = null_check_receiver(callee()); 1.182 + if (stopped()) return true; 1.183 + 1.184 _sp += nargs; 1.185 - jvms()->set_should_reexecute(true); 1.186 + 1.187 + Node* obj_klass = load_object_klass(obj); 1.188 + const TypeKlassPtr* tklass = _gvn.type(obj_klass)->isa_klassptr(); 1.189 + const TypeOopPtr* toop = ((tklass != NULL) 1.190 + ? tklass->as_instance_type() 1.191 + : TypeInstPtr::NOTNULL); 1.192 + 1.193 + // Conservatively insert a memory barrier on all memory slices. 1.194 + // Do not let writes into the original float below the clone. 1.195 + insert_mem_bar(Op_MemBarCPUOrder); 1.196 + 1.197 + // paths into result_reg: 1.198 + enum { 1.199 + _slow_path = 1, // out-of-line call to clone method (virtual or not) 1.200 + _objArray_path, // plain array allocation, plus arrayof_oop_arraycopy 1.201 + _array_path, // plain array allocation, plus arrayof_long_arraycopy 1.202 + _instance_path, // plain instance allocation, plus arrayof_long_arraycopy 1.203 + PATH_LIMIT 1.204 + }; 1.205 + RegionNode* result_reg = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT); 1.206 + result_val = new(C, PATH_LIMIT) PhiNode(result_reg, 1.207 + TypeInstPtr::NOTNULL); 1.208 + PhiNode* result_i_o = new(C, PATH_LIMIT) PhiNode(result_reg, Type::ABIO); 1.209 + PhiNode* result_mem = new(C, PATH_LIMIT) PhiNode(result_reg, Type::MEMORY, 1.210 + TypePtr::BOTTOM); 1.211 + record_for_igvn(result_reg); 1.212 + 1.213 + const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; 1.214 + int raw_adr_idx = Compile::AliasIdxRaw; 1.215 + const bool raw_mem_only = true; 1.216 + 1.217 1.218 Node* array_ctl = generate_array_guard(obj_klass, (RegionNode*)NULL); 1.219 if (array_ctl != NULL) { 1.220 @@ -4141,13 +4146,13 @@ 1.221 result_i_o ->set_req(_slow_path, i_o()); 1.222 result_mem ->set_req(_slow_path, reset_memory()); 1.223 } 1.224 + 1.225 + // Return the combined state. 1.226 + set_control( _gvn.transform(result_reg) ); 1.227 + set_i_o( _gvn.transform(result_i_o) ); 1.228 + set_all_memory( _gvn.transform(result_mem) ); 1.229 } //original reexecute and sp are set back here 1.230 1.231 - // Return the combined state. 1.232 - set_control( _gvn.transform(result_reg) ); 1.233 - set_i_o( _gvn.transform(result_i_o) ); 1.234 - set_all_memory( _gvn.transform(result_mem) ); 1.235 - 1.236 push(_gvn.transform(result_val)); 1.237 1.238 return true;