methodHandles_x86.cpp revision 1472:c18cbe5936b8
1/*
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#include "incls/_precompiled.incl"
26#include "incls/_methodHandles_x86.cpp.incl"
27
28#define __ _masm->
29
30address MethodHandleEntry::start_compiled_entry(MacroAssembler* _masm,
31                                                address interpreted_entry) {
32  // Just before the actual machine code entry point, allocate space
33  // for a MethodHandleEntry::Data record, so that we can manage everything
34  // from one base pointer.
35  __ align(wordSize);
36  address target = __ pc() + sizeof(Data);
37  while (__ pc() < target) {
38    __ nop();
39    __ align(wordSize);
40  }
41
42  MethodHandleEntry* me = (MethodHandleEntry*) __ pc();
43  me->set_end_address(__ pc());         // set a temporary end_address
44  me->set_from_interpreted_entry(interpreted_entry);
45  me->set_type_checking_entry(NULL);
46
47  return (address) me;
48}
49
50MethodHandleEntry* MethodHandleEntry::finish_compiled_entry(MacroAssembler* _masm,
51                                                address start_addr) {
52  MethodHandleEntry* me = (MethodHandleEntry*) start_addr;
53  assert(me->end_address() == start_addr, "valid ME");
54
55  // Fill in the real end_address:
56  __ align(wordSize);
57  me->set_end_address(__ pc());
58
59  return me;
60}
61
62#ifdef ASSERT
63static void verify_argslot(MacroAssembler* _masm, Register argslot_reg,
64                           const char* error_message) {
65  // Verify that argslot lies within (rsp, rbp].
66  Label L_ok, L_bad;
67  __ cmpptr(argslot_reg, rbp);
68  __ jccb(Assembler::above, L_bad);
69  __ cmpptr(rsp, argslot_reg);
70  __ jccb(Assembler::below, L_ok);
71  __ bind(L_bad);
72  __ stop(error_message);
73  __ bind(L_ok);
74}
75#endif
76
77
78// Code generation
79address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm) {
80  // rbx: methodOop
81  // rcx: receiver method handle (must load from sp[MethodTypeForm.vmslots])
82  // rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted)
83  // rdx: garbage temp, blown away
84
85  Register rbx_method = rbx;
86  Register rcx_recv   = rcx;
87  Register rax_mtype  = rax;
88  Register rdx_temp   = rdx;
89
90  // emit WrongMethodType path first, to enable jccb back-branch from main path
91  Label wrong_method_type;
92  __ bind(wrong_method_type);
93  __ push(rax_mtype);       // required mtype
94  __ push(rcx_recv);        // bad mh (1st stacked argument)
95  __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry()));
96
97  // here's where control starts out:
98  __ align(CodeEntryAlignment);
99  address entry_point = __ pc();
100
101  // fetch the MethodType from the method handle into rax (the 'check' register)
102  {
103    Register tem = rbx_method;
104    for (jint* pchase = methodOopDesc::method_type_offsets_chain(); (*pchase) != -1; pchase++) {
105      __ movptr(rax_mtype, Address(tem, *pchase));
106      tem = rax_mtype;          // in case there is another indirection
107    }
108  }
109  Register rbx_temp = rbx_method; // done with incoming methodOop
110
111  // given the MethodType, find out where the MH argument is buried
112  __ movptr(rdx_temp, Address(rax_mtype,
113                              __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rbx_temp)));
114  __ movl(rdx_temp, Address(rdx_temp,
115                            __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, rbx_temp)));
116  __ movptr(rcx_recv, __ argument_address(rdx_temp));
117
118  __ check_method_handle_type(rax_mtype, rcx_recv, rdx_temp, wrong_method_type);
119  __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
120
121  return entry_point;
122}
123
124// Helper to insert argument slots into the stack.
125// arg_slots must be a multiple of stack_move_unit() and <= 0
126void MethodHandles::insert_arg_slots(MacroAssembler* _masm,
127                                     RegisterOrConstant arg_slots,
128                                     int arg_mask,
129                                     Register rax_argslot,
130                                     Register rbx_temp, Register rdx_temp, Register temp3_reg) {
131  assert(temp3_reg == noreg, "temp3 not required");
132  assert_different_registers(rax_argslot, rbx_temp, rdx_temp,
133                             (!arg_slots.is_register() ? rsp : arg_slots.as_register()));
134
135#ifdef ASSERT
136  verify_argslot(_masm, rax_argslot, "insertion point must fall within current frame");
137  if (arg_slots.is_register()) {
138    Label L_ok, L_bad;
139    __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD);
140    __ jccb(Assembler::greater, L_bad);
141    __ testl(arg_slots.as_register(), -stack_move_unit() - 1);
142    __ jccb(Assembler::zero, L_ok);
143    __ bind(L_bad);
144    __ stop("assert arg_slots <= 0 and clear low bits");
145    __ bind(L_ok);
146  } else {
147    assert(arg_slots.as_constant() <= 0, "");
148    assert(arg_slots.as_constant() % -stack_move_unit() == 0, "");
149  }
150#endif //ASSERT
151
152#ifdef _LP64
153  if (arg_slots.is_register()) {
154    // clean high bits of stack motion register (was loaded as an int)
155    __ movslq(arg_slots.as_register(), arg_slots.as_register());
156  }
157#endif
158
159  // Make space on the stack for the inserted argument(s).
160  // Then pull down everything shallower than rax_argslot.
161  // The stacked return address gets pulled down with everything else.
162  // That is, copy [rsp, argslot) downward by -size words.  In pseudo-code:
163  //   rsp -= size;
164  //   for (rdx = rsp + size; rdx < argslot; rdx++)
165  //     rdx[-size] = rdx[0]
166  //   argslot -= size;
167  __ mov(rdx_temp, rsp);                        // source pointer for copy
168  __ lea(rsp, Address(rsp, arg_slots, Address::times_ptr));
169  {
170    Label loop;
171    __ bind(loop);
172    // pull one word down each time through the loop
173    __ movptr(rbx_temp, Address(rdx_temp, 0));
174    __ movptr(Address(rdx_temp, arg_slots, Address::times_ptr), rbx_temp);
175    __ addptr(rdx_temp, wordSize);
176    __ cmpptr(rdx_temp, rax_argslot);
177    __ jccb(Assembler::less, loop);
178  }
179
180  // Now move the argslot down, to point to the opened-up space.
181  __ lea(rax_argslot, Address(rax_argslot, arg_slots, Address::times_ptr));
182}
183
184// Helper to remove argument slots from the stack.
185// arg_slots must be a multiple of stack_move_unit() and >= 0
186void MethodHandles::remove_arg_slots(MacroAssembler* _masm,
187                                    RegisterOrConstant arg_slots,
188                                    Register rax_argslot,
189                                     Register rbx_temp, Register rdx_temp, Register temp3_reg) {
190  assert(temp3_reg == noreg, "temp3 not required");
191  assert_different_registers(rax_argslot, rbx_temp, rdx_temp,
192                             (!arg_slots.is_register() ? rsp : arg_slots.as_register()));
193
194#ifdef ASSERT
195  // Verify that [argslot..argslot+size) lies within (rsp, rbp).
196  __ lea(rbx_temp, Address(rax_argslot, arg_slots, Address::times_ptr));
197  verify_argslot(_masm, rbx_temp, "deleted argument(s) must fall within current frame");
198  if (arg_slots.is_register()) {
199    Label L_ok, L_bad;
200    __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD);
201    __ jccb(Assembler::less, L_bad);
202    __ testl(arg_slots.as_register(), -stack_move_unit() - 1);
203    __ jccb(Assembler::zero, L_ok);
204    __ bind(L_bad);
205    __ stop("assert arg_slots >= 0 and clear low bits");
206    __ bind(L_ok);
207  } else {
208    assert(arg_slots.as_constant() >= 0, "");
209    assert(arg_slots.as_constant() % -stack_move_unit() == 0, "");
210  }
211#endif //ASSERT
212
213#ifdef _LP64
214  if (false) {                  // not needed, since register is positive
215    // clean high bits of stack motion register (was loaded as an int)
216    if (arg_slots.is_register())
217      __ movslq(arg_slots.as_register(), arg_slots.as_register());
218  }
219#endif
220
221  // Pull up everything shallower than rax_argslot.
222  // Then remove the excess space on the stack.
223  // The stacked return address gets pulled up with everything else.
224  // That is, copy [rsp, argslot) upward by size words.  In pseudo-code:
225  //   for (rdx = argslot-1; rdx >= rsp; --rdx)
226  //     rdx[size] = rdx[0]
227  //   argslot += size;
228  //   rsp += size;
229  __ lea(rdx_temp, Address(rax_argslot, -wordSize)); // source pointer for copy
230  {
231    Label loop;
232    __ bind(loop);
233    // pull one word up each time through the loop
234    __ movptr(rbx_temp, Address(rdx_temp, 0));
235    __ movptr(Address(rdx_temp, arg_slots, Address::times_ptr), rbx_temp);
236    __ addptr(rdx_temp, -wordSize);
237    __ cmpptr(rdx_temp, rsp);
238    __ jccb(Assembler::greaterEqual, loop);
239  }
240
241  // Now move the argslot up, to point to the just-copied block.
242  __ lea(rsp, Address(rsp, arg_slots, Address::times_ptr));
243  // And adjust the argslot address to point at the deletion point.
244  __ lea(rax_argslot, Address(rax_argslot, arg_slots, Address::times_ptr));
245}
246
247#ifndef PRODUCT
248extern "C" void print_method_handle(oop mh);
249void trace_method_handle_stub(const char* adaptername,
250                              oop mh,
251                              intptr_t* entry_sp,
252                              intptr_t* saved_sp,
253                              intptr_t* saved_bp) {
254  // called as a leaf from native code: do not block the JVM!
255  intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset];
256  intptr_t* base_sp = (intptr_t*) saved_bp[frame::interpreter_frame_monitor_block_top_offset];
257  printf("MH %s mh="INTPTR_FORMAT" sp=("INTPTR_FORMAT"+"INTX_FORMAT") stack_size="INTX_FORMAT" bp="INTPTR_FORMAT"\n",
258         adaptername, (intptr_t)mh, (intptr_t)entry_sp, (intptr_t)(saved_sp - entry_sp), (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp);
259  if (last_sp != saved_sp)
260    printf("*** last_sp="INTPTR_FORMAT"\n", (intptr_t)last_sp);
261  if (Verbose)  print_method_handle(mh);
262}
263#endif //PRODUCT
264
265// which conversion op types are implemented here?
266int MethodHandles::adapter_conversion_ops_supported_mask() {
267  return ((1<<sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY)
268         |(1<<sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW)
269         |(1<<sun_dyn_AdapterMethodHandle::OP_CHECK_CAST)
270         |(1<<sun_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM)
271         |(1<<sun_dyn_AdapterMethodHandle::OP_REF_TO_PRIM)
272         |(1<<sun_dyn_AdapterMethodHandle::OP_SWAP_ARGS)
273         |(1<<sun_dyn_AdapterMethodHandle::OP_ROT_ARGS)
274         |(1<<sun_dyn_AdapterMethodHandle::OP_DUP_ARGS)
275         |(1<<sun_dyn_AdapterMethodHandle::OP_DROP_ARGS)
276         //|(1<<sun_dyn_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG!
277         );
278  // FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS.
279}
280
281// Generate an "entry" field for a method handle.
282// This determines how the method handle will respond to calls.
283void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek) {
284  // Here is the register state during an interpreted call,
285  // as set up by generate_method_handle_interpreter_entry():
286  // - rbx: garbage temp (was MethodHandle.invoke methodOop, unused)
287  // - rcx: receiver method handle
288  // - rax: method handle type (only used by the check_mtype entry point)
289  // - rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted)
290  // - rdx: garbage temp, can blow away
291
292  Register rcx_recv    = rcx;
293  Register rax_argslot = rax;
294  Register rbx_temp    = rbx;
295  Register rdx_temp    = rdx;
296
297  // This guy is set up by prepare_to_jump_from_interpreted (from interpreted calls)
298  // and gen_c2i_adapter (from compiled calls):
299  Register saved_last_sp = LP64_ONLY(r13) NOT_LP64(rsi);
300
301  guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
302
303  // some handy addresses
304  Address rbx_method_fie(     rbx,      methodOopDesc::from_interpreted_offset() );
305
306  Address rcx_mh_vmtarget(    rcx_recv, java_dyn_MethodHandle::vmtarget_offset_in_bytes() );
307  Address rcx_dmh_vmindex(    rcx_recv, sun_dyn_DirectMethodHandle::vmindex_offset_in_bytes() );
308
309  Address rcx_bmh_vmargslot(  rcx_recv, sun_dyn_BoundMethodHandle::vmargslot_offset_in_bytes() );
310  Address rcx_bmh_argument(   rcx_recv, sun_dyn_BoundMethodHandle::argument_offset_in_bytes() );
311
312  Address rcx_amh_vmargslot(  rcx_recv, sun_dyn_AdapterMethodHandle::vmargslot_offset_in_bytes() );
313  Address rcx_amh_argument(   rcx_recv, sun_dyn_AdapterMethodHandle::argument_offset_in_bytes() );
314  Address rcx_amh_conversion( rcx_recv, sun_dyn_AdapterMethodHandle::conversion_offset_in_bytes() );
315  Address vmarg;                // __ argument_address(vmargslot)
316
317  const int java_mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes();
318
319  if (have_entry(ek)) {
320    __ nop();                   // empty stubs make SG sick
321    return;
322  }
323
324  address interp_entry = __ pc();
325  if (UseCompressedOops)  __ unimplemented("UseCompressedOops");
326
327#ifndef PRODUCT
328  if (TraceMethodHandles) {
329    __ push(rax); __ push(rbx); __ push(rcx); __ push(rdx); __ push(rsi); __ push(rdi);
330    __ lea(rax, Address(rsp, wordSize*6)); // entry_sp
331    // arguments:
332    __ push(rbp);               // interpreter frame pointer
333    __ push(rsi);               // saved_sp
334    __ push(rax);               // entry_sp
335    __ push(rcx);               // mh
336    __ push(rcx);
337    __ movptr(Address(rsp, 0), (intptr_t)entry_name(ek));
338    __ call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub), 5);
339    __ pop(rdi); __ pop(rsi); __ pop(rdx); __ pop(rcx); __ pop(rbx); __ pop(rax);
340  }
341#endif //PRODUCT
342
343  switch ((int) ek) {
344  case _raise_exception:
345    {
346      // Not a real MH entry, but rather shared code for raising an exception.
347      // Extra local arguments are pushed on stack, as required type at TOS+8,
348      // failing object (or NULL) at TOS+4, failing bytecode type at TOS.
349      // Beyond those local arguments are the PC, of course.
350      Register rdx_code = rdx_temp;
351      Register rcx_fail = rcx_recv;
352      Register rax_want = rax_argslot;
353      Register rdi_pc   = rdi;
354      __ pop(rdx_code);  // TOS+0
355      __ pop(rcx_fail);  // TOS+4
356      __ pop(rax_want);  // TOS+8
357      __ pop(rdi_pc);    // caller PC
358
359      __ mov(rsp, rsi);   // cut the stack back to where the caller started
360
361      // Repush the arguments as if coming from the interpreter.
362      __ push(rdx_code);
363      __ push(rcx_fail);
364      __ push(rax_want);
365
366      Register rbx_method = rbx_temp;
367      Label no_method;
368      // FIXME: fill in _raise_exception_method with a suitable sun.dyn method
369      __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method));
370      __ testptr(rbx_method, rbx_method);
371      __ jccb(Assembler::zero, no_method);
372      int jobject_oop_offset = 0;
373      __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset));  // dereference the jobject
374      __ testptr(rbx_method, rbx_method);
375      __ jccb(Assembler::zero, no_method);
376      __ verify_oop(rbx_method);
377      __ push(rdi_pc);          // and restore caller PC
378      __ jmp(rbx_method_fie);
379
380      // If we get here, the Java runtime did not do its job of creating the exception.
381      // Do something that is at least causes a valid throw from the interpreter.
382      __ bind(no_method);
383      __ pop(rax_want);
384      __ pop(rcx_fail);
385      __ push(rax_want);
386      __ push(rcx_fail);
387      __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry()));
388    }
389    break;
390
391  case _invokestatic_mh:
392  case _invokespecial_mh:
393    {
394      Register rbx_method = rbx_temp;
395      __ movptr(rbx_method, rcx_mh_vmtarget); // target is a methodOop
396      __ verify_oop(rbx_method);
397      // same as TemplateTable::invokestatic or invokespecial,
398      // minus the CP setup and profiling:
399      if (ek == _invokespecial_mh) {
400        // Must load & check the first argument before entering the target method.
401        __ load_method_handle_vmslots(rax_argslot, rcx_recv, rdx_temp);
402        __ movptr(rcx_recv, __ argument_address(rax_argslot, -1));
403        __ null_check(rcx_recv);
404        __ verify_oop(rcx_recv);
405      }
406      __ jmp(rbx_method_fie);
407    }
408    break;
409
410  case _invokevirtual_mh:
411    {
412      // same as TemplateTable::invokevirtual,
413      // minus the CP setup and profiling:
414
415      // pick out the vtable index and receiver offset from the MH,
416      // and then we can discard it:
417      __ load_method_handle_vmslots(rax_argslot, rcx_recv, rdx_temp);
418      Register rbx_index = rbx_temp;
419      __ movl(rbx_index, rcx_dmh_vmindex);
420      // Note:  The verifier allows us to ignore rcx_mh_vmtarget.
421      __ movptr(rcx_recv, __ argument_address(rax_argslot, -1));
422      __ null_check(rcx_recv, oopDesc::klass_offset_in_bytes());
423
424      // get receiver klass
425      Register rax_klass = rax_argslot;
426      __ load_klass(rax_klass, rcx_recv);
427      __ verify_oop(rax_klass);
428
429      // get target methodOop & entry point
430      const int base = instanceKlass::vtable_start_offset() * wordSize;
431      assert(vtableEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
432      Address vtable_entry_addr(rax_klass,
433                                rbx_index, Address::times_ptr,
434                                base + vtableEntry::method_offset_in_bytes());
435      Register rbx_method = rbx_temp;
436      __ movptr(rbx_method, vtable_entry_addr);
437
438      __ verify_oop(rbx_method);
439      __ jmp(rbx_method_fie);
440    }
441    break;
442
443  case _invokeinterface_mh:
444    {
445      // same as TemplateTable::invokeinterface,
446      // minus the CP setup and profiling:
447
448      // pick out the interface and itable index from the MH.
449      __ load_method_handle_vmslots(rax_argslot, rcx_recv, rdx_temp);
450      Register rdx_intf  = rdx_temp;
451      Register rbx_index = rbx_temp;
452      __ movptr(rdx_intf,  rcx_mh_vmtarget);
453      __ movl(rbx_index,   rcx_dmh_vmindex);
454      __ movptr(rcx_recv, __ argument_address(rax_argslot, -1));
455      __ null_check(rcx_recv, oopDesc::klass_offset_in_bytes());
456
457      // get receiver klass
458      Register rax_klass = rax_argslot;
459      __ load_klass(rax_klass, rcx_recv);
460      __ verify_oop(rax_klass);
461
462      Register rdi_temp   = rdi;
463      Register rbx_method = rbx_index;
464
465      // get interface klass
466      Label no_such_interface;
467      __ verify_oop(rdx_intf);
468      __ lookup_interface_method(rax_klass, rdx_intf,
469                                 // note: next two args must be the same:
470                                 rbx_index, rbx_method,
471                                 rdi_temp,
472                                 no_such_interface);
473
474      __ verify_oop(rbx_method);
475      __ jmp(rbx_method_fie);
476      __ hlt();
477
478      __ bind(no_such_interface);
479      // Throw an exception.
480      // For historical reasons, it will be IncompatibleClassChangeError.
481      __ pushptr(Address(rdx_intf, java_mirror_offset));  // required interface
482      __ push(rcx_recv);        // bad receiver
483      __ push((int)Bytecodes::_invokeinterface);  // who is complaining?
484      __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
485    }
486    break;
487
488  case _bound_ref_mh:
489  case _bound_int_mh:
490  case _bound_long_mh:
491  case _bound_ref_direct_mh:
492  case _bound_int_direct_mh:
493  case _bound_long_direct_mh:
494    {
495      bool direct_to_method = (ek >= _bound_ref_direct_mh);
496      BasicType arg_type  = T_ILLEGAL;
497      int       arg_mask  = _INSERT_NO_MASK;
498      int       arg_slots = -1;
499      get_ek_bound_mh_info(ek, arg_type, arg_mask, arg_slots);
500
501      // make room for the new argument:
502      __ movl(rax_argslot, rcx_bmh_vmargslot);
503      __ lea(rax_argslot, __ argument_address(rax_argslot));
504      insert_arg_slots(_masm, arg_slots * stack_move_unit(), arg_mask,
505                       rax_argslot, rbx_temp, rdx_temp);
506
507      // store bound argument into the new stack slot:
508      __ movptr(rbx_temp, rcx_bmh_argument);
509      Address prim_value_addr(rbx_temp, java_lang_boxing_object::value_offset_in_bytes(arg_type));
510      if (arg_type == T_OBJECT) {
511        __ movptr(Address(rax_argslot, 0), rbx_temp);
512      } else {
513        __ load_sized_value(rdx_temp, prim_value_addr,
514                            type2aelembytes(arg_type), is_signed_subword_type(arg_type));
515        __ movptr(Address(rax_argslot, 0), rdx_temp);
516#ifndef _LP64
517        if (arg_slots == 2) {
518          __ movl(rdx_temp, prim_value_addr.plus_disp(wordSize));
519          __ movl(Address(rax_argslot, Interpreter::stackElementSize), rdx_temp);
520        }
521#endif //_LP64
522      }
523
524      if (direct_to_method) {
525        Register rbx_method = rbx_temp;
526        __ movptr(rbx_method, rcx_mh_vmtarget);
527        __ verify_oop(rbx_method);
528        __ jmp(rbx_method_fie);
529      } else {
530        __ movptr(rcx_recv, rcx_mh_vmtarget);
531        __ verify_oop(rcx_recv);
532        __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
533      }
534    }
535    break;
536
537  case _adapter_retype_only:
538  case _adapter_retype_raw:
539    // immediately jump to the next MH layer:
540    __ movptr(rcx_recv, rcx_mh_vmtarget);
541    __ verify_oop(rcx_recv);
542    __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
543    // This is OK when all parameter types widen.
544    // It is also OK when a return type narrows.
545    break;
546
547  case _adapter_check_cast:
548    {
549      // temps:
550      Register rbx_klass = rbx_temp; // interesting AMH data
551
552      // check a reference argument before jumping to the next layer of MH:
553      __ movl(rax_argslot, rcx_amh_vmargslot);
554      vmarg = __ argument_address(rax_argslot);
555
556      // What class are we casting to?
557      __ movptr(rbx_klass, rcx_amh_argument); // this is a Class object!
558      __ movptr(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes()));
559
560      Label done;
561      __ movptr(rdx_temp, vmarg);
562      __ testptr(rdx_temp, rdx_temp);
563      __ jccb(Assembler::zero, done);         // no cast if null
564      __ load_klass(rdx_temp, rdx_temp);
565
566      // live at this point:
567      // - rbx_klass:  klass required by the target method
568      // - rdx_temp:   argument klass to test
569      // - rcx_recv:   adapter method handle
570      __ check_klass_subtype(rdx_temp, rbx_klass, rax_argslot, done);
571
572      // If we get here, the type check failed!
573      // Call the wrong_method_type stub, passing the failing argument type in rax.
574      Register rax_mtype = rax_argslot;
575      __ movl(rax_argslot, rcx_amh_vmargslot);  // reload argslot field
576      __ movptr(rdx_temp, vmarg);
577
578      __ pushptr(rcx_amh_argument); // required class
579      __ push(rdx_temp);            // bad object
580      __ push((int)Bytecodes::_checkcast);  // who is complaining?
581      __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
582
583      __ bind(done);
584      // get the new MH:
585      __ movptr(rcx_recv, rcx_mh_vmtarget);
586      __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
587    }
588    break;
589
590  case _adapter_prim_to_prim:
591  case _adapter_ref_to_prim:
592    // handled completely by optimized cases
593    __ stop("init_AdapterMethodHandle should not issue this");
594    break;
595
596  case _adapter_opt_i2i:        // optimized subcase of adapt_prim_to_prim
597//case _adapter_opt_f2i:        // optimized subcase of adapt_prim_to_prim
598  case _adapter_opt_l2i:        // optimized subcase of adapt_prim_to_prim
599  case _adapter_opt_unboxi:     // optimized subcase of adapt_ref_to_prim
600    {
601      // perform an in-place conversion to int or an int subword
602      __ movl(rax_argslot, rcx_amh_vmargslot);
603      vmarg = __ argument_address(rax_argslot);
604
605      switch (ek) {
606      case _adapter_opt_i2i:
607        __ movl(rdx_temp, vmarg);
608        break;
609      case _adapter_opt_l2i:
610        {
611          // just delete the extra slot; on a little-endian machine we keep the first
612          __ lea(rax_argslot, __ argument_address(rax_argslot, 1));
613          remove_arg_slots(_masm, -stack_move_unit(),
614                           rax_argslot, rbx_temp, rdx_temp);
615          vmarg = Address(rax_argslot, -Interpreter::stackElementSize);
616          __ movl(rdx_temp, vmarg);
617        }
618        break;
619      case _adapter_opt_unboxi:
620        {
621          // Load the value up from the heap.
622          __ movptr(rdx_temp, vmarg);
623          int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_INT);
624#ifdef ASSERT
625          for (int bt = T_BOOLEAN; bt < T_INT; bt++) {
626            if (is_subword_type(BasicType(bt)))
627              assert(value_offset == java_lang_boxing_object::value_offset_in_bytes(BasicType(bt)), "");
628          }
629#endif
630          __ null_check(rdx_temp, value_offset);
631          __ movl(rdx_temp, Address(rdx_temp, value_offset));
632          // We load this as a word.  Because we are little-endian,
633          // the low bits will be correct, but the high bits may need cleaning.
634          // The vminfo will guide us to clean those bits.
635        }
636        break;
637      default:
638        ShouldNotReachHere();
639      }
640
641      // Do the requested conversion and store the value.
642      Register rbx_vminfo = rbx_temp;
643      __ movl(rbx_vminfo, rcx_amh_conversion);
644      assert(CONV_VMINFO_SHIFT == 0, "preshifted");
645
646      // get the new MH:
647      __ movptr(rcx_recv, rcx_mh_vmtarget);
648      // (now we are done with the old MH)
649
650      // original 32-bit vmdata word must be of this form:
651      //    | MBZ:6 | signBitCount:8 | srcDstTypes:8 | conversionOp:8 |
652      __ xchgptr(rcx, rbx_vminfo);                // free rcx for shifts
653      __ shll(rdx_temp /*, rcx*/);
654      Label zero_extend, done;
655      __ testl(rcx, CONV_VMINFO_SIGN_FLAG);
656      __ jccb(Assembler::zero, zero_extend);
657
658      // this path is taken for int->byte, int->short
659      __ sarl(rdx_temp /*, rcx*/);
660      __ jmpb(done);
661
662      __ bind(zero_extend);
663      // this is taken for int->char
664      __ shrl(rdx_temp /*, rcx*/);
665
666      __ bind(done);
667      __ movl(vmarg, rdx_temp);  // Store the value.
668      __ xchgptr(rcx, rbx_vminfo);                // restore rcx_recv
669
670      __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
671    }
672    break;
673
674  case _adapter_opt_i2l:        // optimized subcase of adapt_prim_to_prim
675  case _adapter_opt_unboxl:     // optimized subcase of adapt_ref_to_prim
676    {
677      // perform an in-place int-to-long or ref-to-long conversion
678      __ movl(rax_argslot, rcx_amh_vmargslot);
679
680      // on a little-endian machine we keep the first slot and add another after
681      __ lea(rax_argslot, __ argument_address(rax_argslot, 1));
682      insert_arg_slots(_masm, stack_move_unit(), _INSERT_INT_MASK,
683                       rax_argslot, rbx_temp, rdx_temp);
684      Address vmarg1(rax_argslot, -Interpreter::stackElementSize);
685      Address vmarg2 = vmarg1.plus_disp(Interpreter::stackElementSize);
686
687      switch (ek) {
688      case _adapter_opt_i2l:
689        {
690#ifdef _LP64
691          __ movslq(rdx_temp, vmarg1);  // Load sign-extended
692          __ movq(vmarg1, rdx_temp);    // Store into first slot
693#else
694          __ movl(rdx_temp, vmarg1);
695          __ sarl(rdx_temp, BitsPerInt - 1);  // __ extend_sign()
696          __ movl(vmarg2, rdx_temp); // store second word
697#endif
698        }
699        break;
700      case _adapter_opt_unboxl:
701        {
702          // Load the value up from the heap.
703          __ movptr(rdx_temp, vmarg1);
704          int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_LONG);
705          assert(value_offset == java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE), "");
706          __ null_check(rdx_temp, value_offset);
707#ifdef _LP64
708          __ movq(rbx_temp, Address(rdx_temp, value_offset));
709          __ movq(vmarg1, rbx_temp);
710#else
711          __ movl(rbx_temp, Address(rdx_temp, value_offset + 0*BytesPerInt));
712          __ movl(rdx_temp, Address(rdx_temp, value_offset + 1*BytesPerInt));
713          __ movl(vmarg1, rbx_temp);
714          __ movl(vmarg2, rdx_temp);
715#endif
716        }
717        break;
718      default:
719        ShouldNotReachHere();
720      }
721
722      __ movptr(rcx_recv, rcx_mh_vmtarget);
723      __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
724    }
725    break;
726
727  case _adapter_opt_f2d:        // optimized subcase of adapt_prim_to_prim
728  case _adapter_opt_d2f:        // optimized subcase of adapt_prim_to_prim
729    {
730      // perform an in-place floating primitive conversion
731      __ movl(rax_argslot, rcx_amh_vmargslot);
732      __ lea(rax_argslot, __ argument_address(rax_argslot, 1));
733      if (ek == _adapter_opt_f2d) {
734        insert_arg_slots(_masm, stack_move_unit(), _INSERT_INT_MASK,
735                         rax_argslot, rbx_temp, rdx_temp);
736      }
737      Address vmarg(rax_argslot, -Interpreter::stackElementSize);
738
739#ifdef _LP64
740      if (ek == _adapter_opt_f2d) {
741        __ movflt(xmm0, vmarg);
742        __ cvtss2sd(xmm0, xmm0);
743        __ movdbl(vmarg, xmm0);
744      } else {
745        __ movdbl(xmm0, vmarg);
746        __ cvtsd2ss(xmm0, xmm0);
747        __ movflt(vmarg, xmm0);
748      }
749#else //_LP64
750      if (ek == _adapter_opt_f2d) {
751        __ fld_s(vmarg);        // load float to ST0
752        __ fstp_s(vmarg);       // store single
753      } else {
754        __ fld_d(vmarg);        // load double to ST0
755        __ fstp_s(vmarg);       // store single
756      }
757#endif //_LP64
758
759      if (ek == _adapter_opt_d2f) {
760        remove_arg_slots(_masm, -stack_move_unit(),
761                         rax_argslot, rbx_temp, rdx_temp);
762      }
763
764      __ movptr(rcx_recv, rcx_mh_vmtarget);
765      __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
766    }
767    break;
768
769  case _adapter_prim_to_ref:
770    __ unimplemented(entry_name(ek)); // %%% FIXME: NYI
771    break;
772
773  case _adapter_swap_args:
774  case _adapter_rot_args:
775    // handled completely by optimized cases
776    __ stop("init_AdapterMethodHandle should not issue this");
777    break;
778
779  case _adapter_opt_swap_1:
780  case _adapter_opt_swap_2:
781  case _adapter_opt_rot_1_up:
782  case _adapter_opt_rot_1_down:
783  case _adapter_opt_rot_2_up:
784  case _adapter_opt_rot_2_down:
785    {
786      int swap_bytes = 0, rotate = 0;
787      get_ek_adapter_opt_swap_rot_info(ek, swap_bytes, rotate);
788
789      // 'argslot' is the position of the first argument to swap
790      __ movl(rax_argslot, rcx_amh_vmargslot);
791      __ lea(rax_argslot, __ argument_address(rax_argslot));
792
793      // 'vminfo' is the second
794      Register rbx_destslot = rbx_temp;
795      __ movl(rbx_destslot, rcx_amh_conversion);
796      assert(CONV_VMINFO_SHIFT == 0, "preshifted");
797      __ andl(rbx_destslot, CONV_VMINFO_MASK);
798      __ lea(rbx_destslot, __ argument_address(rbx_destslot));
799      DEBUG_ONLY(verify_argslot(_masm, rbx_destslot, "swap point must fall within current frame"));
800
801      if (!rotate) {
802        for (int i = 0; i < swap_bytes; i += wordSize) {
803          __ movptr(rdx_temp, Address(rax_argslot , i));
804          __ push(rdx_temp);
805          __ movptr(rdx_temp, Address(rbx_destslot, i));
806          __ movptr(Address(rax_argslot, i), rdx_temp);
807          __ pop(rdx_temp);
808          __ movptr(Address(rbx_destslot, i), rdx_temp);
809        }
810      } else {
811        // push the first chunk, which is going to get overwritten
812        for (int i = swap_bytes; (i -= wordSize) >= 0; ) {
813          __ movptr(rdx_temp, Address(rax_argslot, i));
814          __ push(rdx_temp);
815        }
816
817        if (rotate > 0) {
818          // rotate upward
819          __ subptr(rax_argslot, swap_bytes);
820#ifdef ASSERT
821          {
822            // Verify that argslot > destslot, by at least swap_bytes.
823            Label L_ok;
824            __ cmpptr(rax_argslot, rbx_destslot);
825            __ jccb(Assembler::aboveEqual, L_ok);
826            __ stop("source must be above destination (upward rotation)");
827            __ bind(L_ok);
828          }
829#endif
830          // work argslot down to destslot, copying contiguous data upwards
831          // pseudo-code:
832          //   rax = src_addr - swap_bytes
833          //   rbx = dest_addr
834          //   while (rax >= rbx) *(rax + swap_bytes) = *(rax + 0), rax--;
835          Label loop;
836          __ bind(loop);
837          __ movptr(rdx_temp, Address(rax_argslot, 0));
838          __ movptr(Address(rax_argslot, swap_bytes), rdx_temp);
839          __ addptr(rax_argslot, -wordSize);
840          __ cmpptr(rax_argslot, rbx_destslot);
841          __ jccb(Assembler::aboveEqual, loop);
842        } else {
843          __ addptr(rax_argslot, swap_bytes);
844#ifdef ASSERT
845          {
846            // Verify that argslot < destslot, by at least swap_bytes.
847            Label L_ok;
848            __ cmpptr(rax_argslot, rbx_destslot);
849            __ jccb(Assembler::belowEqual, L_ok);
850            __ stop("source must be below destination (downward rotation)");
851            __ bind(L_ok);
852          }
853#endif
854          // work argslot up to destslot, copying contiguous data downwards
855          // pseudo-code:
856          //   rax = src_addr + swap_bytes
857          //   rbx = dest_addr
858          //   while (rax <= rbx) *(rax - swap_bytes) = *(rax + 0), rax++;
859          Label loop;
860          __ bind(loop);
861          __ movptr(rdx_temp, Address(rax_argslot, 0));
862          __ movptr(Address(rax_argslot, -swap_bytes), rdx_temp);
863          __ addptr(rax_argslot, wordSize);
864          __ cmpptr(rax_argslot, rbx_destslot);
865          __ jccb(Assembler::belowEqual, loop);
866        }
867
868        // pop the original first chunk into the destination slot, now free
869        for (int i = 0; i < swap_bytes; i += wordSize) {
870          __ pop(rdx_temp);
871          __ movptr(Address(rbx_destslot, i), rdx_temp);
872        }
873      }
874
875      __ movptr(rcx_recv, rcx_mh_vmtarget);
876      __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
877    }
878    break;
879
880  case _adapter_dup_args:
881    {
882      // 'argslot' is the position of the first argument to duplicate
883      __ movl(rax_argslot, rcx_amh_vmargslot);
884      __ lea(rax_argslot, __ argument_address(rax_argslot));
885
886      // 'stack_move' is negative number of words to duplicate
887      Register rdx_stack_move = rdx_temp;
888      __ movl2ptr(rdx_stack_move, rcx_amh_conversion);
889      __ sarptr(rdx_stack_move, CONV_STACK_MOVE_SHIFT);
890
891      int argslot0_num = 0;
892      Address argslot0 = __ argument_address(RegisterOrConstant(argslot0_num));
893      assert(argslot0.base() == rsp, "");
894      int pre_arg_size = argslot0.disp();
895      assert(pre_arg_size % wordSize == 0, "");
896      assert(pre_arg_size > 0, "must include PC");
897
898      // remember the old rsp+1 (argslot[0])
899      Register rbx_oldarg = rbx_temp;
900      __ lea(rbx_oldarg, argslot0);
901
902      // move rsp down to make room for dups
903      __ lea(rsp, Address(rsp, rdx_stack_move, Address::times_ptr));
904
905      // compute the new rsp+1 (argslot[0])
906      Register rdx_newarg = rdx_temp;
907      __ lea(rdx_newarg, argslot0);
908
909      __ push(rdi);             // need a temp
910      // (preceding push must be done after arg addresses are taken!)
911
912      // pull down the pre_arg_size data (PC)
913      for (int i = -pre_arg_size; i < 0; i += wordSize) {
914        __ movptr(rdi, Address(rbx_oldarg, i));
915        __ movptr(Address(rdx_newarg, i), rdi);
916      }
917
918      // copy from rax_argslot[0...] down to new_rsp[1...]
919      // pseudo-code:
920      //   rbx = old_rsp+1
921      //   rdx = new_rsp+1
922      //   rax = argslot
923      //   while (rdx < rbx) *rdx++ = *rax++
924      Label loop;
925      __ bind(loop);
926      __ movptr(rdi, Address(rax_argslot, 0));
927      __ movptr(Address(rdx_newarg, 0), rdi);
928      __ addptr(rax_argslot, wordSize);
929      __ addptr(rdx_newarg, wordSize);
930      __ cmpptr(rdx_newarg, rbx_oldarg);
931      __ jccb(Assembler::less, loop);
932
933      __ pop(rdi);              // restore temp
934
935      __ movptr(rcx_recv, rcx_mh_vmtarget);
936      __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
937    }
938    break;
939
940  case _adapter_drop_args:
941    {
942      // 'argslot' is the position of the first argument to nuke
943      __ movl(rax_argslot, rcx_amh_vmargslot);
944      __ lea(rax_argslot, __ argument_address(rax_argslot));
945
946      __ push(rdi);             // need a temp
947      // (must do previous push after argslot address is taken)
948
949      // 'stack_move' is number of words to drop
950      Register rdi_stack_move = rdi;
951      __ movl2ptr(rdi_stack_move, rcx_amh_conversion);
952      __ sarptr(rdi_stack_move, CONV_STACK_MOVE_SHIFT);
953      remove_arg_slots(_masm, rdi_stack_move,
954                       rax_argslot, rbx_temp, rdx_temp);
955
956      __ pop(rdi);              // restore temp
957
958      __ movptr(rcx_recv, rcx_mh_vmtarget);
959      __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
960    }
961    break;
962
963  case _adapter_collect_args:
964    __ unimplemented(entry_name(ek)); // %%% FIXME: NYI
965    break;
966
967  case _adapter_spread_args:
968    // handled completely by optimized cases
969    __ stop("init_AdapterMethodHandle should not issue this");
970    break;
971
972  case _adapter_opt_spread_0:
973  case _adapter_opt_spread_1:
974  case _adapter_opt_spread_more:
975    {
976      // spread an array out into a group of arguments
977      int length_constant = get_ek_adapter_opt_spread_info(ek);
978
979      // find the address of the array argument
980      __ movl(rax_argslot, rcx_amh_vmargslot);
981      __ lea(rax_argslot, __ argument_address(rax_argslot));
982
983      // grab some temps
984      { __ push(rsi); __ push(rdi); }
985      // (preceding pushes must be done after argslot address is taken!)
986#define UNPUSH_RSI_RDI \
987      { __ pop(rdi); __ pop(rsi); }
988
989      // arx_argslot points both to the array and to the first output arg
990      vmarg = Address(rax_argslot, 0);
991
992      // Get the array value.
993      Register  rsi_array       = rsi;
994      Register  rdx_array_klass = rdx_temp;
995      BasicType elem_type       = T_OBJECT;
996      int       length_offset   = arrayOopDesc::length_offset_in_bytes();
997      int       elem0_offset    = arrayOopDesc::base_offset_in_bytes(elem_type);
998      __ movptr(rsi_array, vmarg);
999      Label skip_array_check;
1000      if (length_constant == 0) {
1001        __ testptr(rsi_array, rsi_array);
1002        __ jcc(Assembler::zero, skip_array_check);
1003      }
1004      __ null_check(rsi_array, oopDesc::klass_offset_in_bytes());
1005      __ load_klass(rdx_array_klass, rsi_array);
1006
1007      // Check the array type.
1008      Register rbx_klass = rbx_temp;
1009      __ movptr(rbx_klass, rcx_amh_argument); // this is a Class object!
1010      __ movptr(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes()));
1011
1012      Label ok_array_klass, bad_array_klass, bad_array_length;
1013      __ check_klass_subtype(rdx_array_klass, rbx_klass, rdi, ok_array_klass);
1014      // If we get here, the type check failed!
1015      __ jmp(bad_array_klass);
1016      __ bind(ok_array_klass);
1017
1018      // Check length.
1019      if (length_constant >= 0) {
1020        __ cmpl(Address(rsi_array, length_offset), length_constant);
1021      } else {
1022        Register rbx_vminfo = rbx_temp;
1023        __ movl(rbx_vminfo, rcx_amh_conversion);
1024        assert(CONV_VMINFO_SHIFT == 0, "preshifted");
1025        __ andl(rbx_vminfo, CONV_VMINFO_MASK);
1026        __ cmpl(rbx_vminfo, Address(rsi_array, length_offset));
1027      }
1028      __ jcc(Assembler::notEqual, bad_array_length);
1029
1030      Register rdx_argslot_limit = rdx_temp;
1031
1032      // Array length checks out.  Now insert any required stack slots.
1033      if (length_constant == -1) {
1034        // Form a pointer to the end of the affected region.
1035        __ lea(rdx_argslot_limit, Address(rax_argslot, Interpreter::stackElementSize));
1036        // 'stack_move' is negative number of words to insert
1037        Register rdi_stack_move = rdi;
1038        __ movl2ptr(rdi_stack_move, rcx_amh_conversion);
1039        __ sarptr(rdi_stack_move, CONV_STACK_MOVE_SHIFT);
1040        Register rsi_temp = rsi_array;  // spill this
1041        insert_arg_slots(_masm, rdi_stack_move, -1,
1042                         rax_argslot, rbx_temp, rsi_temp);
1043        // reload the array (since rsi was killed)
1044        __ movptr(rsi_array, vmarg);
1045      } else if (length_constant > 1) {
1046        int arg_mask = 0;
1047        int new_slots = (length_constant - 1);
1048        for (int i = 0; i < new_slots; i++) {
1049          arg_mask <<= 1;
1050          arg_mask |= _INSERT_REF_MASK;
1051        }
1052        insert_arg_slots(_masm, new_slots * stack_move_unit(), arg_mask,
1053                         rax_argslot, rbx_temp, rdx_temp);
1054      } else if (length_constant == 1) {
1055        // no stack resizing required
1056      } else if (length_constant == 0) {
1057        remove_arg_slots(_masm, -stack_move_unit(),
1058                         rax_argslot, rbx_temp, rdx_temp);
1059      }
1060
1061      // Copy from the array to the new slots.
1062      // Note: Stack change code preserves integrity of rax_argslot pointer.
1063      // So even after slot insertions, rax_argslot still points to first argument.
1064      if (length_constant == -1) {
1065        // [rax_argslot, rdx_argslot_limit) is the area we are inserting into.
1066        Register rsi_source = rsi_array;
1067        __ lea(rsi_source, Address(rsi_array, elem0_offset));
1068        Label loop;
1069        __ bind(loop);
1070        __ movptr(rbx_temp, Address(rsi_source, 0));
1071        __ movptr(Address(rax_argslot, 0), rbx_temp);
1072        __ addptr(rsi_source, type2aelembytes(elem_type));
1073        __ addptr(rax_argslot, Interpreter::stackElementSize);
1074        __ cmpptr(rax_argslot, rdx_argslot_limit);
1075        __ jccb(Assembler::less, loop);
1076      } else if (length_constant == 0) {
1077        __ bind(skip_array_check);
1078        // nothing to copy
1079      } else {
1080        int elem_offset = elem0_offset;
1081        int slot_offset = 0;
1082        for (int index = 0; index < length_constant; index++) {
1083          __ movptr(rbx_temp, Address(rsi_array, elem_offset));
1084          __ movptr(Address(rax_argslot, slot_offset), rbx_temp);
1085          elem_offset += type2aelembytes(elem_type);
1086           slot_offset += Interpreter::stackElementSize;
1087        }
1088      }
1089
1090      // Arguments are spread.  Move to next method handle.
1091      UNPUSH_RSI_RDI;
1092      __ movptr(rcx_recv, rcx_mh_vmtarget);
1093      __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
1094
1095      __ bind(bad_array_klass);
1096      UNPUSH_RSI_RDI;
1097      __ pushptr(Address(rdx_array_klass, java_mirror_offset)); // required type
1098      __ pushptr(vmarg);                // bad array
1099      __ push((int)Bytecodes::_aaload); // who is complaining?
1100      __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
1101
1102      __ bind(bad_array_length);
1103      UNPUSH_RSI_RDI;
1104      __ push(rcx_recv);        // AMH requiring a certain length
1105      __ pushptr(vmarg);        // bad array
1106      __ push((int)Bytecodes::_arraylength); // who is complaining?
1107      __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
1108
1109#undef UNPUSH_RSI_RDI
1110    }
1111    break;
1112
1113  case _adapter_flyby:
1114  case _adapter_ricochet:
1115    __ unimplemented(entry_name(ek)); // %%% FIXME: NYI
1116    break;
1117
1118  default:  ShouldNotReachHere();
1119  }
1120  __ hlt();
1121
1122  address me_cookie = MethodHandleEntry::start_compiled_entry(_masm, interp_entry);
1123  __ unimplemented(entry_name(ek)); // %%% FIXME: NYI
1124
1125  init_entry(ek, MethodHandleEntry::finish_compiled_entry(_masm, me_cookie));
1126}
1127