hotspot/src/share/vm/prims/methodHandles.hpp
author ysr
Thu, 03 Dec 2009 15:01:57 -0800
changeset 4461 c17c526d36ef
parent 4094 1f424b2b2171
child 5050 47ecd86932ce
permissions -rw-r--r--
6906727: UseCompressedOops: some card-marking fixes related to object arrays Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17). Reviewed-by: kvn, coleenp, jmasa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
     1
/*
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
     2
 * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
     4
 *
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
     7
 * published by the Free Software Foundation.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
     8
 *
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    13
 * accompanied this code).
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    14
 *
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    18
 *
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    21
 * have any questions.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    22
 *
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    23
 */
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    24
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    25
class MacroAssembler;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    26
class Label;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    27
class MethodHandleEntry;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    28
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    29
class MethodHandles: AllStatic {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    30
  // JVM support for MethodHandle, MethodType, and related types
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    31
  // in java.dyn and java.dyn.hotspot.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    32
  // See also  javaClasses for layouts java_dyn_Method{Handle,Type,Type::Form}.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    33
 public:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    34
  enum EntryKind {
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
    35
    _raise_exception,           // stub for error generation from other stubs
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    36
    _invokestatic_mh,           // how a MH emulates invokestatic
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    37
    _invokespecial_mh,          // ditto for the other invokes...
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    38
    _invokevirtual_mh,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    39
    _invokeinterface_mh,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    40
    _bound_ref_mh,              // reference argument is bound
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    41
    _bound_int_mh,              // int argument is bound (via an Integer or Float)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    42
    _bound_long_mh,             // long argument is bound (via a Long or Double)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    43
    _bound_ref_direct_mh,       // same as above, with direct linkage to methodOop
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    44
    _bound_int_direct_mh,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    45
    _bound_long_direct_mh,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    46
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    47
    _adapter_mh_first,     // adapter sequence goes here...
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    48
    _adapter_retype_only   = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY,
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
    49
    _adapter_retype_raw    = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW,
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    50
    _adapter_check_cast    = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_CHECK_CAST,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    51
    _adapter_prim_to_prim  = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    52
    _adapter_ref_to_prim   = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_REF_TO_PRIM,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    53
    _adapter_prim_to_ref   = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_PRIM_TO_REF,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    54
    _adapter_swap_args     = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_SWAP_ARGS,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    55
    _adapter_rot_args      = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_ROT_ARGS,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    56
    _adapter_dup_args      = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_DUP_ARGS,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    57
    _adapter_drop_args     = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_DROP_ARGS,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    58
    _adapter_collect_args  = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_COLLECT_ARGS,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    59
    _adapter_spread_args   = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_SPREAD_ARGS,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    60
    _adapter_flyby         = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_FLYBY,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    61
    _adapter_ricochet      = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_RICOCHET,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    62
    _adapter_mh_last       = _adapter_mh_first + sun_dyn_AdapterMethodHandle::CONV_OP_LIMIT - 1,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    63
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    64
    // Optimized adapter types
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    65
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    66
    // argument list reordering
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    67
    _adapter_opt_swap_1,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    68
    _adapter_opt_swap_2,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    69
    _adapter_opt_rot_1_up,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    70
    _adapter_opt_rot_1_down,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    71
    _adapter_opt_rot_2_up,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    72
    _adapter_opt_rot_2_down,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    73
    // primitive single to single:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    74
    _adapter_opt_i2i,           // i2c, i2z, i2b, i2s
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    75
    // primitive double to single:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    76
    _adapter_opt_l2i,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    77
    _adapter_opt_d2f,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    78
    // primitive single to double:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    79
    _adapter_opt_i2l,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    80
    _adapter_opt_f2d,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    81
    // conversion between floating point and integer type is handled by Java
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    82
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    83
    // reference to primitive:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    84
    _adapter_opt_unboxi,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    85
    _adapter_opt_unboxl,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    86
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    87
    // spreading (array length cases 0, 1, >=2)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    88
    _adapter_opt_spread_0,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    89
    _adapter_opt_spread_1,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    90
    _adapter_opt_spread_more,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    91
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    92
    _EK_LIMIT,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    93
    _EK_FIRST = 0
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    94
  };
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    95
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    96
 public:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    97
  static bool enabled()                         { return _enabled; }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    98
  static void set_enabled(bool z);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    99
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   100
 private:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   101
  enum {  // import sun_dyn_AdapterMethodHandle::CONV_OP_*
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   102
    CONV_OP_LIMIT         = sun_dyn_AdapterMethodHandle::CONV_OP_LIMIT,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   103
    CONV_OP_MASK          = sun_dyn_AdapterMethodHandle::CONV_OP_MASK,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   104
    CONV_VMINFO_MASK      = sun_dyn_AdapterMethodHandle::CONV_VMINFO_MASK,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   105
    CONV_VMINFO_SHIFT     = sun_dyn_AdapterMethodHandle::CONV_VMINFO_SHIFT,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   106
    CONV_OP_SHIFT         = sun_dyn_AdapterMethodHandle::CONV_OP_SHIFT,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   107
    CONV_DEST_TYPE_SHIFT  = sun_dyn_AdapterMethodHandle::CONV_DEST_TYPE_SHIFT,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   108
    CONV_SRC_TYPE_SHIFT   = sun_dyn_AdapterMethodHandle::CONV_SRC_TYPE_SHIFT,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   109
    CONV_STACK_MOVE_SHIFT = sun_dyn_AdapterMethodHandle::CONV_STACK_MOVE_SHIFT,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   110
    CONV_STACK_MOVE_MASK  = sun_dyn_AdapterMethodHandle::CONV_STACK_MOVE_MASK
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   111
  };
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   112
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   113
  static bool _enabled;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   114
  static MethodHandleEntry* _entries[_EK_LIMIT];
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   115
  static const char*        _entry_names[_EK_LIMIT+1];
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   116
  static jobject            _raise_exception_method;
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   117
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   118
  static bool ek_valid(EntryKind ek)            { return (uint)ek < (uint)_EK_LIMIT; }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   119
  static bool conv_op_valid(int op)             { return (uint)op < (uint)CONV_OP_LIMIT; }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   120
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   121
 public:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   122
  static bool    have_entry(EntryKind ek)       { return ek_valid(ek) && _entries[ek] != NULL; }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   123
  static MethodHandleEntry* entry(EntryKind ek) { assert(ek_valid(ek), "initialized");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   124
                                                  return _entries[ek]; }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   125
  static const char* entry_name(EntryKind ek)   { assert(ek_valid(ek), "oob");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   126
                                                  return _entry_names[ek]; }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   127
  static EntryKind adapter_entry_kind(int op)   { assert(conv_op_valid(op), "oob");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   128
                                                  return EntryKind(_adapter_mh_first + op); }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   129
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   130
  static void init_entry(EntryKind ek, MethodHandleEntry* me) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   131
    assert(ek_valid(ek), "oob");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   132
    assert(_entries[ek] == NULL, "no double initialization");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   133
    _entries[ek] = me;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   134
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   135
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   136
  static methodOop raise_exception_method() {
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   137
    oop rem = JNIHandles::resolve(_raise_exception_method);
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   138
    assert(rem == NULL || rem->is_method(), "");
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   139
    return (methodOop) rem;
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   140
  }
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   141
  static void set_raise_exception_method(methodOop rem) {
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   142
    assert(_raise_exception_method == NULL, "");
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   143
    _raise_exception_method = JNIHandles::make_global(Handle(rem));
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   144
  }
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   145
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   146
  static jint adapter_conversion(int conv_op, BasicType src, BasicType dest,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   147
                                 int stack_move = 0, int vminfo = 0) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   148
    assert(conv_op_valid(conv_op), "oob");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   149
    jint conv = ((conv_op      << CONV_OP_SHIFT)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   150
                 | (src        << CONV_SRC_TYPE_SHIFT)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   151
                 | (dest       << CONV_DEST_TYPE_SHIFT)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   152
                 | (stack_move << CONV_STACK_MOVE_SHIFT)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   153
                 | (vminfo     << CONV_VMINFO_SHIFT)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   154
                 );
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   155
    assert(adapter_conversion_op(conv) == conv_op, "decode conv_op");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   156
    assert(adapter_conversion_src_type(conv) == src, "decode src");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   157
    assert(adapter_conversion_dest_type(conv) == dest, "decode dest");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   158
    assert(adapter_conversion_stack_move(conv) == stack_move, "decode stack_move");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   159
    assert(adapter_conversion_vminfo(conv) == vminfo, "decode vminfo");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   160
    return conv;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   161
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   162
  static int adapter_conversion_op(jint conv) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   163
    return ((conv >> CONV_OP_SHIFT) & 0xF);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   164
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   165
  static BasicType adapter_conversion_src_type(jint conv) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   166
    return (BasicType)((conv >> CONV_SRC_TYPE_SHIFT) & 0xF);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   167
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   168
  static BasicType adapter_conversion_dest_type(jint conv) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   169
    return (BasicType)((conv >> CONV_DEST_TYPE_SHIFT) & 0xF);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   170
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   171
  static int adapter_conversion_stack_move(jint conv) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   172
    return (conv >> CONV_STACK_MOVE_SHIFT);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   173
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   174
  static int adapter_conversion_vminfo(jint conv) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   175
    return (conv >> CONV_VMINFO_SHIFT) & CONV_VMINFO_MASK;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   176
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   177
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   178
  // Offset in words that the interpreter stack pointer moves when an argument is pushed.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   179
  // The stack_move value must always be a multiple of this.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   180
  static int stack_move_unit() {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   181
    return frame::interpreter_frame_expression_stack_direction() * Interpreter::stackElementWords();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   182
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   183
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   184
  enum { CONV_VMINFO_SIGN_FLAG = 0x80 };
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   185
  static int adapter_subword_vminfo(BasicType dest) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   186
    if (dest == T_BOOLEAN) return (BitsPerInt -  1);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   187
    if (dest == T_CHAR)    return (BitsPerInt - 16);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   188
    if (dest == T_BYTE)    return (BitsPerInt -  8) | CONV_VMINFO_SIGN_FLAG;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   189
    if (dest == T_SHORT)   return (BitsPerInt - 16) | CONV_VMINFO_SIGN_FLAG;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   190
    return 0;                   // case T_INT
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   191
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   192
  // Here is the transformation the i2i adapter must perform:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   193
  static int truncate_subword_from_vminfo(jint value, int vminfo) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   194
    jint tem = value << vminfo;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   195
    if ((vminfo & CONV_VMINFO_SIGN_FLAG) != 0) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   196
      return (jint)tem >> vminfo;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   197
    } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   198
      return (juint)tem >> vminfo;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   199
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   200
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   201
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   202
  static inline address from_compiled_entry(EntryKind ek);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   203
  static inline address from_interpreted_entry(EntryKind ek);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   204
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   205
  // helpers for decode_method.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   206
  static methodOop decode_methodOop(methodOop m, int& decode_flags_result);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   207
  static methodOop decode_vmtarget(oop vmtarget, int vmindex, oop mtype, klassOop& receiver_limit_result, int& decode_flags_result);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   208
  static methodOop decode_MemberName(oop mname, klassOop& receiver_limit_result, int& decode_flags_result);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   209
  static methodOop decode_MethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   210
  static methodOop decode_DirectMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   211
  static methodOop decode_BoundMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   212
  static methodOop decode_AdapterMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   213
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   214
  // Find out how many stack slots an mh pushes or pops.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   215
  // The result is *not* reported as a multiple of stack_move_unit();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   216
  // It is a signed net number of pushes (a difference in vmslots).
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   217
  // To compare with a stack_move value, first multiply by stack_move_unit().
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   218
  static int decode_MethodHandle_stack_pushes(oop mh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   219
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   220
 public:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   221
  // working with member names
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   222
  static void resolve_MemberName(Handle mname, TRAPS); // compute vmtarget/vmindex from name/type
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   223
  static void expand_MemberName(Handle mname, int suppress, TRAPS);  // expand defc/name/type if missing
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   224
  static void init_MemberName(oop mname_oop, oop target); // compute vmtarget/vmindex from target
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   225
  static void init_MemberName(oop mname_oop, methodOop m, bool do_dispatch);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   226
  static void init_MemberName(oop mname_oop, klassOop field_holder, AccessFlags mods, int offset);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   227
  static int find_MemberNames(klassOop k, symbolOop name, symbolOop sig,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   228
                              int mflags, klassOop caller,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   229
                              int skip, objArrayOop results);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   230
  // bit values for suppress argument to expand_MemberName:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   231
  enum { _suppress_defc = 1, _suppress_name = 2, _suppress_type = 4 };
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   232
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   233
  // called from InterpreterGenerator and StubGenerator
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   234
  static address generate_method_handle_interpreter_entry(MacroAssembler* _masm);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   235
  static void generate_method_handle_stub(MacroAssembler* _masm, EntryKind ek);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   236
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   237
  // argument list parsing
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   238
  static int argument_slot(oop method_type, int arg);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   239
  static int argument_slot_count(oop method_type) { return argument_slot(method_type, -1); }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   240
  static int argument_slot_to_argnum(oop method_type, int argslot);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   241
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   242
  // Runtime support
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   243
  enum {                        // bit-encoded flags from decode_method or decode_vmref
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   244
    _dmf_has_receiver   = 0x01, // target method has leading reference argument
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   245
    _dmf_does_dispatch  = 0x02, // method handle performs virtual or interface dispatch
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   246
    _dmf_from_interface = 0x04, // peforms interface dispatch
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   247
    _DMF_DIRECT_MASK    = (_dmf_from_interface*2 - _dmf_has_receiver),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   248
    _dmf_binds_method   = 0x08,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   249
    _dmf_binds_argument = 0x10,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   250
    _DMF_BOUND_MASK     = (_dmf_binds_argument*2 - _dmf_binds_method),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   251
    _dmf_adapter_lsb    = 0x20,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   252
    _DMF_ADAPTER_MASK   = (_dmf_adapter_lsb << CONV_OP_LIMIT) - _dmf_adapter_lsb
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   253
  };
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   254
  static methodOop decode_method(oop x, klassOop& receiver_limit_result, int& decode_flags_result);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   255
  enum {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   256
    // format of query to getConstant:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   257
    GC_JVM_PUSH_LIMIT = 0,
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   258
    GC_JVM_STACK_MOVE_UNIT = 1,
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   259
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   260
    // format of result from getTarget / encode_target:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   261
    ETF_HANDLE_OR_METHOD_NAME = 0, // all available data (immediate MH or method)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   262
    ETF_DIRECT_HANDLE         = 1, // ultimate method handle (will be a DMH, may be self)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   263
    ETF_METHOD_NAME           = 2, // ultimate method as MemberName
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   264
    ETF_REFLECT_METHOD        = 3  // ultimate method as java.lang.reflect object (sans refClass)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   265
  };
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   266
  static int get_named_constant(int which, Handle name_box, TRAPS);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   267
  static oop encode_target(Handle mh, int format, TRAPS); // report vmtarget (to Java code)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   268
  static bool class_cast_needed(klassOop src, klassOop dst);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   269
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   270
 private:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   271
  // These checkers operate on a pair of whole MethodTypes:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   272
  static const char* check_method_type_change(oop src_mtype, int src_beg, int src_end,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   273
                                              int insert_argnum, oop insert_type,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   274
                                              int change_argnum, oop change_type,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   275
                                              int delete_argnum,
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   276
                                              oop dst_mtype, int dst_beg, int dst_end,
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   277
                                              bool raw = false);
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   278
  static const char* check_method_type_insertion(oop src_mtype,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   279
                                                 int insert_argnum, oop insert_type,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   280
                                                 oop dst_mtype) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   281
    oop no_ref = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   282
    return check_method_type_change(src_mtype, 0, -1,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   283
                                    insert_argnum, insert_type,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   284
                                    -1, no_ref, -1, dst_mtype, 0, -1);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   285
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   286
  static const char* check_method_type_conversion(oop src_mtype,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   287
                                                  int change_argnum, oop change_type,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   288
                                                  oop dst_mtype) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   289
    oop no_ref = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   290
    return check_method_type_change(src_mtype, 0, -1, -1, no_ref,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   291
                                    change_argnum, change_type,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   292
                                    -1, dst_mtype, 0, -1);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   293
  }
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   294
  static const char* check_method_type_passthrough(oop src_mtype, oop dst_mtype, bool raw) {
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   295
    oop no_ref = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   296
    return check_method_type_change(src_mtype, 0, -1,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   297
                                    -1, no_ref, -1, no_ref, -1,
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   298
                                    dst_mtype, 0, -1, raw);
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   299
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   300
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   301
  // These checkers operate on pairs of argument or return types:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   302
  static const char* check_argument_type_change(BasicType src_type, klassOop src_klass,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   303
                                                BasicType dst_type, klassOop dst_klass,
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   304
                                                int argnum, bool raw = false);
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   305
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   306
  static const char* check_argument_type_change(oop src_type, oop dst_type,
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   307
                                                int argnum, bool raw = false) {
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   308
    klassOop src_klass = NULL, dst_klass = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   309
    BasicType src_bt = java_lang_Class::as_BasicType(src_type, &src_klass);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   310
    BasicType dst_bt = java_lang_Class::as_BasicType(dst_type, &dst_klass);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   311
    return check_argument_type_change(src_bt, src_klass,
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   312
                                      dst_bt, dst_klass, argnum, raw);
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   313
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   314
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   315
  static const char* check_return_type_change(oop src_type, oop dst_type, bool raw = false) {
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   316
    return check_argument_type_change(src_type, dst_type, -1, raw);
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   317
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   318
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   319
  static const char* check_return_type_change(BasicType src_type, klassOop src_klass,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   320
                                              BasicType dst_type, klassOop dst_klass) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   321
    return check_argument_type_change(src_type, src_klass, dst_type, dst_klass, -1);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   322
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   323
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   324
  static const char* check_method_receiver(methodOop m, klassOop passed_recv_type);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   325
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   326
  // These verifiers can block, and will throw an error if the checking fails:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   327
  static void verify_vmslots(Handle mh, TRAPS);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   328
  static void verify_vmargslot(Handle mh, int argnum, int argslot, TRAPS);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   329
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   330
  static void verify_method_type(methodHandle m, Handle mtype,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   331
                                 bool has_bound_oop,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   332
                                 KlassHandle bound_oop_type,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   333
                                 TRAPS);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   334
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   335
  static void verify_method_signature(methodHandle m, Handle mtype,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   336
                                      int first_ptype_pos,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   337
                                      KlassHandle insert_ptype, TRAPS);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   338
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   339
  static void verify_DirectMethodHandle(Handle mh, methodHandle m, TRAPS);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   340
  static void verify_BoundMethodHandle(Handle mh, Handle target, int argnum,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   341
                                       bool direct_to_method, TRAPS);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   342
  static void verify_BoundMethodHandle_with_receiver(Handle mh, methodHandle m, TRAPS);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   343
  static void verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   344
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   345
 public:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   346
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   347
  // Fill in the fields of a DirectMethodHandle mh.  (MH.type must be pre-filled.)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   348
  static void init_DirectMethodHandle(Handle mh, methodHandle method, bool do_dispatch, TRAPS);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   349
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   350
  // Fill in the fields of a BoundMethodHandle mh.  (MH.type, BMH.argument must be pre-filled.)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   351
  static void init_BoundMethodHandle(Handle mh, Handle target, int argnum, TRAPS);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   352
  static void init_BoundMethodHandle_with_receiver(Handle mh,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   353
                                                   methodHandle original_m,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   354
                                                   KlassHandle receiver_limit,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   355
                                                   int decode_flags,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   356
                                                   TRAPS);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   357
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   358
  // Fill in the fields of an AdapterMethodHandle mh.  (MH.type must be pre-filled.)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   359
  static void init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   360
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   361
#ifdef ASSERT
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   362
  static bool spot_check_entry_names();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   363
#endif
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   364
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   365
 private:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   366
  static methodHandle dispatch_decoded_method(methodHandle m,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   367
                                              KlassHandle receiver_limit,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   368
                                              int decode_flags,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   369
                                              KlassHandle receiver_klass,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   370
                                              TRAPS);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   371
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   372
  static bool same_basic_type_for_arguments(BasicType src, BasicType dst,
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   373
                                            bool raw = false,
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   374
                                            bool for_return = false);
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   375
  static bool same_basic_type_for_returns(BasicType src, BasicType dst, bool raw = false) {
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2534
diff changeset
   376
    return same_basic_type_for_arguments(src, dst, raw, true);
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   377
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   378
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   379
  enum {                        // arg_mask values
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   380
    _INSERT_NO_MASK   = -1,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   381
    _INSERT_REF_MASK  = 0,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   382
    _INSERT_INT_MASK  = 1,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   383
    _INSERT_LONG_MASK = 3
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   384
  };
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   385
  static void insert_arg_slots(MacroAssembler* _masm,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   386
                               RegisterOrConstant arg_slots,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   387
                               int arg_mask,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   388
                               Register rax_argslot,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   389
                               Register rbx_temp, Register rdx_temp);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   390
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   391
  static void remove_arg_slots(MacroAssembler* _masm,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   392
                               RegisterOrConstant arg_slots,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   393
                               Register rax_argslot,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   394
                               Register rbx_temp, Register rdx_temp);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   395
};
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   396
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   397
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   398
// Access methods for the "entry" field of a java.dyn.MethodHandle.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   399
// The field is primarily a jump target for compiled calls.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   400
// However, we squirrel away some nice pointers for other uses,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   401
// just before the jump target.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   402
// Aspects of a method handle entry:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   403
//  - from_compiled_entry - stub used when compiled code calls the MH
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   404
//  - from_interpreted_entry - stub used when the interpreter calls the MH
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   405
//  - type_checking_entry - stub for runtime casting between MHForm siblings (NYI)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   406
class MethodHandleEntry {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   407
 public:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   408
  class Data {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   409
    friend class MethodHandleEntry;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   410
    size_t              _total_size; // size including Data and code stub
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   411
    MethodHandleEntry*  _type_checking_entry;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   412
    address             _from_interpreted_entry;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   413
    MethodHandleEntry* method_entry() { return (MethodHandleEntry*)(this + 1); }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   414
  };
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   415
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   416
  Data*     data()                              { return (Data*)this - 1; }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   417
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   418
  address   start_address()                     { return (address) data(); }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   419
  address   end_address()                       { return start_address() + data()->_total_size; }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   420
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   421
  address   from_compiled_entry()               { return (address) this; }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   422
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   423
  address   from_interpreted_entry()            { return data()->_from_interpreted_entry; }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   424
  void  set_from_interpreted_entry(address e)   { data()->_from_interpreted_entry = e; }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   425
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   426
  MethodHandleEntry* type_checking_entry()           { return data()->_type_checking_entry; }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   427
  void set_type_checking_entry(MethodHandleEntry* e) { data()->_type_checking_entry = e; }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   428
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   429
  void set_end_address(address end_addr) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   430
    size_t total_size = end_addr - start_address();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   431
    assert(total_size > 0 && total_size < 0x1000, "reasonable end address");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   432
    data()->_total_size = total_size;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   433
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   434
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   435
  // Compiler support:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   436
  static int from_interpreted_entry_offset_in_bytes() {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   437
    return (int)( offset_of(Data, _from_interpreted_entry) - sizeof(Data) );
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   438
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   439
  static int type_checking_entry_offset_in_bytes() {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   440
    return (int)( offset_of(Data, _from_interpreted_entry) - sizeof(Data) );
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   441
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   442
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   443
  static address            start_compiled_entry(MacroAssembler* _masm,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   444
                                                 address interpreted_entry = NULL);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   445
  static MethodHandleEntry* finish_compiled_entry(MacroAssembler* masm, address start_addr);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   446
};
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   447
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   448
address MethodHandles::from_compiled_entry(EntryKind ek) { return entry(ek)->from_compiled_entry(); }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   449
address MethodHandles::from_interpreted_entry(EntryKind ek) { return entry(ek)->from_interpreted_entry(); }