author | twisti |
Mon, 04 Jan 2010 15:52:40 +0100 | |
changeset 4562 | 5d93cb2d2090 |
child 4567 | 7fc02fbe5c7a |
permissions | -rw-r--r-- |
4562
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
1 |
/* |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
2 |
* Copyright 2008-2010 Sun Microsystems, Inc. All Rights Reserved. |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
4 |
* |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
5 |
* This code is free software; you can redistribute it and/or modify it |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
7 |
* published by the Free Software Foundation. |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
8 |
* |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
9 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
10 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
11 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
12 |
* version 2 for more details (a copy is included in the LICENSE file that |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
13 |
* accompanied this code). |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
14 |
* |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
15 |
* You should have received a copy of the GNU General Public License version |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
16 |
* 2 along with this work; if not, write to the Free Software Foundation, |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
17 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
18 |
* |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
19 |
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
20 |
* CA 95054 USA or visit www.sun.com if you need additional information or |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
21 |
* have any questions. |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
22 |
* |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
23 |
*/ |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
24 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
25 |
/* |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
26 |
* JSR 292 reference implementation: method handle structure analysis |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
27 |
*/ |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
28 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
29 |
#include "incls/_precompiled.incl" |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
30 |
#include "incls/_methodHandleWalk.cpp.incl" |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
31 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
32 |
void MethodHandleChain::set_method_handle(Handle mh, TRAPS) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
33 |
if (!java_dyn_MethodHandle::is_instance(mh())) lose("bad method handle", CHECK); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
34 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
35 |
// set current method handle and unpack partially |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
36 |
_method_handle = mh; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
37 |
_is_last = false; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
38 |
_is_bound = false; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
39 |
_arg_slot = -1; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
40 |
_arg_type = T_VOID; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
41 |
_conversion = -1; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
42 |
_last_invoke = Bytecodes::_nop; //arbitrary non-garbage |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
43 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
44 |
if (sun_dyn_DirectMethodHandle::is_instance(mh())) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
45 |
set_last_method(mh(), THREAD); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
46 |
return; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
47 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
48 |
if (sun_dyn_AdapterMethodHandle::is_instance(mh())) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
49 |
_conversion = AdapterMethodHandle_conversion(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
50 |
assert(_conversion != -1, "bad conv value"); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
51 |
assert(sun_dyn_BoundMethodHandle::is_instance(mh()), "also BMH"); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
52 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
53 |
if (sun_dyn_BoundMethodHandle::is_instance(mh())) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
54 |
if (!is_adapter()) // keep AMH and BMH separate in this model |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
55 |
_is_bound = true; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
56 |
_arg_slot = BoundMethodHandle_vmargslot(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
57 |
oop target = MethodHandle_vmtarget_oop(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
58 |
if (!is_bound() || java_dyn_MethodHandle::is_instance(target)) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
59 |
_arg_type = compute_bound_arg_type(target, NULL, _arg_slot, CHECK); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
60 |
} else if (target != NULL && target->is_method()) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
61 |
_arg_type = compute_bound_arg_type(NULL, (methodOop)target, _arg_slot, CHECK); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
62 |
set_last_method(mh(), CHECK); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
63 |
} else { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
64 |
_is_bound = false; // lose! |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
65 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
66 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
67 |
if (is_bound() && _arg_type == T_VOID) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
68 |
lose("bad vmargslot", CHECK); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
69 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
70 |
if (!is_bound() && !is_adapter()) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
71 |
lose("unrecognized MH type", CHECK); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
72 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
73 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
74 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
75 |
void MethodHandleChain::set_last_method(oop target, TRAPS) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
76 |
_is_last = true; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
77 |
klassOop receiver_limit_oop = NULL; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
78 |
int flags = 0; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
79 |
methodOop m = MethodHandles::decode_method(target, receiver_limit_oop, flags); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
80 |
_last_method = methodHandle(THREAD, m); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
81 |
if ((flags & MethodHandles::_dmf_has_receiver) == 0) |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
82 |
_last_invoke = Bytecodes::_invokestatic; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
83 |
else if ((flags & MethodHandles::_dmf_does_dispatch) == 0) |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
84 |
_last_invoke = Bytecodes::_invokespecial; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
85 |
else if ((flags & MethodHandles::_dmf_from_interface) != 0) |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
86 |
_last_invoke = Bytecodes::_invokeinterface; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
87 |
else |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
88 |
_last_invoke = Bytecodes::_invokevirtual; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
89 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
90 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
91 |
BasicType MethodHandleChain::compute_bound_arg_type(oop target, methodOop m, int arg_slot, TRAPS) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
92 |
// There is no direct indication of whether the argument is primitive or not. |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
93 |
// It is implied by the _vmentry code, and by the MethodType of the target. |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
94 |
// FIXME: Make it explicit MethodHandleImpl refactors out from MethodHandle |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
95 |
BasicType arg_type = T_VOID; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
96 |
if (target != NULL) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
97 |
oop mtype = java_dyn_MethodHandle::type(target); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
98 |
int arg_num = MethodHandles::argument_slot_to_argnum(mtype, arg_slot); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
99 |
if (arg_num >= 0) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
100 |
oop ptype = java_dyn_MethodType::ptype(mtype, arg_num); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
101 |
arg_type = java_lang_Class::as_BasicType(ptype); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
102 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
103 |
} else if (m != NULL) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
104 |
// figure out the argument type from the slot |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
105 |
// FIXME: make this explicit in the MH |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
106 |
int cur_slot = m->size_of_parameters(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
107 |
if (arg_slot >= cur_slot) |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
108 |
return T_VOID; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
109 |
if (!m->is_static()) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
110 |
cur_slot -= type2size[T_OBJECT]; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
111 |
if (cur_slot == arg_slot) |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
112 |
return T_OBJECT; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
113 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
114 |
for (SignatureStream ss(m->signature()); !ss.is_done(); ss.next()) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
115 |
BasicType bt = ss.type(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
116 |
cur_slot -= type2size[bt]; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
117 |
if (cur_slot <= arg_slot) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
118 |
if (cur_slot == arg_slot) |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
119 |
arg_type = bt; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
120 |
break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
121 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
122 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
123 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
124 |
if (arg_type == T_ARRAY) |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
125 |
arg_type = T_OBJECT; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
126 |
return arg_type; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
127 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
128 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
129 |
void MethodHandleChain::lose(const char* msg, TRAPS) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
130 |
_lose_message = msg; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
131 |
if (!THREAD->is_Java_thread() || ((JavaThread*)THREAD)->thread_state() != _thread_in_vm) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
132 |
// throw a preallocated exception |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
133 |
THROW_OOP(Universe::virtual_machine_error_instance()); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
134 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
135 |
THROW_MSG(vmSymbols::java_lang_InternalError(), msg); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
136 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
137 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
138 |
Bytecodes::Code MethodHandleWalker::conversion_code(BasicType src, BasicType dest) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
139 |
if (is_subword_type(src)) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
140 |
src = T_INT; // all subword src types act like int |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
141 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
142 |
if (src == dest) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
143 |
return Bytecodes::_nop; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
144 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
145 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
146 |
#define SRC_DEST(s,d) (((int)(s) << 4) + (int)(d)) |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
147 |
switch (SRC_DEST(src, dest)) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
148 |
case SRC_DEST(T_INT, T_LONG): return Bytecodes::_i2l; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
149 |
case SRC_DEST(T_INT, T_FLOAT): return Bytecodes::_i2f; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
150 |
case SRC_DEST(T_INT, T_DOUBLE): return Bytecodes::_i2d; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
151 |
case SRC_DEST(T_INT, T_BYTE): return Bytecodes::_i2b; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
152 |
case SRC_DEST(T_INT, T_CHAR): return Bytecodes::_i2c; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
153 |
case SRC_DEST(T_INT, T_SHORT): return Bytecodes::_i2s; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
154 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
155 |
case SRC_DEST(T_LONG, T_INT): return Bytecodes::_l2i; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
156 |
case SRC_DEST(T_LONG, T_FLOAT): return Bytecodes::_l2f; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
157 |
case SRC_DEST(T_LONG, T_DOUBLE): return Bytecodes::_l2d; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
158 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
159 |
case SRC_DEST(T_FLOAT, T_INT): return Bytecodes::_f2i; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
160 |
case SRC_DEST(T_FLOAT, T_LONG): return Bytecodes::_f2l; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
161 |
case SRC_DEST(T_FLOAT, T_DOUBLE): return Bytecodes::_f2d; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
162 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
163 |
case SRC_DEST(T_DOUBLE, T_INT): return Bytecodes::_d2i; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
164 |
case SRC_DEST(T_DOUBLE, T_LONG): return Bytecodes::_d2l; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
165 |
case SRC_DEST(T_DOUBLE, T_FLOAT): return Bytecodes::_d2f; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
166 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
167 |
#undef SRC_DEST |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
168 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
169 |
// cannot do it in one step, or at all |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
170 |
return Bytecodes::_illegal; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
171 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
172 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
173 |
MethodHandleWalker::ArgToken |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
174 |
MethodHandleWalker::walk(TRAPS) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
175 |
walk_incoming_state(CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
176 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
177 |
for (;;) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
178 |
set_method_handle(chain().method_handle_oop()); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
179 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
180 |
assert(_outgoing_argc == argument_count_slow(), "empty slots under control"); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
181 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
182 |
if (chain().is_adapter()) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
183 |
int conv_op = chain().adapter_conversion_op(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
184 |
int arg_slot = chain().adapter_arg_slot(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
185 |
SlotState* arg_state = slot_state(arg_slot); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
186 |
if (arg_state == NULL |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
187 |
&& conv_op > sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
188 |
lose("bad argument index", CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
189 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
190 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
191 |
// perform the adapter action |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
192 |
switch (chain().adapter_conversion_op()) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
193 |
case sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY: |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
194 |
case sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW: |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
195 |
// No changes to arguments; pass the bits through. |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
196 |
// The only difference between the two ops is that the "only" version |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
197 |
// is fully compatible with the verifier, while the "raw" version |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
198 |
// performs a few extra bitwise conversions (like long <-> double). |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
199 |
break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
200 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
201 |
case sun_dyn_AdapterMethodHandle::OP_CHECK_CAST: { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
202 |
// checkcast the Nth outgoing argument in place |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
203 |
klassOop dest_klass = NULL; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
204 |
BasicType dest = java_lang_Class::as_BasicType(chain().adapter_arg_oop(), &dest_klass); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
205 |
assert(dest == T_OBJECT, ""); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
206 |
assert(dest == arg_state->_type, ""); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
207 |
arg_state->_arg = make_conversion(T_OBJECT, dest_klass, Bytecodes::_checkcast, arg_state->_arg, CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
208 |
debug_only(dest_klass = (klassOop)badOop); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
209 |
break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
210 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
211 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
212 |
case sun_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM: { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
213 |
// i2l, etc., on the Nth outgoing argument in place |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
214 |
BasicType src = chain().adapter_conversion_src_type(), |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
215 |
dest = chain().adapter_conversion_dest_type(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
216 |
Bytecodes::Code bc = conversion_code(src, dest); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
217 |
ArgToken arg = arg_state->_arg; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
218 |
if (bc == Bytecodes::_nop) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
219 |
break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
220 |
} else if (bc != Bytecodes::_illegal) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
221 |
arg = make_conversion(dest, NULL, bc, arg, CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
222 |
} else if (is_subword_type(dest)) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
223 |
bc = conversion_code(src, T_INT); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
224 |
if (bc != Bytecodes::_illegal) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
225 |
arg = make_conversion(dest, NULL, bc, arg, CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
226 |
bc = conversion_code(T_INT, dest); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
227 |
arg = make_conversion(dest, NULL, bc, arg, CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
228 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
229 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
230 |
if (bc == Bytecodes::_illegal) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
231 |
lose("bad primitive conversion", CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
232 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
233 |
change_argument(src, arg_slot, dest, arg); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
234 |
break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
235 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
236 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
237 |
case sun_dyn_AdapterMethodHandle::OP_REF_TO_PRIM: { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
238 |
// checkcast to wrapper type & call intValue, etc. |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
239 |
BasicType dest = chain().adapter_conversion_dest_type(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
240 |
ArgToken arg = arg_state->_arg; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
241 |
arg = make_conversion(T_OBJECT, SystemDictionary::box_klass(dest), |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
242 |
Bytecodes::_checkcast, arg, CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
243 |
vmIntrinsics::ID unboxer = vmIntrinsics::for_unboxing(dest); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
244 |
if (unboxer == vmIntrinsics::_none) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
245 |
lose("no unboxing method", CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
246 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
247 |
ArgToken arglist[2]; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
248 |
arglist[0] = arg; // outgoing 'this' |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
249 |
arglist[1] = NULL; // sentinel |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
250 |
arg = make_invoke(NULL, unboxer, Bytecodes::_invokevirtual, false, 1, &arglist[0], CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
251 |
change_argument(T_OBJECT, arg_slot, dest, arg); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
252 |
break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
253 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
254 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
255 |
case sun_dyn_AdapterMethodHandle::OP_PRIM_TO_REF: { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
256 |
// call wrapper type.valueOf |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
257 |
BasicType src = chain().adapter_conversion_src_type(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
258 |
ArgToken arg = arg_state->_arg; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
259 |
vmIntrinsics::ID boxer = vmIntrinsics::for_boxing(src); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
260 |
if (boxer == vmIntrinsics::_none) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
261 |
lose("no boxing method", CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
262 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
263 |
ArgToken arglist[2]; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
264 |
arglist[0] = arg; // outgoing value |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
265 |
arglist[1] = NULL; // sentinel |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
266 |
arg = make_invoke(NULL, boxer, Bytecodes::_invokevirtual, false, 1, &arglist[0], CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
267 |
change_argument(src, arg_slot, T_OBJECT, arg); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
268 |
break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
269 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
270 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
271 |
case sun_dyn_AdapterMethodHandle::OP_SWAP_ARGS: { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
272 |
int dest_arg_slot = chain().adapter_conversion_vminfo(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
273 |
if (!slot_has_argument(dest_arg_slot)) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
274 |
lose("bad swap index", CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
275 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
276 |
// a simple swap between two arguments |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
277 |
SlotState* dest_arg_state = slot_state(dest_arg_slot); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
278 |
SlotState temp = (*dest_arg_state); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
279 |
(*dest_arg_state) = (*arg_state); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
280 |
(*arg_state) = temp; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
281 |
break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
282 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
283 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
284 |
case sun_dyn_AdapterMethodHandle::OP_ROT_ARGS: { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
285 |
int dest_arg_slot = chain().adapter_conversion_vminfo(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
286 |
if (!slot_has_argument(dest_arg_slot) || arg_slot == dest_arg_slot) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
287 |
lose("bad rotate index", CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
288 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
289 |
SlotState* dest_arg_state = slot_state(dest_arg_slot); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
290 |
// Rotate the source argument (plus following N slots) into the |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
291 |
// position occupied by the dest argument (plus following N slots). |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
292 |
int rotate_count = type2size[dest_arg_state->_type]; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
293 |
// (no other rotate counts are currently supported) |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
294 |
if (arg_slot < dest_arg_slot) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
295 |
for (int i = 0; i < rotate_count; i++) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
296 |
SlotState temp = _outgoing.at(arg_slot); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
297 |
_outgoing.remove_at(arg_slot); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
298 |
_outgoing.insert_before(dest_arg_slot + rotate_count - 1, temp); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
299 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
300 |
} else { // arg_slot > dest_arg_slot |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
301 |
for (int i = 0; i < rotate_count; i++) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
302 |
SlotState temp = _outgoing.at(arg_slot + rotate_count - 1); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
303 |
_outgoing.remove_at(arg_slot + rotate_count - 1); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
304 |
_outgoing.insert_before(dest_arg_slot, temp); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
305 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
306 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
307 |
break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
308 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
309 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
310 |
case sun_dyn_AdapterMethodHandle::OP_DUP_ARGS: { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
311 |
int dup_slots = chain().adapter_conversion_stack_pushes(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
312 |
if (dup_slots <= 0) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
313 |
lose("bad dup count", CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
314 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
315 |
for (int i = 0; i < dup_slots; i++) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
316 |
SlotState* dup = slot_state(arg_slot + 2*i); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
317 |
if (dup == NULL) break; // safety net |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
318 |
if (dup->_type != T_VOID) _outgoing_argc += 1; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
319 |
_outgoing.insert_before(i, (*dup)); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
320 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
321 |
break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
322 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
323 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
324 |
case sun_dyn_AdapterMethodHandle::OP_DROP_ARGS: { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
325 |
int drop_slots = -chain().adapter_conversion_stack_pushes(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
326 |
if (drop_slots <= 0) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
327 |
lose("bad drop count", CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
328 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
329 |
for (int i = 0; i < drop_slots; i++) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
330 |
SlotState* drop = slot_state(arg_slot); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
331 |
if (drop == NULL) break; // safety net |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
332 |
if (drop->_type != T_VOID) _outgoing_argc -= 1; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
333 |
_outgoing.remove_at(arg_slot); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
334 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
335 |
break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
336 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
337 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
338 |
case sun_dyn_AdapterMethodHandle::OP_COLLECT_ARGS: { //NYI, may GC |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
339 |
lose("unimplemented", CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
340 |
break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
341 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
342 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
343 |
case sun_dyn_AdapterMethodHandle::OP_SPREAD_ARGS: { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
344 |
klassOop array_klass_oop = NULL; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
345 |
BasicType array_type = java_lang_Class::as_BasicType(chain().adapter_arg_oop(), |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
346 |
&array_klass_oop); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
347 |
assert(array_type == T_OBJECT, ""); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
348 |
assert(Klass::cast(array_klass_oop)->oop_is_array(), ""); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
349 |
arrayKlassHandle array_klass(THREAD, array_klass_oop); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
350 |
debug_only(array_klass_oop = (klassOop)badOop); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
351 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
352 |
klassOop element_klass_oop = NULL; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
353 |
BasicType element_type = java_lang_Class::as_BasicType(array_klass->component_mirror(), |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
354 |
&element_klass_oop); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
355 |
KlassHandle element_klass(THREAD, element_klass_oop); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
356 |
debug_only(element_klass_oop = (klassOop)badOop); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
357 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
358 |
// Fetch the argument, which we will cast to the required array type. |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
359 |
assert(arg_state->_type == T_OBJECT, ""); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
360 |
ArgToken array_arg = arg_state->_arg; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
361 |
array_arg = make_conversion(T_OBJECT, array_klass(), Bytecodes::_checkcast, array_arg, CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
362 |
change_argument(T_OBJECT, arg_slot, T_VOID, NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
363 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
364 |
// Check the required length. |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
365 |
int spread_slots = 1 + chain().adapter_conversion_stack_pushes(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
366 |
int spread_length = spread_slots; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
367 |
if (type2size[element_type] == 2) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
368 |
if (spread_slots % 2 != 0) spread_slots = -1; // force error |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
369 |
spread_length = spread_slots / 2; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
370 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
371 |
if (spread_slots < 0) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
372 |
lose("bad spread length", CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
373 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
374 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
375 |
jvalue length_jvalue; length_jvalue.i = spread_length; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
376 |
ArgToken length_arg = make_prim_constant(T_INT, &length_jvalue, CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
377 |
// Call a built-in method known to the JVM to validate the length. |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
378 |
ArgToken arglist[3]; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
379 |
arglist[0] = array_arg; // value to check |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
380 |
arglist[1] = length_arg; // length to check |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
381 |
arglist[2] = NULL; // sentinel |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
382 |
make_invoke(NULL, vmIntrinsics::_checkSpreadArgument, |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
383 |
Bytecodes::_invokestatic, false, 3, &arglist[0], CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
384 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
385 |
// Spread out the array elements. |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
386 |
Bytecodes::Code aload_op = Bytecodes::_aaload; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
387 |
if (element_type != T_OBJECT) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
388 |
lose("primitive array NYI", CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
389 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
390 |
int ap = arg_slot; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
391 |
for (int i = 0; i < spread_length; i++) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
392 |
jvalue offset_jvalue; offset_jvalue.i = i; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
393 |
ArgToken offset_arg = make_prim_constant(T_INT, &offset_jvalue, CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
394 |
ArgToken element_arg = make_fetch(element_type, element_klass(), aload_op, array_arg, offset_arg, CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
395 |
change_argument(T_VOID, ap, element_type, element_arg); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
396 |
ap += type2size[element_type]; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
397 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
398 |
break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
399 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
400 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
401 |
case sun_dyn_AdapterMethodHandle::OP_FLYBY: //NYI, runs Java code |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
402 |
case sun_dyn_AdapterMethodHandle::OP_RICOCHET: //NYI, runs Java code |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
403 |
lose("unimplemented", CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
404 |
break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
405 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
406 |
default: |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
407 |
lose("bad adapter conversion", CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
408 |
break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
409 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
410 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
411 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
412 |
if (chain().is_bound()) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
413 |
// push a new argument |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
414 |
BasicType arg_type = chain().bound_arg_type(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
415 |
jint arg_slot = chain().bound_arg_slot(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
416 |
oop arg_oop = chain().bound_arg_oop(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
417 |
ArgToken arg = NULL; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
418 |
if (arg_type == T_OBJECT) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
419 |
arg = make_oop_constant(arg_oop, CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
420 |
} else { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
421 |
jvalue arg_value; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
422 |
BasicType bt = java_lang_boxing_object::get_value(arg_oop, &arg_value); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
423 |
if (bt == arg_type) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
424 |
arg = make_prim_constant(arg_type, &arg_value, CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
425 |
} else { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
426 |
lose("bad bound value", CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
427 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
428 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
429 |
debug_only(arg_oop = badOop); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
430 |
change_argument(T_VOID, arg_slot, arg_type, arg); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
431 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
432 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
433 |
// this test must come after the body of the loop |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
434 |
if (!chain().is_last()) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
435 |
chain().next(CHECK_NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
436 |
} else { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
437 |
break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
438 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
439 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
440 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
441 |
// finish the sequence with a tail-call to the ultimate target |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
442 |
// parameters are passed in logical order (recv 1st), not slot order |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
443 |
ArgToken* arglist = NEW_RESOURCE_ARRAY(ArgToken, _outgoing.length() + 1); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
444 |
int ap = 0; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
445 |
for (int i = _outgoing.length() - 1; i >= 0; i--) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
446 |
SlotState* arg_state = slot_state(i); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
447 |
if (arg_state->_type == T_VOID) continue; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
448 |
arglist[ap++] = _outgoing.at(i)._arg; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
449 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
450 |
assert(ap == _outgoing_argc, ""); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
451 |
arglist[ap] = NULL; // add a sentinel, for the sake of asserts |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
452 |
return make_invoke(chain().last_method_oop(), |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
453 |
vmIntrinsics::_none, |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
454 |
chain().last_invoke_code(), true, |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
455 |
ap, arglist, THREAD); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
456 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
457 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
458 |
void MethodHandleWalker::walk_incoming_state(TRAPS) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
459 |
Handle mtype(THREAD, chain().method_type_oop()); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
460 |
int nptypes = java_dyn_MethodType::ptype_count(mtype()); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
461 |
_outgoing_argc = nptypes; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
462 |
int argp = nptypes - 1; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
463 |
if (argp >= 0) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
464 |
_outgoing.at_grow(argp, make_state(T_VOID, NULL)); // presize |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
465 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
466 |
for (int i = 0; i < nptypes; i++) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
467 |
klassOop arg_type_klass = NULL; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
468 |
BasicType arg_type = java_lang_Class::as_BasicType( |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
469 |
java_dyn_MethodType::ptype(mtype(), i), &arg_type_klass); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
470 |
ArgToken arg = make_parameter(arg_type, arg_type_klass, i, CHECK); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
471 |
debug_only(arg_type_klass = (klassOop)NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
472 |
_outgoing.at_put(argp, make_state(arg_type, arg)); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
473 |
if (type2size[arg_type] == 2) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
474 |
// add the extra slot, so we can model the JVM stack |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
475 |
_outgoing.insert_before(argp+1, make_state(T_VOID, NULL)); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
476 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
477 |
--argp; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
478 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
479 |
// call make_parameter at the end of the list for the return type |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
480 |
klassOop ret_type_klass = NULL; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
481 |
BasicType ret_type = java_lang_Class::as_BasicType( |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
482 |
java_dyn_MethodType::rtype(mtype()), &ret_type_klass); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
483 |
ArgToken ret = make_parameter(ret_type, ret_type_klass, -1, CHECK); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
484 |
// ignore ret; client can catch it if needed |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
485 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
486 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
487 |
// this is messy because some kinds of arguments are paired with |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
488 |
// companion slots containing an empty value |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
489 |
void MethodHandleWalker::change_argument(BasicType old_type, int slot, BasicType new_type, |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
490 |
MethodHandleWalker::ArgToken new_arg) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
491 |
int old_size = type2size[old_type]; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
492 |
int new_size = type2size[new_type]; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
493 |
if (old_size == new_size) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
494 |
// simple case first |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
495 |
_outgoing.at_put(slot, make_state(new_type, new_arg)); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
496 |
} else if (old_size > new_size) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
497 |
for (int i = old_size-1; i >= new_size; i++) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
498 |
assert((i != 0) == (_outgoing.at(slot + i)._type == T_VOID), ""); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
499 |
_outgoing.remove_at(slot + i); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
500 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
501 |
if (new_size > 0) |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
502 |
_outgoing.at_put(slot, make_state(new_type, new_arg)); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
503 |
else |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
504 |
_outgoing_argc -= 1; // deleted a real argument |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
505 |
} else { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
506 |
for (int i = old_size; i < new_size; i++) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
507 |
_outgoing.insert_before(slot+i, make_state(T_VOID, NULL)); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
508 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
509 |
_outgoing.at_put(slot, make_state(new_type, new_arg)); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
510 |
if (old_size == 0) |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
511 |
_outgoing_argc += 1; // inserted a real argument |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
512 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
513 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
514 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
515 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
516 |
#ifdef ASSERT |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
517 |
int MethodHandleWalker::argument_count_slow() { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
518 |
int args_seen = 0; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
519 |
for (int i = _outgoing.length() - 1; i >= 0; i--) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
520 |
if (_outgoing.at(i)._type != T_VOID) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
521 |
++args_seen; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
522 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
523 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
524 |
return args_seen; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
525 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
526 |
#endif |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
527 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
528 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
529 |
void MethodHandleCompiler::compile(TRAPS) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
530 |
assert(_thread == THREAD, "must be same thread"); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
531 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
532 |
_constant_oops.append(Handle()); // element zero is always the null constant |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
533 |
_constant_prims.append(NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
534 |
{ |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
535 |
symbolOop sig |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
536 |
= java_dyn_MethodType::as_signature(chain().method_type_oop(), true, CHECK); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
537 |
_signature_index = find_oop_constant(sig); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
538 |
assert(signature() == sig, ""); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
539 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
540 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
541 |
walk(CHECK); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
542 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
543 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
544 |
MethodHandleWalker::ArgToken |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
545 |
MethodHandleCompiler::make_conversion(BasicType type, klassOop tk, Bytecodes::Code op, |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
546 |
MethodHandleWalker::ArgToken src, TRAPS) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
547 |
Unimplemented(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
548 |
return NULL; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
549 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
550 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
551 |
MethodHandleWalker::ArgToken |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
552 |
MethodHandleCompiler::make_invoke(methodOop m, vmIntrinsics::ID iid, |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
553 |
Bytecodes::Code op, bool tailcall, |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
554 |
int argc, MethodHandleWalker::ArgToken* argv, |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
555 |
TRAPS) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
556 |
// If tailcall, we have walked all the way to a direct method handle. |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
557 |
// Otherwise, make a recursive call to some helper routine. |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
558 |
#ifdef ASSERT |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
559 |
switch (op) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
560 |
case Bytecodes::_invokevirtual: |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
561 |
case Bytecodes::_invokespecial: |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
562 |
case Bytecodes::_invokestatic: |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
563 |
case Bytecodes::_invokeinterface: |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
564 |
break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
565 |
default: |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
566 |
ShouldNotReachHere(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
567 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
568 |
#endif //ASSERT |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
569 |
_bytes.put((char) op); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
570 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
571 |
Unimplemented(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
572 |
return NULL; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
573 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
574 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
575 |
MethodHandleWalker::ArgToken |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
576 |
MethodHandleCompiler::make_fetch(BasicType type, klassOop tk, Bytecodes::Code op, |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
577 |
MethodHandleWalker::ArgToken base, |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
578 |
MethodHandleWalker::ArgToken offset, |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
579 |
TRAPS) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
580 |
Unimplemented(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
581 |
return NULL; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
582 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
583 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
584 |
int MethodHandleCompiler::find_oop_constant(oop con) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
585 |
if (con == NULL) return 0; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
586 |
for (int i = 1, imax = _constant_oops.length(); i < imax; i++) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
587 |
if (_constant_oops.at(i) == con) |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
588 |
return i; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
589 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
590 |
_constant_prims.append(NULL); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
591 |
return _constant_oops.append(con); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
592 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
593 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
594 |
int MethodHandleCompiler::find_prim_constant(BasicType bt, jvalue* con) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
595 |
jvalue con_copy; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
596 |
assert(bt < T_OBJECT, ""); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
597 |
if (type2aelembytes(bt) < jintSize) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
598 |
// widen to int |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
599 |
con_copy = (*con); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
600 |
con = &con_copy; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
601 |
switch (bt) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
602 |
case T_BOOLEAN: con->i = (con->z ? 1 : 0); break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
603 |
case T_BYTE: con->i = con->b; break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
604 |
case T_CHAR: con->i = con->c; break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
605 |
case T_SHORT: con->i = con->s; break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
606 |
default: ShouldNotReachHere(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
607 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
608 |
bt = T_INT; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
609 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
610 |
for (int i = 1, imax = _constant_prims.length(); i < imax; i++) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
611 |
PrimCon* pcon = _constant_prims.at(i); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
612 |
if (pcon != NULL && pcon->_type == bt) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
613 |
bool match = false; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
614 |
switch (type2size[bt]) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
615 |
case 1: if (pcon->_value.i == con->i) match = true; break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
616 |
case 2: if (pcon->_value.j == con->j) match = true; break; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
617 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
618 |
if (match) |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
619 |
return i; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
620 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
621 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
622 |
PrimCon* pcon = new PrimCon(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
623 |
pcon->_type = bt; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
624 |
pcon->_value = (*con); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
625 |
_constant_oops.append(Handle()); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
626 |
return _constant_prims.append(pcon); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
627 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
628 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
629 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
630 |
#ifndef PRODUCT |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
631 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
632 |
// MH printer for debugging. |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
633 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
634 |
class MethodHandlePrinter : public MethodHandleWalker { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
635 |
private: |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
636 |
outputStream* _out; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
637 |
bool _verbose; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
638 |
int _temp_num; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
639 |
stringStream _strbuf; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
640 |
const char* strbuf() { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
641 |
const char* s = _strbuf.as_string(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
642 |
_strbuf.reset(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
643 |
return s; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
644 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
645 |
ArgToken token(const char* str) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
646 |
return (ArgToken) str; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
647 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
648 |
void start_params() { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
649 |
_out->print("("); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
650 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
651 |
void end_params() { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
652 |
if (_verbose) _out->print("\n"); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
653 |
_out->print(") => {"); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
654 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
655 |
void put_type_name(BasicType type, klassOop tk, outputStream* s) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
656 |
const char* kname = NULL; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
657 |
if (tk != NULL) |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
658 |
kname = Klass::cast(tk)->external_name(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
659 |
s->print("%s", (kname != NULL) ? kname : type2name(type)); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
660 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
661 |
ArgToken maybe_make_temp(const char* statement_op, BasicType type, const char* temp_name) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
662 |
const char* value = strbuf(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
663 |
if (!_verbose) return token(value); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
664 |
// make an explicit binding for each separate value |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
665 |
_strbuf.print("%s%d", temp_name, ++_temp_num); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
666 |
const char* temp = strbuf(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
667 |
_out->print("\n %s %s %s = %s;", statement_op, type2name(type), temp, value); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
668 |
return token(temp); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
669 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
670 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
671 |
public: |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
672 |
MethodHandlePrinter(Handle root, bool verbose, outputStream* out, TRAPS) |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
673 |
: MethodHandleWalker(root, THREAD), |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
674 |
_out(out), |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
675 |
_verbose(verbose), |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
676 |
_temp_num(0) |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
677 |
{ |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
678 |
start_params(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
679 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
680 |
virtual ArgToken make_parameter(BasicType type, klassOop tk, int argnum, TRAPS) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
681 |
if (argnum < 0) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
682 |
end_params(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
683 |
return NULL; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
684 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
685 |
if (argnum == 0) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
686 |
_out->print(_verbose ? "\n " : ""); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
687 |
} else { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
688 |
_out->print(_verbose ? ",\n " : ", "); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
689 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
690 |
if (argnum >= _temp_num) |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
691 |
_temp_num = argnum; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
692 |
// generate an argument name |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
693 |
_strbuf.print("a%d", argnum); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
694 |
const char* arg = strbuf(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
695 |
put_type_name(type, tk, _out); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
696 |
_out->print(" %s", arg); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
697 |
return token(arg); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
698 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
699 |
virtual ArgToken make_oop_constant(oop con, TRAPS) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
700 |
if (con == NULL) |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
701 |
_strbuf.print("null"); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
702 |
else |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
703 |
con->print_value_on(&_strbuf); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
704 |
if (_strbuf.size() == 0) { // yuck |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
705 |
_strbuf.print("(a "); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
706 |
put_type_name(T_OBJECT, con->klass(), &_strbuf); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
707 |
_strbuf.print(")"); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
708 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
709 |
return maybe_make_temp("constant", T_OBJECT, "k"); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
710 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
711 |
virtual ArgToken make_prim_constant(BasicType type, jvalue* con, TRAPS) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
712 |
java_lang_boxing_object::print(type, con, &_strbuf); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
713 |
return maybe_make_temp("constant", type, "k"); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
714 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
715 |
virtual ArgToken make_conversion(BasicType type, klassOop tk, Bytecodes::Code op, ArgToken src, TRAPS) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
716 |
_strbuf.print("%s(%s", Bytecodes::name(op), (const char*)src); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
717 |
if (tk != NULL) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
718 |
_strbuf.print(", "); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
719 |
put_type_name(type, tk, &_strbuf); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
720 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
721 |
_strbuf.print(")"); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
722 |
return maybe_make_temp("convert", type, "v"); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
723 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
724 |
virtual ArgToken make_fetch(BasicType type, klassOop tk, Bytecodes::Code op, ArgToken base, ArgToken offset, TRAPS) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
725 |
_strbuf.print("%s(%s, %s", Bytecodes::name(op), (const char*)base, (const char*)offset); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
726 |
if (tk != NULL) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
727 |
_strbuf.print(", "); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
728 |
put_type_name(type, tk, &_strbuf); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
729 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
730 |
_strbuf.print(")"); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
731 |
return maybe_make_temp("fetch", type, "x"); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
732 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
733 |
virtual ArgToken make_invoke(methodOop m, vmIntrinsics::ID iid, |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
734 |
Bytecodes::Code op, bool tailcall, |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
735 |
int argc, ArgToken* argv, TRAPS) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
736 |
symbolOop name, sig; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
737 |
if (m != NULL) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
738 |
name = m->name(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
739 |
sig = m->signature(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
740 |
} else { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
741 |
name = vmSymbols::symbol_at(vmIntrinsics::name_for(iid)); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
742 |
sig = vmSymbols::symbol_at(vmIntrinsics::signature_for(iid)); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
743 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
744 |
_strbuf.print("%s %s%s(", Bytecodes::name(op), name->as_C_string(), sig->as_C_string()); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
745 |
for (int i = 0; i < argc; i++) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
746 |
_strbuf.print("%s%s", (i > 0 ? ", " : ""), (const char*)argv[i]); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
747 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
748 |
_strbuf.print(")"); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
749 |
if (!tailcall) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
750 |
BasicType rt = char2type(sig->byte_at(sig->utf8_length()-1)); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
751 |
if (rt == T_ILLEGAL) rt = T_OBJECT; // ';' at the end of '(...)L...;' |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
752 |
return maybe_make_temp("invoke", rt, "x"); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
753 |
} else { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
754 |
const char* ret = strbuf(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
755 |
_out->print(_verbose ? "\n return " : " "); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
756 |
_out->print("%s", ret); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
757 |
_out->print(_verbose ? "\n}\n" : " }"); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
758 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
759 |
return ArgToken(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
760 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
761 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
762 |
virtual void set_method_handle(oop mh) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
763 |
if (WizardMode && Verbose) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
764 |
tty->print("\n--- next target: "); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
765 |
mh->print(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
766 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
767 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
768 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
769 |
static void print(Handle root, bool verbose, outputStream* out, TRAPS) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
770 |
ResourceMark rm; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
771 |
MethodHandlePrinter printer(root, verbose, out, CHECK); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
772 |
printer.walk(CHECK); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
773 |
out->print("\n"); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
774 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
775 |
static void print(Handle root, bool verbose = Verbose, outputStream* out = tty) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
776 |
EXCEPTION_MARK; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
777 |
ResourceMark rm; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
778 |
MethodHandlePrinter printer(root, verbose, out, THREAD); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
779 |
if (!HAS_PENDING_EXCEPTION) |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
780 |
printer.walk(THREAD); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
781 |
if (HAS_PENDING_EXCEPTION) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
782 |
oop ex = PENDING_EXCEPTION; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
783 |
CLEAR_PENDING_EXCEPTION; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
784 |
out->print("\n*** "); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
785 |
if (ex != Universe::virtual_machine_error_instance()) |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
786 |
ex->print_on(out); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
787 |
else |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
788 |
out->print("lose: %s", printer.lose_message()); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
789 |
out->print("\n}\n"); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
790 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
791 |
out->print("\n"); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
792 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
793 |
}; |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
794 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
795 |
extern "C" |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
796 |
void print_method_handle(oop mh) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
797 |
if (java_dyn_MethodHandle::is_instance(mh)) { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
798 |
MethodHandlePrinter::print(mh); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
799 |
} else { |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
800 |
tty->print("*** not a method handle: "); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
801 |
mh->print(); |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
802 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
803 |
} |
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
804 |
|
5d93cb2d2090
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff
changeset
|
805 |
#endif // PRODUCT |