Mercurial > hg > graal-compiler
comparison src/share/vm/opto/callGenerator.cpp @ 6182:765ee2d1674b
7157365: jruby/bench.bench_timeout crashes with JVM internal error
Reviewed-by: jrose, kvn
author | twisti |
---|---|
date | Mon, 18 Jun 2012 15:17:30 -0700 |
parents | 847da049d62f |
children | 1d7922586cf6 |
comparison
equal
deleted
inserted
replaced
6181:f8de958e5b2c | 6182:765ee2d1674b |
---|---|
170 virtual JVMState* generate(JVMState* jvms); | 170 virtual JVMState* generate(JVMState* jvms); |
171 }; | 171 }; |
172 | 172 |
173 JVMState* DynamicCallGenerator::generate(JVMState* jvms) { | 173 JVMState* DynamicCallGenerator::generate(JVMState* jvms) { |
174 GraphKit kit(jvms); | 174 GraphKit kit(jvms); |
175 | 175 Compile* C = kit.C; |
176 if (kit.C->log() != NULL) { | 176 PhaseGVN& gvn = kit.gvn(); |
177 kit.C->log()->elem("dynamic_call bci='%d'", jvms->bci()); | 177 |
178 if (C->log() != NULL) { | |
179 C->log()->elem("dynamic_call bci='%d'", jvms->bci()); | |
178 } | 180 } |
179 | 181 |
180 // Get the constant pool cache from the caller class. | 182 // Get the constant pool cache from the caller class. |
181 ciMethod* caller_method = jvms->method(); | 183 ciMethod* caller_method = jvms->method(); |
182 ciBytecodeStream str(caller_method); | 184 ciBytecodeStream str(caller_method); |
188 // pointer. | 190 // pointer. |
189 int index = str.get_method_index(); | 191 int index = str.get_method_index(); |
190 size_t call_site_offset = cpcache->get_f1_offset(index); | 192 size_t call_site_offset = cpcache->get_f1_offset(index); |
191 | 193 |
192 // Load the CallSite object from the constant pool cache. | 194 // Load the CallSite object from the constant pool cache. |
193 const TypeOopPtr* cpcache_ptr = TypeOopPtr::make_from_constant(cpcache); | 195 const TypeOopPtr* cpcache_type = TypeOopPtr::make_from_constant(cpcache); // returns TypeAryPtr of type T_OBJECT |
194 Node* cpcache_adr = kit.makecon(cpcache_ptr); | 196 const TypeOopPtr* call_site_type = TypeOopPtr::make_from_klass(C->env()->CallSite_klass()); |
195 Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, cpcache_adr, call_site_offset); | 197 Node* cpcache_adr = kit.makecon(cpcache_type); |
196 Node* call_site = kit.make_load(kit.control(), call_site_adr, TypeInstPtr::BOTTOM, T_OBJECT, Compile::AliasIdxRaw); | 198 Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, call_site_offset); |
199 // The oops in the constant pool cache are not compressed; load then as raw pointers. | |
200 Node* call_site = kit.make_load(kit.control(), call_site_adr, call_site_type, T_ADDRESS, Compile::AliasIdxRaw); | |
197 | 201 |
198 // Load the target MethodHandle from the CallSite object. | 202 // Load the target MethodHandle from the CallSite object. |
199 Node* target_mh_adr = kit.basic_plus_adr(call_site, call_site, java_lang_invoke_CallSite::target_offset_in_bytes()); | 203 const TypeOopPtr* target_type = TypeOopPtr::make_from_klass(C->env()->MethodHandle_klass()); |
200 Node* target_mh = kit.make_load(kit.control(), target_mh_adr, TypeInstPtr::BOTTOM, T_OBJECT); | 204 Node* target_mh_adr = kit.basic_plus_adr(call_site, java_lang_invoke_CallSite::target_offset_in_bytes()); |
205 Node* target_mh = kit.make_load(kit.control(), target_mh_adr, target_type, T_OBJECT); | |
201 | 206 |
202 address resolve_stub = SharedRuntime::get_resolve_opt_virtual_call_stub(); | 207 address resolve_stub = SharedRuntime::get_resolve_opt_virtual_call_stub(); |
203 | 208 |
204 CallStaticJavaNode *call = new (kit.C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), resolve_stub, method(), kit.bci()); | 209 CallStaticJavaNode* call = new (C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), resolve_stub, method(), kit.bci()); |
205 // invokedynamic is treated as an optimized invokevirtual. | 210 // invokedynamic is treated as an optimized invokevirtual. |
206 call->set_optimized_virtual(true); | 211 call->set_optimized_virtual(true); |
207 // Take extra care (in the presence of argument motion) not to trash the SP: | 212 // Take extra care (in the presence of argument motion) not to trash the SP: |
208 call->set_method_handle_invoke(true); | 213 call->set_method_handle_invoke(true); |
209 | 214 |
783 } | 788 } |
784 | 789 |
785 | 790 |
786 JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) { | 791 JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) { |
787 GraphKit kit(jvms); | 792 GraphKit kit(jvms); |
793 Compile* C = kit.C; | |
788 PhaseGVN& gvn = kit.gvn(); | 794 PhaseGVN& gvn = kit.gvn(); |
789 | 795 |
790 CompileLog* log = kit.C->log(); | 796 CompileLog* log = C->log(); |
791 if (log != NULL) { | 797 if (log != NULL) { |
792 log->elem("predicted_dynamic_call bci='%d'", jvms->bci()); | 798 log->elem("predicted_dynamic_call bci='%d'", jvms->bci()); |
793 } | 799 } |
794 | 800 |
795 const TypeOopPtr* predicted_mh_ptr = TypeOopPtr::make_from_constant(_predicted_method_handle, true); | 801 const TypeOopPtr* predicted_mh_ptr = TypeOopPtr::make_from_constant(_predicted_method_handle, true); |
801 // This is the selectAlternative idiom for guardWithTest or | 807 // This is the selectAlternative idiom for guardWithTest or |
802 // similar idioms. | 808 // similar idioms. |
803 Node* receiver = kit.argument(0); | 809 Node* receiver = kit.argument(0); |
804 | 810 |
805 // Check if the MethodHandle is the expected one | 811 // Check if the MethodHandle is the expected one |
806 Node* cmp = gvn.transform(new(kit.C, 3) CmpPNode(receiver, predicted_mh)); | 812 Node* cmp = gvn.transform(new (C, 3) CmpPNode(receiver, predicted_mh)); |
807 bol = gvn.transform(new(kit.C, 2) BoolNode(cmp, BoolTest::eq) ); | 813 bol = gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq) ); |
808 } else { | 814 } else { |
809 // Get the constant pool cache from the caller class. | 815 // Get the constant pool cache from the caller class. |
810 ciMethod* caller_method = jvms->method(); | 816 ciMethod* caller_method = jvms->method(); |
811 ciBytecodeStream str(caller_method); | 817 ciBytecodeStream str(caller_method); |
812 str.force_bci(jvms->bci()); // Set the stream to the invokedynamic bci. | 818 str.force_bci(jvms->bci()); // Set the stream to the invokedynamic bci. |
816 // pointer. | 822 // pointer. |
817 int index = str.get_method_index(); | 823 int index = str.get_method_index(); |
818 size_t call_site_offset = cpcache->get_f1_offset(index); | 824 size_t call_site_offset = cpcache->get_f1_offset(index); |
819 | 825 |
820 // Load the CallSite object from the constant pool cache. | 826 // Load the CallSite object from the constant pool cache. |
821 const TypeOopPtr* cpcache_ptr = TypeOopPtr::make_from_constant(cpcache); | 827 const TypeOopPtr* cpcache_type = TypeOopPtr::make_from_constant(cpcache); // returns TypeAryPtr of type T_OBJECT |
822 Node* cpcache_adr = kit.makecon(cpcache_ptr); | 828 const TypeOopPtr* call_site_type = TypeOopPtr::make_from_klass(C->env()->CallSite_klass()); |
823 Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, cpcache_adr, call_site_offset); | 829 Node* cpcache_adr = kit.makecon(cpcache_type); |
824 Node* call_site = kit.make_load(kit.control(), call_site_adr, TypeInstPtr::BOTTOM, T_OBJECT, Compile::AliasIdxRaw); | 830 Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, call_site_offset); |
831 // The oops in the constant pool cache are not compressed; load then as raw pointers. | |
832 Node* call_site = kit.make_load(kit.control(), call_site_adr, call_site_type, T_ADDRESS, Compile::AliasIdxRaw); | |
825 | 833 |
826 // Load the target MethodHandle from the CallSite object. | 834 // Load the target MethodHandle from the CallSite object. |
835 const TypeOopPtr* target_type = TypeOopPtr::make_from_klass(C->env()->MethodHandle_klass()); | |
827 Node* target_adr = kit.basic_plus_adr(call_site, call_site, java_lang_invoke_CallSite::target_offset_in_bytes()); | 836 Node* target_adr = kit.basic_plus_adr(call_site, call_site, java_lang_invoke_CallSite::target_offset_in_bytes()); |
828 Node* target_mh = kit.make_load(kit.control(), target_adr, TypeInstPtr::BOTTOM, T_OBJECT); | 837 Node* target_mh = kit.make_load(kit.control(), target_adr, target_type, T_OBJECT); |
829 | 838 |
830 // Check if the MethodHandle is still the same. | 839 // Check if the MethodHandle is still the same. |
831 Node* cmp = gvn.transform(new(kit.C, 3) CmpPNode(target_mh, predicted_mh)); | 840 Node* cmp = gvn.transform(new (C, 3) CmpPNode(target_mh, predicted_mh)); |
832 bol = gvn.transform(new(kit.C, 2) BoolNode(cmp, BoolTest::eq) ); | 841 bol = gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq) ); |
833 } | 842 } |
834 IfNode* iff = kit.create_and_xform_if(kit.control(), bol, _hit_prob, COUNT_UNKNOWN); | 843 IfNode* iff = kit.create_and_xform_if(kit.control(), bol, _hit_prob, COUNT_UNKNOWN); |
835 kit.set_control( gvn.transform(new(kit.C, 1) IfTrueNode (iff))); | 844 kit.set_control( gvn.transform(new (C, 1) IfTrueNode (iff))); |
836 Node* slow_ctl = gvn.transform(new(kit.C, 1) IfFalseNode(iff)); | 845 Node* slow_ctl = gvn.transform(new (C, 1) IfFalseNode(iff)); |
837 | 846 |
838 SafePointNode* slow_map = NULL; | 847 SafePointNode* slow_map = NULL; |
839 JVMState* slow_jvms; | 848 JVMState* slow_jvms; |
840 { PreserveJVMState pjvms(&kit); | 849 { PreserveJVMState pjvms(&kit); |
841 kit.set_control(slow_ctl); | 850 kit.set_control(slow_ctl); |
880 return kit.transfer_exceptions_into_jvms(); | 889 return kit.transfer_exceptions_into_jvms(); |
881 } | 890 } |
882 | 891 |
883 // Finish the diamond. | 892 // Finish the diamond. |
884 kit.C->set_has_split_ifs(true); // Has chance for split-if optimization | 893 kit.C->set_has_split_ifs(true); // Has chance for split-if optimization |
885 RegionNode* region = new (kit.C, 3) RegionNode(3); | 894 RegionNode* region = new (C, 3) RegionNode(3); |
886 region->init_req(1, kit.control()); | 895 region->init_req(1, kit.control()); |
887 region->init_req(2, slow_map->control()); | 896 region->init_req(2, slow_map->control()); |
888 kit.set_control(gvn.transform(region)); | 897 kit.set_control(gvn.transform(region)); |
889 Node* iophi = PhiNode::make(region, kit.i_o(), Type::ABIO); | 898 Node* iophi = PhiNode::make(region, kit.i_o(), Type::ABIO); |
890 iophi->set_req(2, slow_map->i_o()); | 899 iophi->set_req(2, slow_map->i_o()); |