Mercurial > hg > graal-jvmci-8
comparison src/share/vm/prims/methodHandleWalk.cpp @ 1138:dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
Summary: C2 needs some additional optimizations to be able to handle MethodHandle invokes and invokedynamic instructions at the best performance.
Reviewed-by: kvn, never
author | twisti |
---|---|
date | Tue, 05 Jan 2010 15:21:25 +0100 |
parents | aa62b9388fce |
children | 4ce7240d622c |
comparison
equal
deleted
inserted
replaced
1137:97125851f396 | 1138:dd57230ba8fe |
---|---|
27 */ | 27 */ |
28 | 28 |
29 #include "incls/_precompiled.incl" | 29 #include "incls/_precompiled.incl" |
30 #include "incls/_methodHandleWalk.cpp.incl" | 30 #include "incls/_methodHandleWalk.cpp.incl" |
31 | 31 |
32 | |
33 // ----------------------------------------------------------------------------- | |
34 // MethodHandleChain | |
35 | |
32 void MethodHandleChain::set_method_handle(Handle mh, TRAPS) { | 36 void MethodHandleChain::set_method_handle(Handle mh, TRAPS) { |
33 if (!java_dyn_MethodHandle::is_instance(mh())) lose("bad method handle", CHECK); | 37 if (!java_dyn_MethodHandle::is_instance(mh())) lose("bad method handle", CHECK); |
34 | 38 |
35 // set current method handle and unpack partially | 39 // set current method handle and unpack partially |
36 _method_handle = mh; | 40 _method_handle = mh; |
56 _arg_slot = BoundMethodHandle_vmargslot(); | 60 _arg_slot = BoundMethodHandle_vmargslot(); |
57 oop target = MethodHandle_vmtarget_oop(); | 61 oop target = MethodHandle_vmtarget_oop(); |
58 if (!is_bound() || java_dyn_MethodHandle::is_instance(target)) { | 62 if (!is_bound() || java_dyn_MethodHandle::is_instance(target)) { |
59 _arg_type = compute_bound_arg_type(target, NULL, _arg_slot, CHECK); | 63 _arg_type = compute_bound_arg_type(target, NULL, _arg_slot, CHECK); |
60 } else if (target != NULL && target->is_method()) { | 64 } else if (target != NULL && target->is_method()) { |
61 _arg_type = compute_bound_arg_type(NULL, (methodOop)target, _arg_slot, CHECK); | 65 methodOop m = (methodOop) target; |
66 _arg_type = compute_bound_arg_type(NULL, m, _arg_slot, CHECK); | |
62 set_last_method(mh(), CHECK); | 67 set_last_method(mh(), CHECK); |
63 } else { | 68 } else { |
64 _is_bound = false; // lose! | 69 _is_bound = false; // lose! |
65 } | 70 } |
66 } | 71 } |
69 } | 74 } |
70 if (!is_bound() && !is_adapter()) { | 75 if (!is_bound() && !is_adapter()) { |
71 lose("unrecognized MH type", CHECK); | 76 lose("unrecognized MH type", CHECK); |
72 } | 77 } |
73 } | 78 } |
79 | |
74 | 80 |
75 void MethodHandleChain::set_last_method(oop target, TRAPS) { | 81 void MethodHandleChain::set_last_method(oop target, TRAPS) { |
76 _is_last = true; | 82 _is_last = true; |
77 klassOop receiver_limit_oop = NULL; | 83 klassOop receiver_limit_oop = NULL; |
78 int flags = 0; | 84 int flags = 0; |
86 _last_invoke = Bytecodes::_invokeinterface; | 92 _last_invoke = Bytecodes::_invokeinterface; |
87 else | 93 else |
88 _last_invoke = Bytecodes::_invokevirtual; | 94 _last_invoke = Bytecodes::_invokevirtual; |
89 } | 95 } |
90 | 96 |
97 | |
91 BasicType MethodHandleChain::compute_bound_arg_type(oop target, methodOop m, int arg_slot, TRAPS) { | 98 BasicType MethodHandleChain::compute_bound_arg_type(oop target, methodOop m, int arg_slot, TRAPS) { |
92 // There is no direct indication of whether the argument is primitive or not. | 99 // There is no direct indication of whether the argument is primitive or not. |
93 // It is implied by the _vmentry code, and by the MethodType of the target. | 100 // It is implied by the _vmentry code, and by the MethodType of the target. |
94 // FIXME: Make it explicit MethodHandleImpl refactors out from MethodHandle | 101 // FIXME: Make it explicit MethodHandleImpl refactors out from MethodHandle |
95 BasicType arg_type = T_VOID; | 102 BasicType arg_type = T_VOID; |
124 if (arg_type == T_ARRAY) | 131 if (arg_type == T_ARRAY) |
125 arg_type = T_OBJECT; | 132 arg_type = T_OBJECT; |
126 return arg_type; | 133 return arg_type; |
127 } | 134 } |
128 | 135 |
136 | |
129 void MethodHandleChain::lose(const char* msg, TRAPS) { | 137 void MethodHandleChain::lose(const char* msg, TRAPS) { |
138 assert(false, "lose"); | |
130 _lose_message = msg; | 139 _lose_message = msg; |
131 if (!THREAD->is_Java_thread() || ((JavaThread*)THREAD)->thread_state() != _thread_in_vm) { | 140 if (!THREAD->is_Java_thread() || ((JavaThread*)THREAD)->thread_state() != _thread_in_vm) { |
132 // throw a preallocated exception | 141 // throw a preallocated exception |
133 THROW_OOP(Universe::virtual_machine_error_instance()); | 142 THROW_OOP(Universe::virtual_machine_error_instance()); |
134 } | 143 } |
135 THROW_MSG(vmSymbols::java_lang_InternalError(), msg); | 144 THROW_MSG(vmSymbols::java_lang_InternalError(), msg); |
136 } | 145 } |
146 | |
147 | |
148 // ----------------------------------------------------------------------------- | |
149 // MethodHandleWalker | |
137 | 150 |
138 Bytecodes::Code MethodHandleWalker::conversion_code(BasicType src, BasicType dest) { | 151 Bytecodes::Code MethodHandleWalker::conversion_code(BasicType src, BasicType dest) { |
139 if (is_subword_type(src)) { | 152 if (is_subword_type(src)) { |
140 src = T_INT; // all subword src types act like int | 153 src = T_INT; // all subword src types act like int |
141 } | 154 } |
168 | 181 |
169 // cannot do it in one step, or at all | 182 // cannot do it in one step, or at all |
170 return Bytecodes::_illegal; | 183 return Bytecodes::_illegal; |
171 } | 184 } |
172 | 185 |
186 | |
187 // ----------------------------------------------------------------------------- | |
188 // MethodHandleWalker::walk | |
189 // | |
173 MethodHandleWalker::ArgToken | 190 MethodHandleWalker::ArgToken |
174 MethodHandleWalker::walk(TRAPS) { | 191 MethodHandleWalker::walk(TRAPS) { |
175 walk_incoming_state(CHECK_NULL); | 192 ArgToken empty = ArgToken(); // Empty return value. |
193 | |
194 walk_incoming_state(CHECK_(empty)); | |
176 | 195 |
177 for (;;) { | 196 for (;;) { |
178 set_method_handle(chain().method_handle_oop()); | 197 set_method_handle(chain().method_handle_oop()); |
179 | 198 |
180 assert(_outgoing_argc == argument_count_slow(), "empty slots under control"); | 199 assert(_outgoing_argc == argument_count_slow(), "empty slots under control"); |
183 int conv_op = chain().adapter_conversion_op(); | 202 int conv_op = chain().adapter_conversion_op(); |
184 int arg_slot = chain().adapter_arg_slot(); | 203 int arg_slot = chain().adapter_arg_slot(); |
185 SlotState* arg_state = slot_state(arg_slot); | 204 SlotState* arg_state = slot_state(arg_slot); |
186 if (arg_state == NULL | 205 if (arg_state == NULL |
187 && conv_op > sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW) { | 206 && conv_op > sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW) { |
188 lose("bad argument index", CHECK_NULL); | 207 lose("bad argument index", CHECK_(empty)); |
189 } | 208 } |
190 | 209 |
191 // perform the adapter action | 210 // perform the adapter action |
192 switch (chain().adapter_conversion_op()) { | 211 switch (chain().adapter_conversion_op()) { |
193 case sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY: | 212 case sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY: |
194 case sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW: | |
195 // No changes to arguments; pass the bits through. | 213 // No changes to arguments; pass the bits through. |
196 // The only difference between the two ops is that the "only" version | 214 break; |
197 // is fully compatible with the verifier, while the "raw" version | 215 |
198 // performs a few extra bitwise conversions (like long <-> double). | 216 case sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW: { |
199 break; | 217 // To keep the verifier happy, emit bitwise ("raw") conversions as needed. |
218 // See MethodHandles::same_basic_type_for_arguments for allowed conversions. | |
219 Handle incoming_mtype(THREAD, chain().method_type_oop()); | |
220 oop outgoing_mh_oop = chain().vmtarget_oop(); | |
221 if (!java_dyn_MethodHandle::is_instance(outgoing_mh_oop)) | |
222 lose("outgoing target not a MethodHandle", CHECK_(empty)); | |
223 Handle outgoing_mtype(THREAD, java_dyn_MethodHandle::type(outgoing_mh_oop)); | |
224 outgoing_mh_oop = NULL; // GC safety | |
225 | |
226 int nptypes = java_dyn_MethodType::ptype_count(outgoing_mtype()); | |
227 if (nptypes != java_dyn_MethodType::ptype_count(incoming_mtype())) | |
228 lose("incoming and outgoing parameter count do not agree", CHECK_(empty)); | |
229 | |
230 for (int i = 0, slot = _outgoing.length() - 1; slot >= 0; slot--) { | |
231 SlotState* arg_state = slot_state(slot); | |
232 if (arg_state->_type == T_VOID) continue; | |
233 ArgToken arg = _outgoing.at(slot)._arg; | |
234 | |
235 klassOop in_klass = NULL; | |
236 klassOop out_klass = NULL; | |
237 BasicType inpbt = java_lang_Class::as_BasicType(java_dyn_MethodType::ptype(incoming_mtype(), i), &in_klass); | |
238 BasicType outpbt = java_lang_Class::as_BasicType(java_dyn_MethodType::ptype(outgoing_mtype(), i), &out_klass); | |
239 assert(inpbt == arg.basic_type(), "sanity"); | |
240 | |
241 if (inpbt != outpbt) { | |
242 vmIntrinsics::ID iid = vmIntrinsics::for_raw_conversion(inpbt, outpbt); | |
243 if (iid == vmIntrinsics::_none) { | |
244 lose("no raw conversion method", CHECK_(empty)); | |
245 } | |
246 ArgToken arglist[2]; | |
247 arglist[0] = arg; // outgoing 'this' | |
248 arglist[1] = ArgToken(); // sentinel | |
249 arg = make_invoke(NULL, iid, Bytecodes::_invokestatic, false, 1, &arglist[0], CHECK_(empty)); | |
250 change_argument(inpbt, slot, outpbt, arg); | |
251 } | |
252 | |
253 i++; // We need to skip void slots at the top of the loop. | |
254 } | |
255 | |
256 BasicType inrbt = java_lang_Class::as_BasicType(java_dyn_MethodType::rtype(incoming_mtype())); | |
257 BasicType outrbt = java_lang_Class::as_BasicType(java_dyn_MethodType::rtype(outgoing_mtype())); | |
258 if (inrbt != outrbt) { | |
259 if (inrbt == T_INT && outrbt == T_VOID) { | |
260 // See comments in MethodHandles::same_basic_type_for_arguments. | |
261 } else { | |
262 assert(false, "IMPLEMENT ME"); | |
263 lose("no raw conversion method", CHECK_(empty)); | |
264 } | |
265 } | |
266 break; | |
267 } | |
200 | 268 |
201 case sun_dyn_AdapterMethodHandle::OP_CHECK_CAST: { | 269 case sun_dyn_AdapterMethodHandle::OP_CHECK_CAST: { |
202 // checkcast the Nth outgoing argument in place | 270 // checkcast the Nth outgoing argument in place |
203 klassOop dest_klass = NULL; | 271 klassOop dest_klass = NULL; |
204 BasicType dest = java_lang_Class::as_BasicType(chain().adapter_arg_oop(), &dest_klass); | 272 BasicType dest = java_lang_Class::as_BasicType(chain().adapter_arg_oop(), &dest_klass); |
205 assert(dest == T_OBJECT, ""); | 273 assert(dest == T_OBJECT, ""); |
206 assert(dest == arg_state->_type, ""); | 274 assert(dest == arg_state->_type, ""); |
207 arg_state->_arg = make_conversion(T_OBJECT, dest_klass, Bytecodes::_checkcast, arg_state->_arg, CHECK_NULL); | 275 ArgToken arg = arg_state->_arg; |
276 ArgToken new_arg = make_conversion(T_OBJECT, dest_klass, Bytecodes::_checkcast, arg, CHECK_(empty)); | |
277 assert(arg.index() == new_arg.index(), "should be the same index"); | |
208 debug_only(dest_klass = (klassOop)badOop); | 278 debug_only(dest_klass = (klassOop)badOop); |
209 break; | 279 break; |
210 } | 280 } |
211 | 281 |
212 case sun_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM: { | 282 case sun_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM: { |
216 Bytecodes::Code bc = conversion_code(src, dest); | 286 Bytecodes::Code bc = conversion_code(src, dest); |
217 ArgToken arg = arg_state->_arg; | 287 ArgToken arg = arg_state->_arg; |
218 if (bc == Bytecodes::_nop) { | 288 if (bc == Bytecodes::_nop) { |
219 break; | 289 break; |
220 } else if (bc != Bytecodes::_illegal) { | 290 } else if (bc != Bytecodes::_illegal) { |
221 arg = make_conversion(dest, NULL, bc, arg, CHECK_NULL); | 291 arg = make_conversion(dest, NULL, bc, arg, CHECK_(empty)); |
222 } else if (is_subword_type(dest)) { | 292 } else if (is_subword_type(dest)) { |
223 bc = conversion_code(src, T_INT); | 293 bc = conversion_code(src, T_INT); |
224 if (bc != Bytecodes::_illegal) { | 294 if (bc != Bytecodes::_illegal) { |
225 arg = make_conversion(dest, NULL, bc, arg, CHECK_NULL); | 295 arg = make_conversion(dest, NULL, bc, arg, CHECK_(empty)); |
226 bc = conversion_code(T_INT, dest); | 296 bc = conversion_code(T_INT, dest); |
227 arg = make_conversion(dest, NULL, bc, arg, CHECK_NULL); | 297 arg = make_conversion(dest, NULL, bc, arg, CHECK_(empty)); |
228 } | 298 } |
229 } | 299 } |
230 if (bc == Bytecodes::_illegal) { | 300 if (bc == Bytecodes::_illegal) { |
231 lose("bad primitive conversion", CHECK_NULL); | 301 lose("bad primitive conversion", CHECK_(empty)); |
232 } | 302 } |
233 change_argument(src, arg_slot, dest, arg); | 303 change_argument(src, arg_slot, dest, arg); |
234 break; | 304 break; |
235 } | 305 } |
236 | 306 |
237 case sun_dyn_AdapterMethodHandle::OP_REF_TO_PRIM: { | 307 case sun_dyn_AdapterMethodHandle::OP_REF_TO_PRIM: { |
238 // checkcast to wrapper type & call intValue, etc. | 308 // checkcast to wrapper type & call intValue, etc. |
239 BasicType dest = chain().adapter_conversion_dest_type(); | 309 BasicType dest = chain().adapter_conversion_dest_type(); |
240 ArgToken arg = arg_state->_arg; | 310 ArgToken arg = arg_state->_arg; |
241 arg = make_conversion(T_OBJECT, SystemDictionary::box_klass(dest), | 311 arg = make_conversion(T_OBJECT, SystemDictionary::box_klass(dest), |
242 Bytecodes::_checkcast, arg, CHECK_NULL); | 312 Bytecodes::_checkcast, arg, CHECK_(empty)); |
243 vmIntrinsics::ID unboxer = vmIntrinsics::for_unboxing(dest); | 313 vmIntrinsics::ID unboxer = vmIntrinsics::for_unboxing(dest); |
244 if (unboxer == vmIntrinsics::_none) { | 314 if (unboxer == vmIntrinsics::_none) { |
245 lose("no unboxing method", CHECK_NULL); | 315 lose("no unboxing method", CHECK_(empty)); |
246 } | 316 } |
247 ArgToken arglist[2]; | 317 ArgToken arglist[2]; |
248 arglist[0] = arg; // outgoing 'this' | 318 arglist[0] = arg; // outgoing 'this' |
249 arglist[1] = NULL; // sentinel | 319 arglist[1] = ArgToken(); // sentinel |
250 arg = make_invoke(NULL, unboxer, Bytecodes::_invokevirtual, false, 1, &arglist[0], CHECK_NULL); | 320 arg = make_invoke(NULL, unboxer, Bytecodes::_invokevirtual, false, 1, &arglist[0], CHECK_(empty)); |
251 change_argument(T_OBJECT, arg_slot, dest, arg); | 321 change_argument(T_OBJECT, arg_slot, dest, arg); |
252 break; | 322 break; |
253 } | 323 } |
254 | 324 |
255 case sun_dyn_AdapterMethodHandle::OP_PRIM_TO_REF: { | 325 case sun_dyn_AdapterMethodHandle::OP_PRIM_TO_REF: { |
256 // call wrapper type.valueOf | 326 // call wrapper type.valueOf |
257 BasicType src = chain().adapter_conversion_src_type(); | 327 BasicType src = chain().adapter_conversion_src_type(); |
258 ArgToken arg = arg_state->_arg; | 328 ArgToken arg = arg_state->_arg; |
259 vmIntrinsics::ID boxer = vmIntrinsics::for_boxing(src); | 329 vmIntrinsics::ID boxer = vmIntrinsics::for_boxing(src); |
260 if (boxer == vmIntrinsics::_none) { | 330 if (boxer == vmIntrinsics::_none) { |
261 lose("no boxing method", CHECK_NULL); | 331 lose("no boxing method", CHECK_(empty)); |
262 } | 332 } |
263 ArgToken arglist[2]; | 333 ArgToken arglist[2]; |
264 arglist[0] = arg; // outgoing value | 334 arglist[0] = arg; // outgoing value |
265 arglist[1] = NULL; // sentinel | 335 arglist[1] = ArgToken(); // sentinel |
266 arg = make_invoke(NULL, boxer, Bytecodes::_invokevirtual, false, 1, &arglist[0], CHECK_NULL); | 336 assert(false, "I think the argument count must be 1 instead of 0"); |
337 arg = make_invoke(NULL, boxer, Bytecodes::_invokevirtual, false, 0, &arglist[0], CHECK_(empty)); | |
267 change_argument(src, arg_slot, T_OBJECT, arg); | 338 change_argument(src, arg_slot, T_OBJECT, arg); |
268 break; | 339 break; |
269 } | 340 } |
270 | 341 |
271 case sun_dyn_AdapterMethodHandle::OP_SWAP_ARGS: { | 342 case sun_dyn_AdapterMethodHandle::OP_SWAP_ARGS: { |
272 int dest_arg_slot = chain().adapter_conversion_vminfo(); | 343 int dest_arg_slot = chain().adapter_conversion_vminfo(); |
273 if (!slot_has_argument(dest_arg_slot)) { | 344 if (!slot_has_argument(dest_arg_slot)) { |
274 lose("bad swap index", CHECK_NULL); | 345 lose("bad swap index", CHECK_(empty)); |
275 } | 346 } |
276 // a simple swap between two arguments | 347 // a simple swap between two arguments |
277 SlotState* dest_arg_state = slot_state(dest_arg_slot); | 348 SlotState* dest_arg_state = slot_state(dest_arg_slot); |
278 SlotState temp = (*dest_arg_state); | 349 SlotState temp = (*dest_arg_state); |
279 (*dest_arg_state) = (*arg_state); | 350 (*dest_arg_state) = (*arg_state); |
282 } | 353 } |
283 | 354 |
284 case sun_dyn_AdapterMethodHandle::OP_ROT_ARGS: { | 355 case sun_dyn_AdapterMethodHandle::OP_ROT_ARGS: { |
285 int dest_arg_slot = chain().adapter_conversion_vminfo(); | 356 int dest_arg_slot = chain().adapter_conversion_vminfo(); |
286 if (!slot_has_argument(dest_arg_slot) || arg_slot == dest_arg_slot) { | 357 if (!slot_has_argument(dest_arg_slot) || arg_slot == dest_arg_slot) { |
287 lose("bad rotate index", CHECK_NULL); | 358 lose("bad rotate index", CHECK_(empty)); |
288 } | 359 } |
289 SlotState* dest_arg_state = slot_state(dest_arg_slot); | 360 SlotState* dest_arg_state = slot_state(dest_arg_slot); |
290 // Rotate the source argument (plus following N slots) into the | 361 // Rotate the source argument (plus following N slots) into the |
291 // position occupied by the dest argument (plus following N slots). | 362 // position occupied by the dest argument (plus following N slots). |
292 int rotate_count = type2size[dest_arg_state->_type]; | 363 int rotate_count = type2size[dest_arg_state->_type]; |
308 } | 379 } |
309 | 380 |
310 case sun_dyn_AdapterMethodHandle::OP_DUP_ARGS: { | 381 case sun_dyn_AdapterMethodHandle::OP_DUP_ARGS: { |
311 int dup_slots = chain().adapter_conversion_stack_pushes(); | 382 int dup_slots = chain().adapter_conversion_stack_pushes(); |
312 if (dup_slots <= 0) { | 383 if (dup_slots <= 0) { |
313 lose("bad dup count", CHECK_NULL); | 384 lose("bad dup count", CHECK_(empty)); |
314 } | 385 } |
315 for (int i = 0; i < dup_slots; i++) { | 386 for (int i = 0; i < dup_slots; i++) { |
316 SlotState* dup = slot_state(arg_slot + 2*i); | 387 SlotState* dup = slot_state(arg_slot + 2*i); |
317 if (dup == NULL) break; // safety net | 388 if (dup == NULL) break; // safety net |
318 if (dup->_type != T_VOID) _outgoing_argc += 1; | 389 if (dup->_type != T_VOID) _outgoing_argc += 1; |
322 } | 393 } |
323 | 394 |
324 case sun_dyn_AdapterMethodHandle::OP_DROP_ARGS: { | 395 case sun_dyn_AdapterMethodHandle::OP_DROP_ARGS: { |
325 int drop_slots = -chain().adapter_conversion_stack_pushes(); | 396 int drop_slots = -chain().adapter_conversion_stack_pushes(); |
326 if (drop_slots <= 0) { | 397 if (drop_slots <= 0) { |
327 lose("bad drop count", CHECK_NULL); | 398 lose("bad drop count", CHECK_(empty)); |
328 } | 399 } |
329 for (int i = 0; i < drop_slots; i++) { | 400 for (int i = 0; i < drop_slots; i++) { |
330 SlotState* drop = slot_state(arg_slot); | 401 SlotState* drop = slot_state(arg_slot); |
331 if (drop == NULL) break; // safety net | 402 if (drop == NULL) break; // safety net |
332 if (drop->_type != T_VOID) _outgoing_argc -= 1; | 403 if (drop->_type != T_VOID) _outgoing_argc -= 1; |
334 } | 405 } |
335 break; | 406 break; |
336 } | 407 } |
337 | 408 |
338 case sun_dyn_AdapterMethodHandle::OP_COLLECT_ARGS: { //NYI, may GC | 409 case sun_dyn_AdapterMethodHandle::OP_COLLECT_ARGS: { //NYI, may GC |
339 lose("unimplemented", CHECK_NULL); | 410 lose("unimplemented", CHECK_(empty)); |
340 break; | 411 break; |
341 } | 412 } |
342 | 413 |
343 case sun_dyn_AdapterMethodHandle::OP_SPREAD_ARGS: { | 414 case sun_dyn_AdapterMethodHandle::OP_SPREAD_ARGS: { |
344 klassOop array_klass_oop = NULL; | 415 klassOop array_klass_oop = NULL; |
356 debug_only(element_klass_oop = (klassOop)badOop); | 427 debug_only(element_klass_oop = (klassOop)badOop); |
357 | 428 |
358 // Fetch the argument, which we will cast to the required array type. | 429 // Fetch the argument, which we will cast to the required array type. |
359 assert(arg_state->_type == T_OBJECT, ""); | 430 assert(arg_state->_type == T_OBJECT, ""); |
360 ArgToken array_arg = arg_state->_arg; | 431 ArgToken array_arg = arg_state->_arg; |
361 array_arg = make_conversion(T_OBJECT, array_klass(), Bytecodes::_checkcast, array_arg, CHECK_NULL); | 432 array_arg = make_conversion(T_OBJECT, array_klass(), Bytecodes::_checkcast, array_arg, CHECK_(empty)); |
362 change_argument(T_OBJECT, arg_slot, T_VOID, NULL); | 433 change_argument(T_OBJECT, arg_slot, T_VOID, ArgToken(tt_void)); |
363 | 434 |
364 // Check the required length. | 435 // Check the required length. |
365 int spread_slots = 1 + chain().adapter_conversion_stack_pushes(); | 436 int spread_slots = 1 + chain().adapter_conversion_stack_pushes(); |
366 int spread_length = spread_slots; | 437 int spread_length = spread_slots; |
367 if (type2size[element_type] == 2) { | 438 if (type2size[element_type] == 2) { |
368 if (spread_slots % 2 != 0) spread_slots = -1; // force error | 439 if (spread_slots % 2 != 0) spread_slots = -1; // force error |
369 spread_length = spread_slots / 2; | 440 spread_length = spread_slots / 2; |
370 } | 441 } |
371 if (spread_slots < 0) { | 442 if (spread_slots < 0) { |
372 lose("bad spread length", CHECK_NULL); | 443 lose("bad spread length", CHECK_(empty)); |
373 } | 444 } |
374 | 445 |
375 jvalue length_jvalue; length_jvalue.i = spread_length; | 446 jvalue length_jvalue; length_jvalue.i = spread_length; |
376 ArgToken length_arg = make_prim_constant(T_INT, &length_jvalue, CHECK_NULL); | 447 ArgToken length_arg = make_prim_constant(T_INT, &length_jvalue, CHECK_(empty)); |
377 // Call a built-in method known to the JVM to validate the length. | 448 // Call a built-in method known to the JVM to validate the length. |
378 ArgToken arglist[3]; | 449 ArgToken arglist[3]; |
379 arglist[0] = array_arg; // value to check | 450 arglist[0] = array_arg; // value to check |
380 arglist[1] = length_arg; // length to check | 451 arglist[1] = length_arg; // length to check |
381 arglist[2] = NULL; // sentinel | 452 arglist[2] = ArgToken(); // sentinel |
382 make_invoke(NULL, vmIntrinsics::_checkSpreadArgument, | 453 make_invoke(NULL, vmIntrinsics::_checkSpreadArgument, |
383 Bytecodes::_invokestatic, false, 3, &arglist[0], CHECK_NULL); | 454 Bytecodes::_invokestatic, false, 3, &arglist[0], CHECK_(empty)); |
384 | 455 |
385 // Spread out the array elements. | 456 // Spread out the array elements. |
386 Bytecodes::Code aload_op = Bytecodes::_aaload; | 457 Bytecodes::Code aload_op = Bytecodes::_aaload; |
387 if (element_type != T_OBJECT) { | 458 if (element_type != T_OBJECT) { |
388 lose("primitive array NYI", CHECK_NULL); | 459 lose("primitive array NYI", CHECK_(empty)); |
389 } | 460 } |
390 int ap = arg_slot; | 461 int ap = arg_slot; |
391 for (int i = 0; i < spread_length; i++) { | 462 for (int i = 0; i < spread_length; i++) { |
392 jvalue offset_jvalue; offset_jvalue.i = i; | 463 jvalue offset_jvalue; offset_jvalue.i = i; |
393 ArgToken offset_arg = make_prim_constant(T_INT, &offset_jvalue, CHECK_NULL); | 464 ArgToken offset_arg = make_prim_constant(T_INT, &offset_jvalue, CHECK_(empty)); |
394 ArgToken element_arg = make_fetch(element_type, element_klass(), aload_op, array_arg, offset_arg, CHECK_NULL); | 465 ArgToken element_arg = make_fetch(element_type, element_klass(), aload_op, array_arg, offset_arg, CHECK_(empty)); |
395 change_argument(T_VOID, ap, element_type, element_arg); | 466 change_argument(T_VOID, ap, element_type, element_arg); |
396 ap += type2size[element_type]; | 467 ap += type2size[element_type]; |
397 } | 468 } |
398 break; | 469 break; |
399 } | 470 } |
400 | 471 |
401 case sun_dyn_AdapterMethodHandle::OP_FLYBY: //NYI, runs Java code | 472 case sun_dyn_AdapterMethodHandle::OP_FLYBY: //NYI, runs Java code |
402 case sun_dyn_AdapterMethodHandle::OP_RICOCHET: //NYI, runs Java code | 473 case sun_dyn_AdapterMethodHandle::OP_RICOCHET: //NYI, runs Java code |
403 lose("unimplemented", CHECK_NULL); | 474 lose("unimplemented", CHECK_(empty)); |
404 break; | 475 break; |
405 | 476 |
406 default: | 477 default: |
407 lose("bad adapter conversion", CHECK_NULL); | 478 lose("bad adapter conversion", CHECK_(empty)); |
408 break; | 479 break; |
409 } | 480 } |
410 } | 481 } |
411 | 482 |
412 if (chain().is_bound()) { | 483 if (chain().is_bound()) { |
413 // push a new argument | 484 // push a new argument |
414 BasicType arg_type = chain().bound_arg_type(); | 485 BasicType arg_type = chain().bound_arg_type(); |
415 jint arg_slot = chain().bound_arg_slot(); | 486 jint arg_slot = chain().bound_arg_slot(); |
416 oop arg_oop = chain().bound_arg_oop(); | 487 oop arg_oop = chain().bound_arg_oop(); |
417 ArgToken arg = NULL; | 488 ArgToken arg; |
418 if (arg_type == T_OBJECT) { | 489 if (arg_type == T_OBJECT) { |
419 arg = make_oop_constant(arg_oop, CHECK_NULL); | 490 arg = make_oop_constant(arg_oop, CHECK_(empty)); |
420 } else { | 491 } else { |
421 jvalue arg_value; | 492 jvalue arg_value; |
422 BasicType bt = java_lang_boxing_object::get_value(arg_oop, &arg_value); | 493 BasicType bt = java_lang_boxing_object::get_value(arg_oop, &arg_value); |
423 if (bt == arg_type) { | 494 if (bt == arg_type) { |
424 arg = make_prim_constant(arg_type, &arg_value, CHECK_NULL); | 495 arg = make_prim_constant(arg_type, &arg_value, CHECK_(empty)); |
425 } else { | 496 } else { |
426 lose("bad bound value", CHECK_NULL); | 497 lose("bad bound value", CHECK_(empty)); |
427 } | 498 } |
428 } | 499 } |
429 debug_only(arg_oop = badOop); | 500 debug_only(arg_oop = badOop); |
430 change_argument(T_VOID, arg_slot, arg_type, arg); | 501 change_argument(T_VOID, arg_slot, arg_type, arg); |
431 } | 502 } |
432 | 503 |
433 // this test must come after the body of the loop | 504 // this test must come after the body of the loop |
434 if (!chain().is_last()) { | 505 if (!chain().is_last()) { |
435 chain().next(CHECK_NULL); | 506 chain().next(CHECK_(empty)); |
436 } else { | 507 } else { |
437 break; | 508 break; |
438 } | 509 } |
439 } | 510 } |
440 | 511 |
446 SlotState* arg_state = slot_state(i); | 517 SlotState* arg_state = slot_state(i); |
447 if (arg_state->_type == T_VOID) continue; | 518 if (arg_state->_type == T_VOID) continue; |
448 arglist[ap++] = _outgoing.at(i)._arg; | 519 arglist[ap++] = _outgoing.at(i)._arg; |
449 } | 520 } |
450 assert(ap == _outgoing_argc, ""); | 521 assert(ap == _outgoing_argc, ""); |
451 arglist[ap] = NULL; // add a sentinel, for the sake of asserts | 522 arglist[ap] = ArgToken(); // add a sentinel, for the sake of asserts |
452 return make_invoke(chain().last_method_oop(), | 523 return make_invoke(chain().last_method_oop(), |
453 vmIntrinsics::_none, | 524 vmIntrinsics::_none, |
454 chain().last_invoke_code(), true, | 525 chain().last_invoke_code(), true, |
455 ap, arglist, THREAD); | 526 ap, arglist, THREAD); |
456 } | 527 } |
457 | 528 |
529 | |
530 // ----------------------------------------------------------------------------- | |
531 // MethodHandleWalker::walk_incoming_state | |
532 // | |
458 void MethodHandleWalker::walk_incoming_state(TRAPS) { | 533 void MethodHandleWalker::walk_incoming_state(TRAPS) { |
459 Handle mtype(THREAD, chain().method_type_oop()); | 534 Handle mtype(THREAD, chain().method_type_oop()); |
460 int nptypes = java_dyn_MethodType::ptype_count(mtype()); | 535 int nptypes = java_dyn_MethodType::ptype_count(mtype()); |
461 _outgoing_argc = nptypes; | 536 _outgoing_argc = nptypes; |
462 int argp = nptypes - 1; | 537 int argp = nptypes - 1; |
463 if (argp >= 0) { | 538 if (argp >= 0) { |
464 _outgoing.at_grow(argp, make_state(T_VOID, NULL)); // presize | 539 _outgoing.at_grow(argp, make_state(T_VOID, ArgToken(tt_void))); // presize |
465 } | 540 } |
466 for (int i = 0; i < nptypes; i++) { | 541 for (int i = 0; i < nptypes; i++) { |
467 klassOop arg_type_klass = NULL; | 542 klassOop arg_type_klass = NULL; |
468 BasicType arg_type = java_lang_Class::as_BasicType( | 543 BasicType arg_type = java_lang_Class::as_BasicType( |
469 java_dyn_MethodType::ptype(mtype(), i), &arg_type_klass); | 544 java_dyn_MethodType::ptype(mtype(), i), &arg_type_klass); |
470 ArgToken arg = make_parameter(arg_type, arg_type_klass, i, CHECK); | 545 int index = new_local_index(arg_type); |
471 debug_only(arg_type_klass = (klassOop)NULL); | 546 ArgToken arg = make_parameter(arg_type, arg_type_klass, index, CHECK); |
547 debug_only(arg_type_klass = (klassOop) NULL); | |
472 _outgoing.at_put(argp, make_state(arg_type, arg)); | 548 _outgoing.at_put(argp, make_state(arg_type, arg)); |
473 if (type2size[arg_type] == 2) { | 549 if (type2size[arg_type] == 2) { |
474 // add the extra slot, so we can model the JVM stack | 550 // add the extra slot, so we can model the JVM stack |
475 _outgoing.insert_before(argp+1, make_state(T_VOID, NULL)); | 551 _outgoing.insert_before(argp+1, make_state(T_VOID, ArgToken(tt_void))); |
476 } | 552 } |
477 --argp; | 553 --argp; |
478 } | 554 } |
479 // call make_parameter at the end of the list for the return type | 555 // call make_parameter at the end of the list for the return type |
480 klassOop ret_type_klass = NULL; | 556 klassOop ret_type_klass = NULL; |
482 java_dyn_MethodType::rtype(mtype()), &ret_type_klass); | 558 java_dyn_MethodType::rtype(mtype()), &ret_type_klass); |
483 ArgToken ret = make_parameter(ret_type, ret_type_klass, -1, CHECK); | 559 ArgToken ret = make_parameter(ret_type, ret_type_klass, -1, CHECK); |
484 // ignore ret; client can catch it if needed | 560 // ignore ret; client can catch it if needed |
485 } | 561 } |
486 | 562 |
487 // this is messy because some kinds of arguments are paired with | 563 |
488 // companion slots containing an empty value | 564 // ----------------------------------------------------------------------------- |
565 // MethodHandleWalker::change_argument | |
566 // | |
567 // This is messy because some kinds of arguments are paired with | |
568 // companion slots containing an empty value. | |
489 void MethodHandleWalker::change_argument(BasicType old_type, int slot, BasicType new_type, | 569 void MethodHandleWalker::change_argument(BasicType old_type, int slot, BasicType new_type, |
490 MethodHandleWalker::ArgToken new_arg) { | 570 const ArgToken& new_arg) { |
491 int old_size = type2size[old_type]; | 571 int old_size = type2size[old_type]; |
492 int new_size = type2size[new_type]; | 572 int new_size = type2size[new_type]; |
493 if (old_size == new_size) { | 573 if (old_size == new_size) { |
494 // simple case first | 574 // simple case first |
495 _outgoing.at_put(slot, make_state(new_type, new_arg)); | 575 _outgoing.at_put(slot, make_state(new_type, new_arg)); |
496 } else if (old_size > new_size) { | 576 } else if (old_size > new_size) { |
497 for (int i = old_size-1; i >= new_size; i++) { | 577 for (int i = old_size - 1; i >= new_size; i--) { |
498 assert((i != 0) == (_outgoing.at(slot + i)._type == T_VOID), ""); | 578 assert((i != 0) == (_outgoing.at(slot + i)._type == T_VOID), ""); |
499 _outgoing.remove_at(slot + i); | 579 _outgoing.remove_at(slot + i); |
500 } | 580 } |
501 if (new_size > 0) | 581 if (new_size > 0) |
502 _outgoing.at_put(slot, make_state(new_type, new_arg)); | 582 _outgoing.at_put(slot, make_state(new_type, new_arg)); |
503 else | 583 else |
504 _outgoing_argc -= 1; // deleted a real argument | 584 _outgoing_argc -= 1; // deleted a real argument |
505 } else { | 585 } else { |
506 for (int i = old_size; i < new_size; i++) { | 586 for (int i = old_size; i < new_size; i++) { |
507 _outgoing.insert_before(slot+i, make_state(T_VOID, NULL)); | 587 _outgoing.insert_before(slot + i, make_state(T_VOID, ArgToken(tt_void))); |
508 } | 588 } |
509 _outgoing.at_put(slot, make_state(new_type, new_arg)); | 589 _outgoing.at_put(slot, make_state(new_type, new_arg)); |
510 if (old_size == 0) | 590 if (old_size == 0) |
511 _outgoing_argc += 1; // inserted a real argument | 591 _outgoing_argc += 1; // inserted a real argument |
512 } | 592 } |
524 return args_seen; | 604 return args_seen; |
525 } | 605 } |
526 #endif | 606 #endif |
527 | 607 |
528 | 608 |
529 void MethodHandleCompiler::compile(TRAPS) { | 609 // ----------------------------------------------------------------------------- |
610 // MethodHandleCompiler | |
611 | |
612 MethodHandleCompiler::MethodHandleCompiler(Handle root, methodHandle callee, bool is_invokedynamic, TRAPS) | |
613 : MethodHandleWalker(root, is_invokedynamic, THREAD), | |
614 _callee(callee), | |
615 _thread(THREAD), | |
616 _bytecode(THREAD, 50), | |
617 _constants(THREAD, 10), | |
618 _cur_stack(0), | |
619 _max_stack(0), | |
620 _rtype(T_ILLEGAL) | |
621 { | |
622 | |
623 // Element zero is always the null constant. | |
624 (void) _constants.append(NULL); | |
625 | |
626 // Set name and signature index. | |
627 _name_index = cpool_symbol_put(_callee->name()); | |
628 _signature_index = cpool_symbol_put(_callee->signature()); | |
629 | |
630 // Get return type klass. | |
631 Handle first_mtype(THREAD, chain().method_type_oop()); | |
632 // _rklass is NULL for primitives. | |
633 _rtype = java_lang_Class::as_BasicType(java_dyn_MethodType::rtype(first_mtype()), &_rklass); | |
634 | |
635 int params = _callee->size_of_parameters(); // Incoming arguments plus receiver. | |
636 _num_params = for_invokedynamic() ? params - 1 : params; // XXX Check if callee is static? | |
637 } | |
638 | |
639 | |
640 // ----------------------------------------------------------------------------- | |
641 // MethodHandleCompiler::compile | |
642 // | |
643 // Compile this MethodHandle into a bytecode adapter and return a | |
644 // methodOop. | |
645 methodHandle MethodHandleCompiler::compile(TRAPS) { | |
530 assert(_thread == THREAD, "must be same thread"); | 646 assert(_thread == THREAD, "must be same thread"); |
531 | 647 methodHandle nullHandle; |
532 _constant_oops.append(Handle()); // element zero is always the null constant | 648 (void) walk(CHECK_(nullHandle)); |
533 _constant_prims.append(NULL); | 649 return get_method_oop(CHECK_(nullHandle)); |
534 { | 650 } |
535 symbolOop sig | 651 |
536 = java_dyn_MethodType::as_signature(chain().method_type_oop(), true, CHECK); | 652 |
537 _signature_index = find_oop_constant(sig); | 653 void MethodHandleCompiler::emit_bc(Bytecodes::Code op, int index) { |
538 assert(signature() == sig, ""); | 654 Bytecodes::check(op); // Are we legal? |
539 } | 655 |
540 | 656 switch (op) { |
541 walk(CHECK); | 657 // b |
542 } | 658 case Bytecodes::_aconst_null: |
659 case Bytecodes::_iconst_m1: | |
660 case Bytecodes::_iconst_0: | |
661 case Bytecodes::_iconst_1: | |
662 case Bytecodes::_iconst_2: | |
663 case Bytecodes::_iconst_3: | |
664 case Bytecodes::_iconst_4: | |
665 case Bytecodes::_iconst_5: | |
666 case Bytecodes::_lconst_0: | |
667 case Bytecodes::_lconst_1: | |
668 case Bytecodes::_fconst_0: | |
669 case Bytecodes::_fconst_1: | |
670 case Bytecodes::_fconst_2: | |
671 case Bytecodes::_dconst_0: | |
672 case Bytecodes::_dconst_1: | |
673 case Bytecodes::_iload_0: | |
674 case Bytecodes::_iload_1: | |
675 case Bytecodes::_iload_2: | |
676 case Bytecodes::_iload_3: | |
677 case Bytecodes::_lload_0: | |
678 case Bytecodes::_lload_1: | |
679 case Bytecodes::_lload_2: | |
680 case Bytecodes::_lload_3: | |
681 case Bytecodes::_fload_0: | |
682 case Bytecodes::_fload_1: | |
683 case Bytecodes::_fload_2: | |
684 case Bytecodes::_fload_3: | |
685 case Bytecodes::_dload_0: | |
686 case Bytecodes::_dload_1: | |
687 case Bytecodes::_dload_2: | |
688 case Bytecodes::_dload_3: | |
689 case Bytecodes::_aload_0: | |
690 case Bytecodes::_aload_1: | |
691 case Bytecodes::_aload_2: | |
692 case Bytecodes::_aload_3: | |
693 case Bytecodes::_istore_0: | |
694 case Bytecodes::_istore_1: | |
695 case Bytecodes::_istore_2: | |
696 case Bytecodes::_istore_3: | |
697 case Bytecodes::_lstore_0: | |
698 case Bytecodes::_lstore_1: | |
699 case Bytecodes::_lstore_2: | |
700 case Bytecodes::_lstore_3: | |
701 case Bytecodes::_fstore_0: | |
702 case Bytecodes::_fstore_1: | |
703 case Bytecodes::_fstore_2: | |
704 case Bytecodes::_fstore_3: | |
705 case Bytecodes::_dstore_0: | |
706 case Bytecodes::_dstore_1: | |
707 case Bytecodes::_dstore_2: | |
708 case Bytecodes::_dstore_3: | |
709 case Bytecodes::_astore_0: | |
710 case Bytecodes::_astore_1: | |
711 case Bytecodes::_astore_2: | |
712 case Bytecodes::_astore_3: | |
713 case Bytecodes::_i2l: | |
714 case Bytecodes::_i2f: | |
715 case Bytecodes::_i2d: | |
716 case Bytecodes::_i2b: | |
717 case Bytecodes::_i2c: | |
718 case Bytecodes::_i2s: | |
719 case Bytecodes::_l2i: | |
720 case Bytecodes::_l2f: | |
721 case Bytecodes::_l2d: | |
722 case Bytecodes::_f2i: | |
723 case Bytecodes::_f2l: | |
724 case Bytecodes::_f2d: | |
725 case Bytecodes::_d2i: | |
726 case Bytecodes::_d2l: | |
727 case Bytecodes::_d2f: | |
728 case Bytecodes::_ireturn: | |
729 case Bytecodes::_lreturn: | |
730 case Bytecodes::_freturn: | |
731 case Bytecodes::_dreturn: | |
732 case Bytecodes::_areturn: | |
733 case Bytecodes::_return: | |
734 assert(strcmp(Bytecodes::format(op), "b") == 0, "wrong bytecode format"); | |
735 _bytecode.push(op); | |
736 break; | |
737 | |
738 // bi | |
739 case Bytecodes::_ldc: | |
740 case Bytecodes::_iload: | |
741 case Bytecodes::_lload: | |
742 case Bytecodes::_fload: | |
743 case Bytecodes::_dload: | |
744 case Bytecodes::_aload: | |
745 case Bytecodes::_istore: | |
746 case Bytecodes::_lstore: | |
747 case Bytecodes::_fstore: | |
748 case Bytecodes::_dstore: | |
749 case Bytecodes::_astore: | |
750 assert(strcmp(Bytecodes::format(op), "bi") == 0, "wrong bytecode format"); | |
751 assert((char) index == index, "index does not fit in 8-bit"); | |
752 _bytecode.push(op); | |
753 _bytecode.push(index); | |
754 break; | |
755 | |
756 // bii | |
757 case Bytecodes::_ldc2_w: | |
758 case Bytecodes::_checkcast: | |
759 assert(strcmp(Bytecodes::format(op), "bii") == 0, "wrong bytecode format"); | |
760 assert((short) index == index, "index does not fit in 16-bit"); | |
761 _bytecode.push(op); | |
762 _bytecode.push(index >> 8); | |
763 _bytecode.push(index); | |
764 break; | |
765 | |
766 // bjj | |
767 case Bytecodes::_invokestatic: | |
768 case Bytecodes::_invokespecial: | |
769 case Bytecodes::_invokevirtual: | |
770 assert(strcmp(Bytecodes::format(op), "bjj") == 0, "wrong bytecode format"); | |
771 assert((short) index == index, "index does not fit in 16-bit"); | |
772 _bytecode.push(op); | |
773 _bytecode.push(index >> 8); | |
774 _bytecode.push(index); | |
775 break; | |
776 | |
777 default: | |
778 ShouldNotReachHere(); | |
779 } | |
780 } | |
781 | |
782 | |
783 void MethodHandleCompiler::emit_load(BasicType bt, int index) { | |
784 if (index <= 3) { | |
785 switch (bt) { | |
786 case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT: | |
787 case T_INT: emit_bc(Bytecodes::cast(Bytecodes::_iload_0 + index)); break; | |
788 case T_LONG: emit_bc(Bytecodes::cast(Bytecodes::_lload_0 + index)); break; | |
789 case T_FLOAT: emit_bc(Bytecodes::cast(Bytecodes::_fload_0 + index)); break; | |
790 case T_DOUBLE: emit_bc(Bytecodes::cast(Bytecodes::_dload_0 + index)); break; | |
791 case T_OBJECT: emit_bc(Bytecodes::cast(Bytecodes::_aload_0 + index)); break; | |
792 default: | |
793 ShouldNotReachHere(); | |
794 } | |
795 } | |
796 else { | |
797 switch (bt) { | |
798 case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT: | |
799 case T_INT: emit_bc(Bytecodes::_iload, index); break; | |
800 case T_LONG: emit_bc(Bytecodes::_lload, index); break; | |
801 case T_FLOAT: emit_bc(Bytecodes::_fload, index); break; | |
802 case T_DOUBLE: emit_bc(Bytecodes::_dload, index); break; | |
803 case T_OBJECT: emit_bc(Bytecodes::_aload, index); break; | |
804 default: | |
805 ShouldNotReachHere(); | |
806 } | |
807 } | |
808 stack_push(bt); | |
809 } | |
810 | |
811 void MethodHandleCompiler::emit_store(BasicType bt, int index) { | |
812 if (index <= 3) { | |
813 switch (bt) { | |
814 case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT: | |
815 case T_INT: emit_bc(Bytecodes::cast(Bytecodes::_istore_0 + index)); break; | |
816 case T_LONG: emit_bc(Bytecodes::cast(Bytecodes::_lstore_0 + index)); break; | |
817 case T_FLOAT: emit_bc(Bytecodes::cast(Bytecodes::_fstore_0 + index)); break; | |
818 case T_DOUBLE: emit_bc(Bytecodes::cast(Bytecodes::_dstore_0 + index)); break; | |
819 case T_OBJECT: emit_bc(Bytecodes::cast(Bytecodes::_astore_0 + index)); break; | |
820 default: | |
821 ShouldNotReachHere(); | |
822 } | |
823 } | |
824 else { | |
825 switch (bt) { | |
826 case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT: | |
827 case T_INT: emit_bc(Bytecodes::_istore, index); break; | |
828 case T_LONG: emit_bc(Bytecodes::_lstore, index); break; | |
829 case T_FLOAT: emit_bc(Bytecodes::_fstore, index); break; | |
830 case T_DOUBLE: emit_bc(Bytecodes::_dstore, index); break; | |
831 case T_OBJECT: emit_bc(Bytecodes::_astore, index); break; | |
832 default: | |
833 ShouldNotReachHere(); | |
834 } | |
835 } | |
836 stack_pop(bt); | |
837 } | |
838 | |
839 | |
840 void MethodHandleCompiler::emit_load_constant(ArgToken arg) { | |
841 BasicType bt = arg.basic_type(); | |
842 switch (bt) { | |
843 case T_INT: { | |
844 jint value = arg.get_jint(); | |
845 if (-1 <= value && value <= 5) | |
846 emit_bc(Bytecodes::cast(Bytecodes::_iconst_0 + value)); | |
847 else | |
848 emit_bc(Bytecodes::_ldc, cpool_int_put(value)); | |
849 break; | |
850 } | |
851 case T_LONG: { | |
852 jlong value = arg.get_jlong(); | |
853 if (0 <= value && value <= 1) | |
854 emit_bc(Bytecodes::cast(Bytecodes::_lconst_0 + (int) value)); | |
855 else | |
856 emit_bc(Bytecodes::_ldc2_w, cpool_long_put(value)); | |
857 break; | |
858 } | |
859 case T_FLOAT: { | |
860 jfloat value = arg.get_jfloat(); | |
861 if (value == 0.0 || value == 1.0 || value == 2.0) | |
862 emit_bc(Bytecodes::cast(Bytecodes::_fconst_0 + (int) value)); | |
863 else | |
864 emit_bc(Bytecodes::_ldc, cpool_float_put(value)); | |
865 break; | |
866 } | |
867 case T_DOUBLE: { | |
868 jdouble value = arg.get_jdouble(); | |
869 if (value == 0.0 || value == 1.0) | |
870 emit_bc(Bytecodes::cast(Bytecodes::_dconst_0 + (int) value)); | |
871 else | |
872 emit_bc(Bytecodes::_ldc2_w, cpool_double_put(value)); | |
873 break; | |
874 } | |
875 case T_OBJECT: { | |
876 Handle value = arg.object(); | |
877 if (value.is_null()) | |
878 emit_bc(Bytecodes::_aconst_null); | |
879 else | |
880 emit_bc(Bytecodes::_ldc, cpool_object_put(value)); | |
881 break; | |
882 } | |
883 default: | |
884 ShouldNotReachHere(); | |
885 } | |
886 stack_push(bt); | |
887 } | |
888 | |
543 | 889 |
544 MethodHandleWalker::ArgToken | 890 MethodHandleWalker::ArgToken |
545 MethodHandleCompiler::make_conversion(BasicType type, klassOop tk, Bytecodes::Code op, | 891 MethodHandleCompiler::make_conversion(BasicType type, klassOop tk, Bytecodes::Code op, |
546 MethodHandleWalker::ArgToken src, TRAPS) { | 892 const ArgToken& src, TRAPS) { |
547 Unimplemented(); | 893 |
548 return NULL; | 894 BasicType srctype = src.basic_type(); |
549 } | 895 int index = src.index(); |
550 | 896 |
897 switch (op) { | |
898 case Bytecodes::_i2l: | |
899 case Bytecodes::_i2f: | |
900 case Bytecodes::_i2d: | |
901 case Bytecodes::_i2b: | |
902 case Bytecodes::_i2c: | |
903 case Bytecodes::_i2s: | |
904 | |
905 case Bytecodes::_l2i: | |
906 case Bytecodes::_l2f: | |
907 case Bytecodes::_l2d: | |
908 | |
909 case Bytecodes::_f2i: | |
910 case Bytecodes::_f2l: | |
911 case Bytecodes::_f2d: | |
912 | |
913 case Bytecodes::_d2i: | |
914 case Bytecodes::_d2l: | |
915 case Bytecodes::_d2f: | |
916 emit_load(srctype, index); | |
917 stack_pop(srctype); // pop the src type | |
918 emit_bc(op); | |
919 stack_push(type); // push the dest value | |
920 if (srctype != type) | |
921 index = new_local_index(type); | |
922 emit_store(type, index); | |
923 break; | |
924 | |
925 case Bytecodes::_checkcast: | |
926 emit_load(srctype, index); | |
927 emit_bc(op, cpool_klass_put(tk)); | |
928 emit_store(srctype, index); | |
929 break; | |
930 | |
931 default: | |
932 ShouldNotReachHere(); | |
933 } | |
934 | |
935 return make_parameter(type, tk, index, THREAD); | |
936 } | |
937 | |
938 | |
939 // ----------------------------------------------------------------------------- | |
940 // MethodHandleCompiler | |
941 // | |
942 | |
943 static jvalue zero_jvalue; | |
944 | |
945 // Emit bytecodes for the given invoke instruction. | |
551 MethodHandleWalker::ArgToken | 946 MethodHandleWalker::ArgToken |
552 MethodHandleCompiler::make_invoke(methodOop m, vmIntrinsics::ID iid, | 947 MethodHandleCompiler::make_invoke(methodOop m, vmIntrinsics::ID iid, |
553 Bytecodes::Code op, bool tailcall, | 948 Bytecodes::Code op, bool tailcall, |
554 int argc, MethodHandleWalker::ArgToken* argv, | 949 int argc, MethodHandleWalker::ArgToken* argv, |
555 TRAPS) { | 950 TRAPS) { |
556 // If tailcall, we have walked all the way to a direct method handle. | 951 if (m == NULL) { |
557 // Otherwise, make a recursive call to some helper routine. | 952 // Get the intrinsic methodOop. |
558 #ifdef ASSERT | 953 m = vmIntrinsics::method_for(iid); |
954 } | |
955 | |
956 klassOop klass = m->method_holder(); | |
957 symbolOop name = m->name(); | |
958 symbolOop signature = m->signature(); | |
959 | |
960 // This generated adapter method should be in the same class as the | |
961 // DMH target method (for accessability reasons). | |
962 if (tailcall) { | |
963 _target_klass = klass; | |
964 } | |
965 | |
966 // instanceKlass* ik = instanceKlass::cast(klass); | |
967 // tty->print_cr("MethodHandleCompiler::make_invoke: %s %s.%s%s", Bytecodes::name(op), ik->external_name(), name->as_C_string(), signature->as_C_string()); | |
968 | |
969 // Inline the method. | |
970 InvocationCounter* ic = m->invocation_counter(); | |
971 ic->set_carry(); | |
972 | |
973 for (int i = 0; i < argc; i++) { | |
974 ArgToken arg = argv[i]; | |
975 TokenType tt = arg.token_type(); | |
976 BasicType bt = arg.basic_type(); | |
977 | |
978 switch (tt) { | |
979 case tt_parameter: | |
980 case tt_temporary: | |
981 emit_load(bt, arg.index()); | |
982 break; | |
983 case tt_constant: | |
984 emit_load_constant(arg); | |
985 break; | |
986 case tt_illegal: | |
987 // Sentinel. | |
988 assert(i == (argc - 1), "sentinel must be last entry"); | |
989 break; | |
990 case tt_void: | |
991 default: | |
992 ShouldNotReachHere(); | |
993 } | |
994 } | |
995 | |
996 // Populate constant pool. | |
997 int name_index = cpool_symbol_put(name); | |
998 int signature_index = cpool_symbol_put(signature); | |
999 int name_and_type_index = cpool_name_and_type_put(name_index, signature_index); | |
1000 int klass_index = cpool_klass_put(klass); | |
1001 int methodref_index = cpool_methodref_put(klass_index, name_and_type_index); | |
1002 | |
1003 // Generate invoke. | |
559 switch (op) { | 1004 switch (op) { |
1005 case Bytecodes::_invokestatic: | |
1006 case Bytecodes::_invokespecial: | |
560 case Bytecodes::_invokevirtual: | 1007 case Bytecodes::_invokevirtual: |
561 case Bytecodes::_invokespecial: | 1008 emit_bc(op, methodref_index); |
562 case Bytecodes::_invokestatic: | 1009 break; |
563 case Bytecodes::_invokeinterface: | 1010 case Bytecodes::_invokeinterface: |
1011 Unimplemented(); | |
564 break; | 1012 break; |
565 default: | 1013 default: |
566 ShouldNotReachHere(); | 1014 ShouldNotReachHere(); |
567 } | 1015 } |
568 #endif //ASSERT | 1016 |
569 _bytes.put((char) op); | 1017 // If tailcall, we have walked all the way to a direct method handle. |
570 | 1018 // Otherwise, make a recursive call to some helper routine. |
571 Unimplemented(); | 1019 BasicType rbt = m->result_type(); |
572 return NULL; | 1020 ArgToken ret; |
1021 if (tailcall) { | |
1022 if (rbt != _rtype) { | |
1023 if (rbt == T_VOID) { | |
1024 // push a zero of the right sort | |
1025 ArgToken zero; | |
1026 if (_rtype == T_OBJECT) { | |
1027 zero = make_oop_constant(NULL, CHECK_(zero)); | |
1028 } else { | |
1029 zero = make_prim_constant(_rtype, &zero_jvalue, CHECK_(zero)); | |
1030 } | |
1031 emit_load_constant(zero); | |
1032 } else if (_rtype == T_VOID) { | |
1033 // We'll emit a _return with something on the stack. | |
1034 // It's OK to ignore what's on the stack. | |
1035 } else { | |
1036 tty->print_cr("*** rbt=%d != rtype=%d", rbt, _rtype); | |
1037 assert(false, "IMPLEMENT ME"); | |
1038 } | |
1039 } | |
1040 switch (_rtype) { | |
1041 case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT: | |
1042 case T_INT: emit_bc(Bytecodes::_ireturn); break; | |
1043 case T_LONG: emit_bc(Bytecodes::_lreturn); break; | |
1044 case T_FLOAT: emit_bc(Bytecodes::_freturn); break; | |
1045 case T_DOUBLE: emit_bc(Bytecodes::_dreturn); break; | |
1046 case T_VOID: emit_bc(Bytecodes::_return); break; | |
1047 case T_OBJECT: | |
1048 if (_rklass.not_null() && _rklass() != SystemDictionary::object_klass()) | |
1049 emit_bc(Bytecodes::_checkcast, cpool_klass_put(_rklass())); | |
1050 emit_bc(Bytecodes::_areturn); | |
1051 break; | |
1052 default: ShouldNotReachHere(); | |
1053 } | |
1054 ret = ArgToken(); // Dummy return value. | |
1055 } | |
1056 else { | |
1057 stack_push(rbt); // The return value is already pushed onto the stack. | |
1058 int index = new_local_index(rbt); | |
1059 switch (rbt) { | |
1060 case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT: | |
1061 case T_INT: case T_LONG: case T_FLOAT: case T_DOUBLE: | |
1062 case T_OBJECT: | |
1063 emit_store(rbt, index); | |
1064 ret = ArgToken(tt_temporary, rbt, index); | |
1065 break; | |
1066 case T_VOID: | |
1067 ret = ArgToken(tt_void); | |
1068 break; | |
1069 default: | |
1070 ShouldNotReachHere(); | |
1071 } | |
1072 } | |
1073 | |
1074 return ret; | |
573 } | 1075 } |
574 | 1076 |
575 MethodHandleWalker::ArgToken | 1077 MethodHandleWalker::ArgToken |
576 MethodHandleCompiler::make_fetch(BasicType type, klassOop tk, Bytecodes::Code op, | 1078 MethodHandleCompiler::make_fetch(BasicType type, klassOop tk, Bytecodes::Code op, |
577 MethodHandleWalker::ArgToken base, | 1079 const MethodHandleWalker::ArgToken& base, |
578 MethodHandleWalker::ArgToken offset, | 1080 const MethodHandleWalker::ArgToken& offset, |
579 TRAPS) { | 1081 TRAPS) { |
580 Unimplemented(); | 1082 Unimplemented(); |
581 return NULL; | 1083 return ArgToken(); |
582 } | 1084 } |
583 | 1085 |
584 int MethodHandleCompiler::find_oop_constant(oop con) { | 1086 |
585 if (con == NULL) return 0; | 1087 int MethodHandleCompiler::cpool_primitive_put(BasicType bt, jvalue* con) { |
586 for (int i = 1, imax = _constant_oops.length(); i < imax; i++) { | |
587 if (_constant_oops.at(i) == con) | |
588 return i; | |
589 } | |
590 _constant_prims.append(NULL); | |
591 return _constant_oops.append(con); | |
592 } | |
593 | |
594 int MethodHandleCompiler::find_prim_constant(BasicType bt, jvalue* con) { | |
595 jvalue con_copy; | 1088 jvalue con_copy; |
596 assert(bt < T_OBJECT, ""); | 1089 assert(bt < T_OBJECT, ""); |
597 if (type2aelembytes(bt) < jintSize) { | 1090 if (type2aelembytes(bt) < jintSize) { |
598 // widen to int | 1091 // widen to int |
599 con_copy = (*con); | 1092 con_copy = (*con); |
605 case T_SHORT: con->i = con->s; break; | 1098 case T_SHORT: con->i = con->s; break; |
606 default: ShouldNotReachHere(); | 1099 default: ShouldNotReachHere(); |
607 } | 1100 } |
608 bt = T_INT; | 1101 bt = T_INT; |
609 } | 1102 } |
610 for (int i = 1, imax = _constant_prims.length(); i < imax; i++) { | 1103 |
611 PrimCon* pcon = _constant_prims.at(i); | 1104 // for (int i = 1, imax = _constants.length(); i < imax; i++) { |
612 if (pcon != NULL && pcon->_type == bt) { | 1105 // ConstantValue* con = _constants.at(i); |
613 bool match = false; | 1106 // if (con != NULL && con->is_primitive() && con->_type == bt) { |
614 switch (type2size[bt]) { | 1107 // bool match = false; |
615 case 1: if (pcon->_value.i == con->i) match = true; break; | 1108 // switch (type2size[bt]) { |
616 case 2: if (pcon->_value.j == con->j) match = true; break; | 1109 // case 1: if (pcon->_value.i == con->i) match = true; break; |
617 } | 1110 // case 2: if (pcon->_value.j == con->j) match = true; break; |
618 if (match) | 1111 // } |
619 return i; | 1112 // if (match) |
620 } | 1113 // return i; |
621 } | 1114 // } |
622 PrimCon* pcon = new PrimCon(); | 1115 // } |
623 pcon->_type = bt; | 1116 ConstantValue* cv = new ConstantValue(bt, *con); |
624 pcon->_value = (*con); | 1117 int index = _constants.append(cv); |
625 _constant_oops.append(Handle()); | 1118 |
626 return _constant_prims.append(pcon); | 1119 // long and double entries take 2 slots, we add another empty entry. |
627 } | 1120 if (type2size[bt] == 2) |
628 | 1121 (void) _constants.append(NULL); |
1122 | |
1123 return index; | |
1124 } | |
1125 | |
1126 | |
1127 constantPoolHandle MethodHandleCompiler::get_constant_pool(TRAPS) const { | |
1128 constantPoolHandle nullHandle; | |
1129 bool is_conc_safe = true; | |
1130 constantPoolOop cpool_oop = oopFactory::new_constantPool(_constants.length(), is_conc_safe, CHECK_(nullHandle)); | |
1131 constantPoolHandle cpool(THREAD, cpool_oop); | |
1132 | |
1133 // Fill the real constant pool skipping the zero element. | |
1134 for (int i = 1; i < _constants.length(); i++) { | |
1135 ConstantValue* cv = _constants.at(i); | |
1136 switch (cv->tag()) { | |
1137 case JVM_CONSTANT_Utf8: cpool->symbol_at_put( i, cv->symbol_oop() ); break; | |
1138 case JVM_CONSTANT_Integer: cpool->int_at_put( i, cv->get_jint() ); break; | |
1139 case JVM_CONSTANT_Float: cpool->float_at_put( i, cv->get_jfloat() ); break; | |
1140 case JVM_CONSTANT_Long: cpool->long_at_put( i, cv->get_jlong() ); break; | |
1141 case JVM_CONSTANT_Double: cpool->double_at_put( i, cv->get_jdouble() ); break; | |
1142 case JVM_CONSTANT_Class: cpool->klass_at_put( i, cv->klass_oop() ); break; | |
1143 case JVM_CONSTANT_Methodref: cpool->method_at_put( i, cv->first_index(), cv->second_index()); break; | |
1144 case JVM_CONSTANT_NameAndType: cpool->name_and_type_at_put(i, cv->first_index(), cv->second_index()); break; | |
1145 case JVM_CONSTANT_Object: cpool->object_at_put( i, cv->object_oop() ); break; | |
1146 default: ShouldNotReachHere(); | |
1147 } | |
1148 | |
1149 switch (cv->tag()) { | |
1150 case JVM_CONSTANT_Long: | |
1151 case JVM_CONSTANT_Double: | |
1152 i++; // Skip empty entry. | |
1153 assert(_constants.at(i) == NULL, "empty entry"); | |
1154 break; | |
1155 } | |
1156 } | |
1157 | |
1158 // Set the constant pool holder to the target method's class. | |
1159 cpool->set_pool_holder(_target_klass()); | |
1160 | |
1161 return cpool; | |
1162 } | |
1163 | |
1164 | |
1165 methodHandle MethodHandleCompiler::get_method_oop(TRAPS) const { | |
1166 methodHandle nullHandle; | |
1167 // Create a method that holds the generated bytecode. invokedynamic | |
1168 // has no receiver, normal MH calls do. | |
1169 int flags_bits; | |
1170 if (for_invokedynamic()) | |
1171 flags_bits = (/*JVM_MH_INVOKE_BITS |*/ JVM_ACC_PUBLIC | JVM_ACC_FINAL | JVM_ACC_STATIC); | |
1172 else | |
1173 flags_bits = (/*JVM_MH_INVOKE_BITS |*/ JVM_ACC_PUBLIC | JVM_ACC_FINAL); | |
1174 | |
1175 bool is_conc_safe = true; | |
1176 methodOop m_oop = oopFactory::new_method(bytecode_length(), | |
1177 accessFlags_from(flags_bits), | |
1178 0, 0, 0, is_conc_safe, CHECK_(nullHandle)); | |
1179 methodHandle m(THREAD, m_oop); | |
1180 m_oop = NULL; // oop not GC safe | |
1181 | |
1182 constantPoolHandle cpool = get_constant_pool(CHECK_(nullHandle)); | |
1183 m->set_constants(cpool()); | |
1184 | |
1185 m->set_name_index(_name_index); | |
1186 m->set_signature_index(_signature_index); | |
1187 | |
1188 m->set_code((address) bytecode()); | |
1189 | |
1190 m->set_max_stack(_max_stack); | |
1191 m->set_max_locals(max_locals()); | |
1192 m->set_size_of_parameters(_num_params); | |
1193 | |
1194 typeArrayHandle exception_handlers(THREAD, Universe::the_empty_int_array()); | |
1195 m->set_exception_table(exception_handlers()); | |
1196 | |
1197 // Set the carry bit of the invocation counter to force inlining of | |
1198 // the adapter. | |
1199 InvocationCounter* ic = m->invocation_counter(); | |
1200 ic->set_carry(); | |
1201 | |
1202 // Rewrite the method and set up the constant pool cache. | |
1203 objArrayOop m_array = oopFactory::new_system_objArray(1, CHECK_(nullHandle)); | |
1204 objArrayHandle methods(THREAD, m_array); | |
1205 methods->obj_at_put(0, m()); | |
1206 Rewriter::rewrite(_target_klass(), cpool, methods, CHECK_(nullHandle)); // Use fake class. | |
629 | 1207 |
630 #ifndef PRODUCT | 1208 #ifndef PRODUCT |
631 | 1209 if (TraceMethodHandles) { |
1210 m->print(); | |
1211 m->print_codes(); | |
1212 } | |
1213 #endif //PRODUCT | |
1214 | |
1215 return m; | |
1216 } | |
1217 | |
1218 | |
1219 #ifndef PRODUCT | |
1220 | |
1221 #if 0 | |
632 // MH printer for debugging. | 1222 // MH printer for debugging. |
633 | 1223 |
634 class MethodHandlePrinter : public MethodHandleWalker { | 1224 class MethodHandlePrinter : public MethodHandleWalker { |
635 private: | 1225 private: |
636 outputStream* _out; | 1226 outputStream* _out; |
789 out->print("\n}\n"); | 1379 out->print("\n}\n"); |
790 } | 1380 } |
791 out->print("\n"); | 1381 out->print("\n"); |
792 } | 1382 } |
793 }; | 1383 }; |
1384 #endif // 0 | |
794 | 1385 |
795 extern "C" | 1386 extern "C" |
796 void print_method_handle(oop mh) { | 1387 void print_method_handle(oop mh) { |
797 if (java_dyn_MethodHandle::is_instance(mh)) { | 1388 if (java_dyn_MethodHandle::is_instance(mh)) { |
798 MethodHandlePrinter::print(mh); | 1389 //MethodHandlePrinter::print(mh); |
799 } else { | 1390 } else { |
800 tty->print("*** not a method handle: "); | 1391 tty->print("*** not a method handle: "); |
801 mh->print(); | 1392 mh->print(); |
802 } | 1393 } |
803 } | 1394 } |