53 T_DOUBLE , |
52 T_DOUBLE , |
54 T_OBJECT |
53 T_OBJECT |
55 }; |
54 }; |
56 |
55 |
57 void TemplateInterpreterGenerator::generate_all() { |
56 void TemplateInterpreterGenerator::generate_all() { |
58 // Loop, in case we need several variants of the interpreter entries |
57 { CodeletMark cm(_masm, "slow signature handler"); |
59 do { |
58 AbstractInterpreter::_slow_signature_handler = generate_slow_signature_handler(); |
60 if (!CodeCacheExtensions::skip_code_generation()) { |
59 } |
61 // bypass code generation when useless |
60 |
62 { CodeletMark cm(_masm, "slow signature handler"); |
61 { CodeletMark cm(_masm, "error exits"); |
63 AbstractInterpreter::_slow_signature_handler = generate_slow_signature_handler(); |
62 _unimplemented_bytecode = generate_error_exit("unimplemented bytecode"); |
|
63 _illegal_bytecode_sequence = generate_error_exit("illegal bytecode sequence - method not verified"); |
|
64 } |
|
65 |
|
66 #ifndef PRODUCT |
|
67 if (TraceBytecodes) { |
|
68 CodeletMark cm(_masm, "bytecode tracing support"); |
|
69 Interpreter::_trace_code = |
|
70 EntryPoint( |
|
71 generate_trace_code(btos), |
|
72 generate_trace_code(ztos), |
|
73 generate_trace_code(ctos), |
|
74 generate_trace_code(stos), |
|
75 generate_trace_code(atos), |
|
76 generate_trace_code(itos), |
|
77 generate_trace_code(ltos), |
|
78 generate_trace_code(ftos), |
|
79 generate_trace_code(dtos), |
|
80 generate_trace_code(vtos) |
|
81 ); |
|
82 } |
|
83 #endif // !PRODUCT |
|
84 |
|
85 { CodeletMark cm(_masm, "return entry points"); |
|
86 const int index_size = sizeof(u2); |
|
87 for (int i = 0; i < Interpreter::number_of_return_entries; i++) { |
|
88 Interpreter::_return_entry[i] = |
|
89 EntryPoint( |
|
90 generate_return_entry_for(itos, i, index_size), |
|
91 generate_return_entry_for(itos, i, index_size), |
|
92 generate_return_entry_for(itos, i, index_size), |
|
93 generate_return_entry_for(itos, i, index_size), |
|
94 generate_return_entry_for(atos, i, index_size), |
|
95 generate_return_entry_for(itos, i, index_size), |
|
96 generate_return_entry_for(ltos, i, index_size), |
|
97 generate_return_entry_for(ftos, i, index_size), |
|
98 generate_return_entry_for(dtos, i, index_size), |
|
99 generate_return_entry_for(vtos, i, index_size) |
|
100 ); |
|
101 } |
|
102 } |
|
103 |
|
104 { CodeletMark cm(_masm, "invoke return entry points"); |
|
105 // These states are in order specified in TosState, except btos/ztos/ctos/stos are |
|
106 // really the same as itos since there is no top of stack optimization for these types |
|
107 const TosState states[] = {itos, itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos, ilgl}; |
|
108 const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic); |
|
109 const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface); |
|
110 const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic); |
|
111 |
|
112 for (int i = 0; i < Interpreter::number_of_return_addrs; i++) { |
|
113 TosState state = states[i]; |
|
114 assert(state != ilgl, "states array is wrong above"); |
|
115 Interpreter::_invoke_return_entry[i] = generate_return_entry_for(state, invoke_length, sizeof(u2)); |
|
116 Interpreter::_invokeinterface_return_entry[i] = generate_return_entry_for(state, invokeinterface_length, sizeof(u2)); |
|
117 Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4)); |
|
118 } |
|
119 } |
|
120 |
|
121 { CodeletMark cm(_masm, "earlyret entry points"); |
|
122 Interpreter::_earlyret_entry = |
|
123 EntryPoint( |
|
124 generate_earlyret_entry_for(btos), |
|
125 generate_earlyret_entry_for(ztos), |
|
126 generate_earlyret_entry_for(ctos), |
|
127 generate_earlyret_entry_for(stos), |
|
128 generate_earlyret_entry_for(atos), |
|
129 generate_earlyret_entry_for(itos), |
|
130 generate_earlyret_entry_for(ltos), |
|
131 generate_earlyret_entry_for(ftos), |
|
132 generate_earlyret_entry_for(dtos), |
|
133 generate_earlyret_entry_for(vtos) |
|
134 ); |
|
135 } |
|
136 |
|
137 { CodeletMark cm(_masm, "deoptimization entry points"); |
|
138 for (int i = 0; i < Interpreter::number_of_deopt_entries; i++) { |
|
139 Interpreter::_deopt_entry[i] = |
|
140 EntryPoint( |
|
141 generate_deopt_entry_for(itos, i), |
|
142 generate_deopt_entry_for(itos, i), |
|
143 generate_deopt_entry_for(itos, i), |
|
144 generate_deopt_entry_for(itos, i), |
|
145 generate_deopt_entry_for(atos, i), |
|
146 generate_deopt_entry_for(itos, i), |
|
147 generate_deopt_entry_for(ltos, i), |
|
148 generate_deopt_entry_for(ftos, i), |
|
149 generate_deopt_entry_for(dtos, i), |
|
150 generate_deopt_entry_for(vtos, i) |
|
151 ); |
|
152 } |
|
153 } |
|
154 |
|
155 { CodeletMark cm(_masm, "result handlers for native calls"); |
|
156 // The various result converter stublets. |
|
157 int is_generated[Interpreter::number_of_result_handlers]; |
|
158 memset(is_generated, 0, sizeof(is_generated)); |
|
159 |
|
160 for (int i = 0; i < Interpreter::number_of_result_handlers; i++) { |
|
161 BasicType type = types[i]; |
|
162 if (!is_generated[Interpreter::BasicType_as_index(type)]++) { |
|
163 Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type); |
64 } |
164 } |
65 |
165 } |
66 { CodeletMark cm(_masm, "error exits"); |
166 } |
67 _unimplemented_bytecode = generate_error_exit("unimplemented bytecode"); |
167 |
68 _illegal_bytecode_sequence = generate_error_exit("illegal bytecode sequence - method not verified"); |
168 { CodeletMark cm(_masm, "continuation entry points"); |
69 } |
169 Interpreter::_continuation_entry = |
70 |
170 EntryPoint( |
71 #ifndef PRODUCT |
171 generate_continuation_for(btos), |
72 if (TraceBytecodes) { |
172 generate_continuation_for(ztos), |
73 CodeletMark cm(_masm, "bytecode tracing support"); |
173 generate_continuation_for(ctos), |
74 Interpreter::_trace_code = |
174 generate_continuation_for(stos), |
75 EntryPoint( |
175 generate_continuation_for(atos), |
76 generate_trace_code(btos), |
176 generate_continuation_for(itos), |
77 generate_trace_code(ztos), |
177 generate_continuation_for(ltos), |
78 generate_trace_code(ctos), |
178 generate_continuation_for(ftos), |
79 generate_trace_code(stos), |
179 generate_continuation_for(dtos), |
80 generate_trace_code(atos), |
180 generate_continuation_for(vtos) |
81 generate_trace_code(itos), |
181 ); |
82 generate_trace_code(ltos), |
182 } |
83 generate_trace_code(ftos), |
183 |
84 generate_trace_code(dtos), |
184 { CodeletMark cm(_masm, "safepoint entry points"); |
85 generate_trace_code(vtos) |
185 Interpreter::_safept_entry = |
86 ); |
186 EntryPoint( |
87 } |
187 generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
88 #endif // !PRODUCT |
188 generate_safept_entry_for(ztos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
89 |
189 generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
90 { CodeletMark cm(_masm, "return entry points"); |
190 generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
91 const int index_size = sizeof(u2); |
191 generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
92 for (int i = 0; i < Interpreter::number_of_return_entries; i++) { |
192 generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
93 Interpreter::_return_entry[i] = |
193 generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
94 EntryPoint( |
194 generate_safept_entry_for(ftos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
95 generate_return_entry_for(itos, i, index_size), |
195 generate_safept_entry_for(dtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
96 generate_return_entry_for(itos, i, index_size), |
196 generate_safept_entry_for(vtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)) |
97 generate_return_entry_for(itos, i, index_size), |
197 ); |
98 generate_return_entry_for(itos, i, index_size), |
198 } |
99 generate_return_entry_for(atos, i, index_size), |
199 |
100 generate_return_entry_for(itos, i, index_size), |
200 { CodeletMark cm(_masm, "exception handling"); |
101 generate_return_entry_for(ltos, i, index_size), |
201 // (Note: this is not safepoint safe because thread may return to compiled code) |
102 generate_return_entry_for(ftos, i, index_size), |
202 generate_throw_exception(); |
103 generate_return_entry_for(dtos, i, index_size), |
203 } |
104 generate_return_entry_for(vtos, i, index_size) |
204 |
105 ); |
205 { CodeletMark cm(_masm, "throw exception entrypoints"); |
106 } |
206 Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler("java/lang/ArrayIndexOutOfBoundsException"); |
107 } |
207 Interpreter::_throw_ArrayStoreException_entry = generate_klass_exception_handler("java/lang/ArrayStoreException" ); |
108 |
208 Interpreter::_throw_ArithmeticException_entry = generate_exception_handler("java/lang/ArithmeticException" , "/ by zero"); |
109 { CodeletMark cm(_masm, "invoke return entry points"); |
209 Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler(); |
110 // These states are in order specified in TosState, except btos/ztos/ctos/stos are |
210 Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException" , NULL ); |
111 // really the same as itos since there is no top of stack optimization for these types |
211 Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler(); |
112 const TosState states[] = {itos, itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos, ilgl}; |
212 } |
113 const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic); |
|
114 const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface); |
|
115 const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic); |
|
116 |
|
117 for (int i = 0; i < Interpreter::number_of_return_addrs; i++) { |
|
118 TosState state = states[i]; |
|
119 assert(state != ilgl, "states array is wrong above"); |
|
120 Interpreter::_invoke_return_entry[i] = generate_return_entry_for(state, invoke_length, sizeof(u2)); |
|
121 Interpreter::_invokeinterface_return_entry[i] = generate_return_entry_for(state, invokeinterface_length, sizeof(u2)); |
|
122 Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4)); |
|
123 } |
|
124 } |
|
125 |
|
126 { CodeletMark cm(_masm, "earlyret entry points"); |
|
127 Interpreter::_earlyret_entry = |
|
128 EntryPoint( |
|
129 generate_earlyret_entry_for(btos), |
|
130 generate_earlyret_entry_for(ztos), |
|
131 generate_earlyret_entry_for(ctos), |
|
132 generate_earlyret_entry_for(stos), |
|
133 generate_earlyret_entry_for(atos), |
|
134 generate_earlyret_entry_for(itos), |
|
135 generate_earlyret_entry_for(ltos), |
|
136 generate_earlyret_entry_for(ftos), |
|
137 generate_earlyret_entry_for(dtos), |
|
138 generate_earlyret_entry_for(vtos) |
|
139 ); |
|
140 } |
|
141 |
|
142 { CodeletMark cm(_masm, "deoptimization entry points"); |
|
143 for (int i = 0; i < Interpreter::number_of_deopt_entries; i++) { |
|
144 Interpreter::_deopt_entry[i] = |
|
145 EntryPoint( |
|
146 generate_deopt_entry_for(itos, i), |
|
147 generate_deopt_entry_for(itos, i), |
|
148 generate_deopt_entry_for(itos, i), |
|
149 generate_deopt_entry_for(itos, i), |
|
150 generate_deopt_entry_for(atos, i), |
|
151 generate_deopt_entry_for(itos, i), |
|
152 generate_deopt_entry_for(ltos, i), |
|
153 generate_deopt_entry_for(ftos, i), |
|
154 generate_deopt_entry_for(dtos, i), |
|
155 generate_deopt_entry_for(vtos, i) |
|
156 ); |
|
157 } |
|
158 } |
|
159 |
|
160 { CodeletMark cm(_masm, "result handlers for native calls"); |
|
161 // The various result converter stublets. |
|
162 int is_generated[Interpreter::number_of_result_handlers]; |
|
163 memset(is_generated, 0, sizeof(is_generated)); |
|
164 |
|
165 for (int i = 0; i < Interpreter::number_of_result_handlers; i++) { |
|
166 BasicType type = types[i]; |
|
167 if (!is_generated[Interpreter::BasicType_as_index(type)]++) { |
|
168 Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type); |
|
169 } |
|
170 } |
|
171 } |
|
172 |
|
173 { CodeletMark cm(_masm, "continuation entry points"); |
|
174 Interpreter::_continuation_entry = |
|
175 EntryPoint( |
|
176 generate_continuation_for(btos), |
|
177 generate_continuation_for(ztos), |
|
178 generate_continuation_for(ctos), |
|
179 generate_continuation_for(stos), |
|
180 generate_continuation_for(atos), |
|
181 generate_continuation_for(itos), |
|
182 generate_continuation_for(ltos), |
|
183 generate_continuation_for(ftos), |
|
184 generate_continuation_for(dtos), |
|
185 generate_continuation_for(vtos) |
|
186 ); |
|
187 } |
|
188 |
|
189 { CodeletMark cm(_masm, "safepoint entry points"); |
|
190 Interpreter::_safept_entry = |
|
191 EntryPoint( |
|
192 generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
193 generate_safept_entry_for(ztos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
194 generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
195 generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
196 generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
197 generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
198 generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
199 generate_safept_entry_for(ftos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
200 generate_safept_entry_for(dtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
201 generate_safept_entry_for(vtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)) |
|
202 ); |
|
203 } |
|
204 |
|
205 { CodeletMark cm(_masm, "exception handling"); |
|
206 // (Note: this is not safepoint safe because thread may return to compiled code) |
|
207 generate_throw_exception(); |
|
208 } |
|
209 |
|
210 { CodeletMark cm(_masm, "throw exception entrypoints"); |
|
211 Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler("java/lang/ArrayIndexOutOfBoundsException"); |
|
212 Interpreter::_throw_ArrayStoreException_entry = generate_klass_exception_handler("java/lang/ArrayStoreException" ); |
|
213 Interpreter::_throw_ArithmeticException_entry = generate_exception_handler("java/lang/ArithmeticException" , "/ by zero"); |
|
214 Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler(); |
|
215 Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException" , NULL ); |
|
216 Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler(); |
|
217 } |
|
218 |
213 |
219 |
214 |
220 |
215 |
221 #define method_entry(kind) \ |
216 #define method_entry(kind) \ |
222 { CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \ |
217 { CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \ |
223 Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind); \ |
218 Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind); \ |
224 Interpreter::update_cds_entry_table(Interpreter::kind); \ |
219 Interpreter::update_cds_entry_table(Interpreter::kind); \ |
225 } |
220 } |
226 |
221 |
227 // all non-native method kinds |
222 // all non-native method kinds |
228 method_entry(zerolocals) |
223 method_entry(zerolocals) |
229 method_entry(zerolocals_synchronized) |
224 method_entry(zerolocals_synchronized) |
230 method_entry(empty) |
225 method_entry(empty) |
231 method_entry(accessor) |
226 method_entry(accessor) |
232 method_entry(abstract) |
227 method_entry(abstract) |
233 method_entry(java_lang_math_sin ) |
228 method_entry(java_lang_math_sin ) |
234 method_entry(java_lang_math_cos ) |
229 method_entry(java_lang_math_cos ) |
235 method_entry(java_lang_math_tan ) |
230 method_entry(java_lang_math_tan ) |
236 method_entry(java_lang_math_abs ) |
231 method_entry(java_lang_math_abs ) |
237 method_entry(java_lang_math_sqrt ) |
232 method_entry(java_lang_math_sqrt ) |
238 method_entry(java_lang_math_log ) |
233 method_entry(java_lang_math_log ) |
239 method_entry(java_lang_math_log10) |
234 method_entry(java_lang_math_log10) |
240 method_entry(java_lang_math_exp ) |
235 method_entry(java_lang_math_exp ) |
241 method_entry(java_lang_math_pow ) |
236 method_entry(java_lang_math_pow ) |
242 method_entry(java_lang_math_fmaF ) |
237 method_entry(java_lang_math_fmaF ) |
243 method_entry(java_lang_math_fmaD ) |
238 method_entry(java_lang_math_fmaD ) |
244 method_entry(java_lang_ref_reference_get) |
239 method_entry(java_lang_ref_reference_get) |
245 |
240 |
246 AbstractInterpreter::initialize_method_handle_entries(); |
241 AbstractInterpreter::initialize_method_handle_entries(); |
247 |
242 |
248 // all native method kinds (must be one contiguous block) |
243 // all native method kinds (must be one contiguous block) |
249 Interpreter::_native_entry_begin = Interpreter::code()->code_end(); |
244 Interpreter::_native_entry_begin = Interpreter::code()->code_end(); |
250 method_entry(native) |
245 method_entry(native) |
251 method_entry(native_synchronized) |
246 method_entry(native_synchronized) |
252 Interpreter::_native_entry_end = Interpreter::code()->code_end(); |
247 Interpreter::_native_entry_end = Interpreter::code()->code_end(); |
253 |
248 |
254 method_entry(java_util_zip_CRC32_update) |
249 method_entry(java_util_zip_CRC32_update) |
255 method_entry(java_util_zip_CRC32_updateBytes) |
250 method_entry(java_util_zip_CRC32_updateBytes) |
256 method_entry(java_util_zip_CRC32_updateByteBuffer) |
251 method_entry(java_util_zip_CRC32_updateByteBuffer) |
257 method_entry(java_util_zip_CRC32C_updateBytes) |
252 method_entry(java_util_zip_CRC32C_updateBytes) |
258 method_entry(java_util_zip_CRC32C_updateDirectByteBuffer) |
253 method_entry(java_util_zip_CRC32C_updateDirectByteBuffer) |
259 |
254 |
260 method_entry(java_lang_Float_intBitsToFloat); |
255 method_entry(java_lang_Float_intBitsToFloat); |
261 method_entry(java_lang_Float_floatToRawIntBits); |
256 method_entry(java_lang_Float_floatToRawIntBits); |
262 method_entry(java_lang_Double_longBitsToDouble); |
257 method_entry(java_lang_Double_longBitsToDouble); |
263 method_entry(java_lang_Double_doubleToRawLongBits); |
258 method_entry(java_lang_Double_doubleToRawLongBits); |
264 |
259 |
265 #undef method_entry |
260 #undef method_entry |
266 |
261 |
267 // Bytecodes |
262 // Bytecodes |
268 set_entry_points_for_all_bytes(); |
263 set_entry_points_for_all_bytes(); |
269 } |
|
270 } while (CodeCacheExtensions::needs_other_interpreter_variant()); |
|
271 |
264 |
272 // installation of code in other places in the runtime |
265 // installation of code in other places in the runtime |
273 // (ExcutableCodeManager calls not needed to copy the entries) |
266 // (ExcutableCodeManager calls not needed to copy the entries) |
274 set_safepoints_for_all_bytes(); |
267 set_safepoints_for_all_bytes(); |
275 } |
268 } |