< prev index next >

src/share/vm/opto/callGenerator.cpp

Print this page




 171            vtable_index >= 0, "either invalid or usable");
 172   }
 173   virtual bool      is_virtual() const          { return true; }
 174   virtual JVMState* generate(JVMState* jvms);
 175 };
 176 
 177 JVMState* VirtualCallGenerator::generate(JVMState* jvms) {
 178   GraphKit kit(jvms);
 179   Node* receiver = kit.argument(0);
 180 
 181   if (kit.C->log() != NULL) {
 182     kit.C->log()->elem("virtual_call bci='%d'", jvms->bci());
 183   }
 184 
 185   // If the receiver is a constant null, do not torture the system
 186   // by attempting to call through it.  The compile will proceed
 187   // correctly, but may bail out in final_graph_reshaping, because
 188   // the call instruction will have a seemingly deficient out-count.
 189   // (The bailout says something misleading about an "infinite loop".)
 190   if (kit.gvn().type(receiver)->higher_equal(TypePtr::NULL_PTR)) {
 191     kit.inc_sp(method()->arg_size());  // restore arguments



 192     kit.uncommon_trap(Deoptimization::Reason_null_check,
 193                       Deoptimization::Action_none,
 194                       NULL, "null receiver");
 195     return kit.transfer_exceptions_into_jvms();
 196   }
 197 
 198   // Ideally we would unconditionally do a null check here and let it
 199   // be converted to an implicit check based on profile information.
 200   // However currently the conversion to implicit null checks in
 201   // Block::implicit_null_check() only looks for loads and stores, not calls.
 202   ciMethod *caller = kit.method();
 203   ciMethodData *caller_md = (caller == NULL) ? NULL : caller->method_data();
 204   if (!UseInlineCaches || !ImplicitNullChecks || !os::zero_page_read_protected() ||
 205        ((ImplicitNullCheckThreshold > 0) && caller_md &&
 206        (caller_md->trap_count(Deoptimization::Reason_null_check)
 207        >= (uint)ImplicitNullCheckThreshold))) {
 208     // Make an explicit receiver null_check as part of this call.
 209     // Since we share a map with the caller, his JVMS gets adjusted.
 210     receiver = kit.null_check_receiver_before_call(method());
 211     if (kit.stopped()) {


1102   }
1103 
1104   virtual bool      is_virtual() const          { ShouldNotReachHere(); return false; }
1105   virtual bool      is_trap() const             { return true; }
1106 
1107   virtual JVMState* generate(JVMState* jvms);
1108 };
1109 
1110 
1111 CallGenerator*
1112 CallGenerator::for_uncommon_trap(ciMethod* m,
1113                                  Deoptimization::DeoptReason reason,
1114                                  Deoptimization::DeoptAction action) {
1115   return new UncommonTrapCallGenerator(m, reason, action);
1116 }
1117 
1118 
1119 JVMState* UncommonTrapCallGenerator::generate(JVMState* jvms) {
1120   GraphKit kit(jvms);
1121   // Take the trap with arguments pushed on the stack.  (Cf. null_check_receiver).
1122   int nargs = method()->arg_size();



1123   kit.inc_sp(nargs);
1124   assert(nargs <= kit.sp() && kit.sp() <= jvms->stk_size(), "sane sp w/ args pushed");
1125   if (_reason == Deoptimization::Reason_class_check &&
1126       _action == Deoptimization::Action_maybe_recompile) {
1127     // Temp fix for 6529811
1128     // Don't allow uncommon_trap to override our decision to recompile in the event
1129     // of a class cast failure for a monomorphic call as it will never let us convert
1130     // the call to either bi-morphic or megamorphic and can lead to unc-trap loops
1131     bool keep_exact_action = true;
1132     kit.uncommon_trap(_reason, _action, NULL, "monomorphic vcall checkcast", false, keep_exact_action);
1133   } else {
1134     kit.uncommon_trap(_reason, _action);
1135   }
1136   return kit.transfer_exceptions_into_jvms();
1137 }
1138 
1139 // (Note:  Moved hook_up_call to GraphKit::set_edges_for_java_call.)
1140 
1141 // (Node:  Merged hook_up_exits into ParseGenerator::generate.)
1142 




 171            vtable_index >= 0, "either invalid or usable");
 172   }
 173   virtual bool      is_virtual() const          { return true; }
 174   virtual JVMState* generate(JVMState* jvms);
 175 };
 176 
 177 JVMState* VirtualCallGenerator::generate(JVMState* jvms) {
 178   GraphKit kit(jvms);
 179   Node* receiver = kit.argument(0);
 180 
 181   if (kit.C->log() != NULL) {
 182     kit.C->log()->elem("virtual_call bci='%d'", jvms->bci());
 183   }
 184 
 185   // If the receiver is a constant null, do not torture the system
 186   // by attempting to call through it.  The compile will proceed
 187   // correctly, but may bail out in final_graph_reshaping, because
 188   // the call instruction will have a seemingly deficient out-count.
 189   // (The bailout says something misleading about an "infinite loop".)
 190   if (kit.gvn().type(receiver)->higher_equal(TypePtr::NULL_PTR)) {
 191     assert(Bytecodes::is_invoke(kit.java_bc()), err_msg("%d: %s", kit.java_bc(), Bytecodes::name(kit.java_bc())));
 192     ciMethod* declared_method = kit.method()->get_method_at_bci(kit.bci());
 193     int arg_size = declared_method->signature()->arg_size_for_bc(kit.java_bc());
 194     kit.inc_sp(arg_size);  // restore arguments
 195     kit.uncommon_trap(Deoptimization::Reason_null_check,
 196                       Deoptimization::Action_none,
 197                       NULL, "null receiver");
 198     return kit.transfer_exceptions_into_jvms();
 199   }
 200 
 201   // Ideally we would unconditionally do a null check here and let it
 202   // be converted to an implicit check based on profile information.
 203   // However currently the conversion to implicit null checks in
 204   // Block::implicit_null_check() only looks for loads and stores, not calls.
 205   ciMethod *caller = kit.method();
 206   ciMethodData *caller_md = (caller == NULL) ? NULL : caller->method_data();
 207   if (!UseInlineCaches || !ImplicitNullChecks || !os::zero_page_read_protected() ||
 208        ((ImplicitNullCheckThreshold > 0) && caller_md &&
 209        (caller_md->trap_count(Deoptimization::Reason_null_check)
 210        >= (uint)ImplicitNullCheckThreshold))) {
 211     // Make an explicit receiver null_check as part of this call.
 212     // Since we share a map with the caller, his JVMS gets adjusted.
 213     receiver = kit.null_check_receiver_before_call(method());
 214     if (kit.stopped()) {


1105   }
1106 
1107   virtual bool      is_virtual() const          { ShouldNotReachHere(); return false; }
1108   virtual bool      is_trap() const             { return true; }
1109 
1110   virtual JVMState* generate(JVMState* jvms);
1111 };
1112 
1113 
1114 CallGenerator*
1115 CallGenerator::for_uncommon_trap(ciMethod* m,
1116                                  Deoptimization::DeoptReason reason,
1117                                  Deoptimization::DeoptAction action) {
1118   return new UncommonTrapCallGenerator(m, reason, action);
1119 }
1120 
1121 
1122 JVMState* UncommonTrapCallGenerator::generate(JVMState* jvms) {
1123   GraphKit kit(jvms);
1124   // Take the trap with arguments pushed on the stack.  (Cf. null_check_receiver).
1125   // Callsite signature can be different from actual method being called (i.e _linkTo* sites).
1126   // Use callsite signature always.
1127   ciMethod* declared_method = kit.method()->get_method_at_bci(kit.bci());
1128   int nargs = declared_method->arg_size();
1129   kit.inc_sp(nargs);
1130   assert(nargs <= kit.sp() && kit.sp() <= jvms->stk_size(), "sane sp w/ args pushed");
1131   if (_reason == Deoptimization::Reason_class_check &&
1132       _action == Deoptimization::Action_maybe_recompile) {
1133     // Temp fix for 6529811
1134     // Don't allow uncommon_trap to override our decision to recompile in the event
1135     // of a class cast failure for a monomorphic call as it will never let us convert
1136     // the call to either bi-morphic or megamorphic and can lead to unc-trap loops
1137     bool keep_exact_action = true;
1138     kit.uncommon_trap(_reason, _action, NULL, "monomorphic vcall checkcast", false, keep_exact_action);
1139   } else {
1140     kit.uncommon_trap(_reason, _action);
1141   }
1142   return kit.transfer_exceptions_into_jvms();
1143 }
1144 
1145 // (Note:  Moved hook_up_call to GraphKit::set_edges_for_java_call.)
1146 
1147 // (Node:  Merged hook_up_exits into ParseGenerator::generate.)
1148 


< prev index next >