57 tty->cr();
58 }
59 }
60 #endif
61
62 CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual,
63 JVMState* jvms, bool allow_inline,
64 float prof_factor) {
65 CallGenerator* cg;
66 guarantee(call_method != NULL, "failed method resolution");
67
68 // Dtrace currently doesn't work unless all calls are vanilla
69 if (env()->dtrace_method_probes()) {
70 allow_inline = false;
71 }
72
73 // Note: When we get profiling during stage-1 compiles, we want to pull
74 // from more specific profile data which pertains to this inlining.
75 // Right now, ignore the information in jvms->caller(), and do method[bci].
76 ciCallProfile profile = jvms->method()->call_profile_at_bci(jvms->bci());
77
78 // See how many times this site has been invoked.
79 int site_count = profile.count();
80 int receiver_count = -1;
81 if (call_is_virtual && UseTypeProfile && profile.has_receiver(0)) {
82 // Receivers in the profile structure are ordered by call counts
83 // so that the most called (major) receiver is profile.receiver(0).
84 receiver_count = profile.receiver_count(0);
85 }
86
87 CompileLog* log = this->log();
88 if (log != NULL) {
89 int rid = (receiver_count >= 0)? log->identify(profile.receiver(0)): -1;
90 int r2id = (rid != -1 && profile.has_receiver(1))? log->identify(profile.receiver(1)):-1;
91 log->begin_elem("call method='%d' count='%d' prof_factor='%g'",
92 log->identify(call_method), site_count, prof_factor);
93 if (call_is_virtual) log->print(" virtual='1'");
94 if (allow_inline) log->print(" inline='1'");
95 if (receiver_count >= 0) {
96 log->print(" receiver='%d' receiver_count='%d'", rid, receiver_count);
99 }
100 }
101 log->end_elem();
102 }
103
104 // Special case the handling of certain common, profitable library
105 // methods. If these methods are replaced with specialized code,
106 // then we return it as the inlined version of the call.
107 // We do this before the strict f.p. check below because the
108 // intrinsics handle strict f.p. correctly.
109 if (allow_inline) {
110 cg = find_intrinsic(call_method, call_is_virtual);
111 if (cg != NULL) return cg;
112 }
113
114 // Do MethodHandle calls.
115 // NOTE: This must happen before normal inlining logic below since
116 // MethodHandle.invoke* are native methods which obviously don't
117 // have bytecodes and so normal inlining fails.
118 if (call_method->is_method_handle_invoke()) {
119 if (jvms->method()->java_code_at_bci(jvms->bci()) != Bytecodes::_invokedynamic) {
120 GraphKit kit(jvms);
121 Node* n = kit.argument(0);
122
123 if (n->Opcode() == Op_ConP) {
124 const TypeOopPtr* oop_ptr = n->bottom_type()->is_oopptr();
125 ciObject* const_oop = oop_ptr->const_oop();
126 ciMethodHandle* method_handle = const_oop->as_method_handle();
127
128 // Set the actually called method to have access to the class
129 // and signature in the MethodHandleCompiler.
130 method_handle->set_callee(call_method);
131
132 // Get an adapter for the MethodHandle.
133 ciMethod* target_method = method_handle->get_method_handle_adapter();
134 CallGenerator* hit_cg = NULL;
135 if (target_method != NULL)
136 hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);
137 if (hit_cg != NULL && hit_cg->is_inline())
138 return hit_cg;
139 }
140
141 return CallGenerator::for_direct_call(call_method);
142 }
143 else {
144 // Get the MethodHandle from the CallSite.
145 ciMethod* caller_method = jvms->method();
146 ciBytecodeStream str(caller_method);
147 str.force_bci(jvms->bci()); // Set the stream to the invokedynamic bci.
148 ciCallSite* call_site = str.get_call_site();
149 ciMethodHandle* method_handle = call_site->get_target();
150
151 // Set the actually called method to have access to the class
152 // and signature in the MethodHandleCompiler.
153 method_handle->set_callee(call_method);
154
155 // Get an adapter for the MethodHandle.
156 ciMethod* target_method = method_handle->get_invokedynamic_adapter();
157 CallGenerator* hit_cg = NULL;
158 if (target_method != NULL)
159 hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);
160 if (hit_cg != NULL && hit_cg->is_inline()) {
161 CallGenerator* miss_cg = CallGenerator::for_dynamic_call(call_method);
162 return CallGenerator::for_predicted_dynamic_call(method_handle, miss_cg, hit_cg, prof_factor);
163 }
164
165 // If something failed, generate a normal dynamic call.
166 return CallGenerator::for_dynamic_call(call_method);
167 }
168 }
169
170 // Do not inline strict fp into non-strict code, or the reverse
171 bool caller_method_is_strict = jvms->method()->is_strict();
172 if( caller_method_is_strict ^ call_method->is_strict() ) {
173 allow_inline = false;
174 }
175
176 // Attempt to inline...
177 if (allow_inline) {
178 // The profile data is only partly attributable to this caller,
179 // scale back the call site information.
180 float past_uses = jvms->method()->scale_count(site_count, prof_factor);
181 // This is the number of times we expect the call code to be used.
182 float expected_uses = past_uses;
183
|
57 tty->cr();
58 }
59 }
60 #endif
61
62 CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual,
63 JVMState* jvms, bool allow_inline,
64 float prof_factor) {
65 CallGenerator* cg;
66 guarantee(call_method != NULL, "failed method resolution");
67
68 // Dtrace currently doesn't work unless all calls are vanilla
69 if (env()->dtrace_method_probes()) {
70 allow_inline = false;
71 }
72
73 // Note: When we get profiling during stage-1 compiles, we want to pull
74 // from more specific profile data which pertains to this inlining.
75 // Right now, ignore the information in jvms->caller(), and do method[bci].
76 ciCallProfile profile = jvms->method()->call_profile_at_bci(jvms->bci());
77 Bytecodes::Code bytecode = jvms->method()->java_code_at_bci(jvms->bci());
78
79 // See how many times this site has been invoked.
80 int site_count = profile.count();
81 int receiver_count = -1;
82 if (call_is_virtual && UseTypeProfile && profile.has_receiver(0)) {
83 // Receivers in the profile structure are ordered by call counts
84 // so that the most called (major) receiver is profile.receiver(0).
85 receiver_count = profile.receiver_count(0);
86 }
87
88 CompileLog* log = this->log();
89 if (log != NULL) {
90 int rid = (receiver_count >= 0)? log->identify(profile.receiver(0)): -1;
91 int r2id = (rid != -1 && profile.has_receiver(1))? log->identify(profile.receiver(1)):-1;
92 log->begin_elem("call method='%d' count='%d' prof_factor='%g'",
93 log->identify(call_method), site_count, prof_factor);
94 if (call_is_virtual) log->print(" virtual='1'");
95 if (allow_inline) log->print(" inline='1'");
96 if (receiver_count >= 0) {
97 log->print(" receiver='%d' receiver_count='%d'", rid, receiver_count);
100 }
101 }
102 log->end_elem();
103 }
104
105 // Special case the handling of certain common, profitable library
106 // methods. If these methods are replaced with specialized code,
107 // then we return it as the inlined version of the call.
108 // We do this before the strict f.p. check below because the
109 // intrinsics handle strict f.p. correctly.
110 if (allow_inline) {
111 cg = find_intrinsic(call_method, call_is_virtual);
112 if (cg != NULL) return cg;
113 }
114
115 // Do MethodHandle calls.
116 // NOTE: This must happen before normal inlining logic below since
117 // MethodHandle.invoke* are native methods which obviously don't
118 // have bytecodes and so normal inlining fails.
119 if (call_method->is_method_handle_invoke()) {
120 if (bytecode != Bytecodes::_invokedynamic) {
121 GraphKit kit(jvms);
122 Node* n = kit.argument(0);
123
124 if (n->Opcode() == Op_ConP) {
125 const TypeOopPtr* oop_ptr = n->bottom_type()->is_oopptr();
126 ciObject* const_oop = oop_ptr->const_oop();
127 ciMethodHandle* method_handle = const_oop->as_method_handle();
128
129 // Set the actually called method to have access to the class
130 // and signature in the MethodHandleCompiler.
131 method_handle->set_callee(call_method);
132 method_handle->set_call_profile(&profile);
133
134 // Get an adapter for the MethodHandle.
135 ciMethod* target_method = method_handle->get_method_handle_adapter();
136 if (target_method != NULL) {
137 CallGenerator* hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);
138 if (hit_cg != NULL && hit_cg->is_inline())
139 return hit_cg;
140 }
141 }
142
143 return CallGenerator::for_direct_call(call_method);
144 }
145 else {
146 // Get the MethodHandle from the CallSite.
147 ciMethod* caller_method = jvms->method();
148 ciBytecodeStream str(caller_method);
149 str.force_bci(jvms->bci()); // Set the stream to the invokedynamic bci.
150 ciCallSite* call_site = str.get_call_site();
151 ciMethodHandle* method_handle = call_site->get_target();
152
153 // Set the actually called method to have access to the class
154 // and signature in the MethodHandleCompiler.
155 method_handle->set_callee(call_method);
156 method_handle->set_call_profile(&profile);
157
158 // Get an adapter for the MethodHandle.
159 ciMethod* target_method = method_handle->get_invokedynamic_adapter();
160 if (target_method != NULL) {
161 CallGenerator* hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);
162 if (hit_cg != NULL && hit_cg->is_inline()) {
163 CallGenerator* miss_cg = CallGenerator::for_dynamic_call(call_method);
164 return CallGenerator::for_predicted_dynamic_call(method_handle, miss_cg, hit_cg, prof_factor);
165 }
166 }
167
168 // If something failed, generate a normal dynamic call.
169 return CallGenerator::for_dynamic_call(call_method);
170 }
171 }
172
173 // Do not inline strict fp into non-strict code, or the reverse
174 bool caller_method_is_strict = jvms->method()->is_strict();
175 if( caller_method_is_strict ^ call_method->is_strict() ) {
176 allow_inline = false;
177 }
178
179 // Attempt to inline...
180 if (allow_inline) {
181 // The profile data is only partly attributable to this caller,
182 // scale back the call site information.
183 float past_uses = jvms->method()->scale_count(site_count, prof_factor);
184 // This is the number of times we expect the call code to be used.
185 float expected_uses = past_uses;
186
|