Mercurial > hg > graal-compiler
annotate src/share/vm/prims/methodHandles.cpp @ 3992:d1bdeef3e3e2
7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76
Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing.
Reviewed-by: tonyp, brutisso, ysr
author | johnc |
---|---|
date | Wed, 12 Oct 2011 10:25:51 -0700 |
parents | e6b1331a51d2 |
children | 12d38ffcba2a |
rev | line source |
---|---|
710 | 1 /* |
2116
d810e9a3fc33
7010180: JSR 292 InvokeDynamicPrintArgs fails with: assert(_adapter == NULL) failed: init'd to NULL
twisti
parents:
2088
diff
changeset
|
2 * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. |
710 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1508
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1508
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1508
diff
changeset
|
21 * questions. |
710 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/symbolTable.hpp" | |
3785
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
27 #include "compiler/compileBroker.hpp" |
1972 | 28 #include "interpreter/interpreter.hpp" |
3388
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
29 #include "interpreter/oopMapCache.hpp" |
1972 | 30 #include "memory/allocation.inline.hpp" |
31 #include "memory/oopFactory.hpp" | |
32 #include "prims/methodHandles.hpp" | |
3388
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
33 #include "prims/methodHandleWalk.hpp" |
3785
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
34 #include "runtime/compilationPolicy.hpp" |
1972 | 35 #include "runtime/javaCalls.hpp" |
36 #include "runtime/reflection.hpp" | |
37 #include "runtime/signature.hpp" | |
38 #include "runtime/stubRoutines.hpp" | |
39 | |
710 | 40 /* |
41 * JSR 292 reference implementation: method handles | |
42 */ | |
43 | |
44 bool MethodHandles::_enabled = false; // set true after successful native linkage | |
45 | |
46 MethodHandleEntry* MethodHandles::_entries[MethodHandles::_EK_LIMIT] = {NULL}; | |
47 const char* MethodHandles::_entry_names[_EK_LIMIT+1] = { | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
48 "raise_exception", |
710 | 49 "invokestatic", // how a MH emulates invokestatic |
50 "invokespecial", // ditto for the other invokes... | |
51 "invokevirtual", | |
52 "invokeinterface", | |
53 "bound_ref", // these are for BMH... | |
54 "bound_int", | |
55 "bound_long", | |
56 "bound_ref_direct", // (direct versions have a direct methodOop) | |
57 "bound_int_direct", | |
58 "bound_long_direct", | |
59 | |
60 // starting at _adapter_mh_first: | |
61 "adapter_retype_only", // these are for AMH... | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
62 "adapter_retype_raw", |
710 | 63 "adapter_check_cast", |
64 "adapter_prim_to_prim", | |
65 "adapter_ref_to_prim", | |
66 "adapter_prim_to_ref", | |
67 "adapter_swap_args", | |
68 "adapter_rot_args", | |
69 "adapter_dup_args", | |
70 "adapter_drop_args", | |
71 "adapter_collect_args", | |
72 "adapter_spread_args", | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
73 "adapter_fold_args", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
74 "adapter_unused_13", |
710 | 75 |
76 // optimized adapter types: | |
77 "adapter_swap_args/1", | |
78 "adapter_swap_args/2", | |
79 "adapter_rot_args/1,up", | |
80 "adapter_rot_args/1,down", | |
81 "adapter_rot_args/2,up", | |
82 "adapter_rot_args/2,down", | |
83 "adapter_prim_to_prim/i2i", | |
84 "adapter_prim_to_prim/l2i", | |
85 "adapter_prim_to_prim/d2f", | |
86 "adapter_prim_to_prim/i2l", | |
87 "adapter_prim_to_prim/f2d", | |
88 "adapter_ref_to_prim/unboxi", | |
89 "adapter_ref_to_prim/unboxl", | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
90 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
91 // return value handlers for collect/filter/fold adapters: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
92 "return/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
93 "return/int", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
94 "return/long", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
95 "return/float", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
96 "return/double", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
97 "return/void", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
98 "return/S0/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
99 "return/S1/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
100 "return/S2/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
101 "return/S3/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
102 "return/S4/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
103 "return/S5/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
104 "return/any", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
105 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
106 // spreading (array length cases 0, 1, ...) |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
107 "adapter_spread/0", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
108 "adapter_spread/1/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
109 "adapter_spread/2/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
110 "adapter_spread/3/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
111 "adapter_spread/4/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
112 "adapter_spread/5/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
113 "adapter_spread/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
114 "adapter_spread/byte", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
115 "adapter_spread/char", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
116 "adapter_spread/short", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
117 "adapter_spread/int", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
118 "adapter_spread/long", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
119 "adapter_spread/float", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
120 "adapter_spread/double", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
121 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
122 // blocking filter/collect conversions: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
123 "adapter_collect/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
124 "adapter_collect/int", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
125 "adapter_collect/long", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
126 "adapter_collect/float", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
127 "adapter_collect/double", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
128 "adapter_collect/void", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
129 "adapter_collect/0/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
130 "adapter_collect/1/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
131 "adapter_collect/2/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
132 "adapter_collect/3/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
133 "adapter_collect/4/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
134 "adapter_collect/5/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
135 "adapter_filter/S0/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
136 "adapter_filter/S1/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
137 "adapter_filter/S2/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
138 "adapter_filter/S3/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
139 "adapter_filter/S4/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
140 "adapter_filter/S5/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
141 "adapter_collect/2/S0/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
142 "adapter_collect/2/S1/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
143 "adapter_collect/2/S2/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
144 "adapter_collect/2/S3/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
145 "adapter_collect/2/S4/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
146 "adapter_collect/2/S5/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
147 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
148 // blocking fold conversions: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
149 "adapter_fold/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
150 "adapter_fold/int", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
151 "adapter_fold/long", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
152 "adapter_fold/float", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
153 "adapter_fold/double", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
154 "adapter_fold/void", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
155 "adapter_fold/1/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
156 "adapter_fold/2/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
157 "adapter_fold/3/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
158 "adapter_fold/4/ref", |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
159 "adapter_fold/5/ref", |
710 | 160 |
3905
c26de9aef2ed
7071307: MethodHandle bimorphic inlining should consider the frequency
never
parents:
3837
diff
changeset
|
161 "adapter_opt_profiling", |
c26de9aef2ed
7071307: MethodHandle bimorphic inlining should consider the frequency
never
parents:
3837
diff
changeset
|
162 |
710 | 163 NULL |
164 }; | |
165 | |
1299
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
166 // Adapters. |
3753
cba7b5c2d53f
7045514: SPARC assembly code for JSR 292 ricochet frames
never
parents:
3744
diff
changeset
|
167 MethodHandlesAdapterBlob* MethodHandles::_adapter_code = NULL; |
1299
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
168 |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
169 jobject MethodHandles::_raise_exception_method; |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
170 |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
171 address MethodHandles::_adapter_return_handlers[CONV_TYPE_MASK+1]; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
172 |
710 | 173 #ifdef ASSERT |
174 bool MethodHandles::spot_check_entry_names() { | |
175 assert(!strcmp(entry_name(_invokestatic_mh), "invokestatic"), ""); | |
176 assert(!strcmp(entry_name(_bound_ref_mh), "bound_ref"), ""); | |
177 assert(!strcmp(entry_name(_adapter_retype_only), "adapter_retype_only"), ""); | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
178 assert(!strcmp(entry_name(_adapter_fold_args), "adapter_fold_args"), ""); |
710 | 179 assert(!strcmp(entry_name(_adapter_opt_unboxi), "adapter_ref_to_prim/unboxi"), ""); |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
180 assert(!strcmp(entry_name(_adapter_opt_spread_char), "adapter_spread/char"), ""); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
181 assert(!strcmp(entry_name(_adapter_opt_spread_double), "adapter_spread/double"), ""); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
182 assert(!strcmp(entry_name(_adapter_opt_collect_int), "adapter_collect/int"), ""); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
183 assert(!strcmp(entry_name(_adapter_opt_collect_0_ref), "adapter_collect/0/ref"), ""); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
184 assert(!strcmp(entry_name(_adapter_opt_collect_2_S3_ref), "adapter_collect/2/S3/ref"), ""); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
185 assert(!strcmp(entry_name(_adapter_opt_filter_S5_ref), "adapter_filter/S5/ref"), ""); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
186 assert(!strcmp(entry_name(_adapter_opt_fold_3_ref), "adapter_fold/3/ref"), ""); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
187 assert(!strcmp(entry_name(_adapter_opt_fold_void), "adapter_fold/void"), ""); |
710 | 188 return true; |
189 } | |
190 #endif | |
191 | |
1299
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
192 |
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
193 //------------------------------------------------------------------------------ |
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
194 // MethodHandles::generate_adapters |
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
195 // |
2116
d810e9a3fc33
7010180: JSR 292 InvokeDynamicPrintArgs fails with: assert(_adapter == NULL) failed: init'd to NULL
twisti
parents:
2088
diff
changeset
|
196 void MethodHandles::generate_adapters() { |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
197 #ifdef TARGET_ARCH_NYI_6939861 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
198 if (FLAG_IS_DEFAULT(UseRicochetFrames)) UseRicochetFrames = false; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
199 #endif |
2416
38fea01eb669
6817525: turn on method handle functionality by default for JSR 292
twisti
parents:
2357
diff
changeset
|
200 if (!EnableInvokeDynamic || SystemDictionary::MethodHandle_klass() == NULL) return; |
1299
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
201 |
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
202 assert(_adapter_code == NULL, "generate only once"); |
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
203 |
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
204 ResourceMark rm; |
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
205 TraceTime timer("MethodHandles adapters generation", TraceStartupTime); |
3753
cba7b5c2d53f
7045514: SPARC assembly code for JSR 292 ricochet frames
never
parents:
3744
diff
changeset
|
206 _adapter_code = MethodHandlesAdapterBlob::create(adapter_code_size); |
1299
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
207 if (_adapter_code == NULL) |
3753
cba7b5c2d53f
7045514: SPARC assembly code for JSR 292 ricochet frames
never
parents:
3744
diff
changeset
|
208 vm_exit_out_of_memory(adapter_code_size, "CodeCache: no room for MethodHandles adapters"); |
1748 | 209 CodeBuffer code(_adapter_code); |
1299
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
210 MethodHandlesAdapterGenerator g(&code); |
2116
d810e9a3fc33
7010180: JSR 292 InvokeDynamicPrintArgs fails with: assert(_adapter == NULL) failed: init'd to NULL
twisti
parents:
2088
diff
changeset
|
211 g.generate(); |
1299
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
212 } |
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
213 |
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
214 //------------------------------------------------------------------------------ |
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
215 // MethodHandlesAdapterGenerator::generate |
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
216 // |
2116
d810e9a3fc33
7010180: JSR 292 InvokeDynamicPrintArgs fails with: assert(_adapter == NULL) failed: init'd to NULL
twisti
parents:
2088
diff
changeset
|
217 void MethodHandlesAdapterGenerator::generate() { |
1299
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
218 // Generate generic method handle adapters. |
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
219 for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST; |
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
220 ek < MethodHandles::_EK_LIMIT; |
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
221 ek = MethodHandles::EntryKind(1 + (int)ek)) { |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
222 if (MethodHandles::ek_supported(ek)) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
223 StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek)); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
224 MethodHandles::generate_method_handle_stub(_masm, ek); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
225 } |
1299
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
226 } |
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
227 } |
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
228 |
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1142
diff
changeset
|
229 |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
230 #ifdef TARGET_ARCH_NYI_6939861 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
231 // these defs belong in methodHandles_<arch>.cpp |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
232 frame MethodHandles::ricochet_frame_sender(const frame& fr, RegisterMap *map) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
233 ShouldNotCallThis(); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
234 return fr; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
235 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
236 void MethodHandles::ricochet_frame_oops_do(const frame& fr, OopClosure* f, const RegisterMap* reg_map) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
237 ShouldNotCallThis(); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
238 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
239 #endif //TARGET_ARCH_NYI_6939861 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
240 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
241 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
242 //------------------------------------------------------------------------------ |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
243 // MethodHandles::ek_supported |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
244 // |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
245 bool MethodHandles::ek_supported(MethodHandles::EntryKind ek) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
246 MethodHandles::EntryKind ek_orig = MethodHandles::ek_original_kind(ek); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
247 switch (ek_orig) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
248 case _adapter_unused_13: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
249 return false; // not defined yet |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
250 case _adapter_prim_to_ref: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
251 return UseRicochetFrames && conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
252 case _adapter_collect_args: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
253 return UseRicochetFrames && conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
254 case _adapter_fold_args: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
255 return UseRicochetFrames && conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
256 case _adapter_opt_return_any: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
257 return UseRicochetFrames; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
258 #ifdef TARGET_ARCH_NYI_6939861 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
259 // ports before 6939861 supported only three kinds of spread ops |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
260 case _adapter_spread_args: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
261 // restrict spreads to three kinds: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
262 switch (ek) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
263 case _adapter_opt_spread_0: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
264 case _adapter_opt_spread_1: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
265 case _adapter_opt_spread_more: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
266 break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
267 default: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
268 return false; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
269 break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
270 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
271 break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
272 #endif //TARGET_ARCH_NYI_6939861 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
273 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
274 return true; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
275 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
276 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
277 |
710 | 278 void MethodHandles::set_enabled(bool z) { |
279 if (_enabled != z) { | |
2416
38fea01eb669
6817525: turn on method handle functionality by default for JSR 292
twisti
parents:
2357
diff
changeset
|
280 guarantee(z && EnableInvokeDynamic, "can only enable once, and only if -XX:+EnableInvokeDynamic"); |
710 | 281 _enabled = z; |
282 } | |
283 } | |
284 | |
285 // Note: A method which does not have a TRAPS argument cannot block in the GC | |
286 // or throw exceptions. Such methods are used in this file to do something quick | |
287 // and local, like parse a data structure. For speed, such methods work on plain | |
288 // oops, not handles. Trapping methods uniformly operate on handles. | |
289 | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
290 methodHandle MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype, |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
291 KlassHandle& receiver_limit_result, int& decode_flags_result) { |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
292 if (vmtarget == NULL) return methodHandle(); |
710 | 293 assert(methodOopDesc::nonvirtual_vtable_index < 0, "encoding"); |
294 if (vmindex < 0) { | |
295 // this DMH performs no dispatch; it is directly bound to a methodOop | |
296 // A MemberName may either be directly bound to a methodOop, | |
297 // or it may use the klass/index form; both forms mean the same thing. | |
298 methodOop m = decode_methodOop(methodOop(vmtarget), decode_flags_result); | |
299 if ((decode_flags_result & _dmf_has_receiver) != 0 | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
300 && java_lang_invoke_MethodType::is_instance(mtype)) { |
710 | 301 // Extract receiver type restriction from mtype.ptypes[0]. |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
302 objArrayOop ptypes = java_lang_invoke_MethodType::ptypes(mtype); |
710 | 303 oop ptype0 = (ptypes == NULL || ptypes->length() < 1) ? oop(NULL) : ptypes->obj_at(0); |
304 if (java_lang_Class::is_instance(ptype0)) | |
305 receiver_limit_result = java_lang_Class::as_klassOop(ptype0); | |
306 } | |
307 if (vmindex == methodOopDesc::nonvirtual_vtable_index) { | |
308 // this DMH can be an "invokespecial" version | |
309 decode_flags_result &= ~_dmf_does_dispatch; | |
310 } else { | |
311 assert(vmindex == methodOopDesc::invalid_vtable_index, "random vmindex?"); | |
312 } | |
313 return m; | |
314 } else { | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
315 assert(vmtarget->is_klass(), "must be class or interface"); |
710 | 316 decode_flags_result |= MethodHandles::_dmf_does_dispatch; |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
317 decode_flags_result |= MethodHandles::_dmf_has_receiver; |
710 | 318 receiver_limit_result = (klassOop)vmtarget; |
319 Klass* tk = Klass::cast((klassOop)vmtarget); | |
320 if (tk->is_interface()) { | |
321 // an itable linkage is <interface, itable index> | |
322 decode_flags_result |= MethodHandles::_dmf_from_interface; | |
323 return klassItable::method_for_itable_index((klassOop)vmtarget, vmindex); | |
324 } else { | |
325 if (!tk->oop_is_instance()) | |
1142 | 326 tk = instanceKlass::cast(SystemDictionary::Object_klass()); |
710 | 327 return ((instanceKlass*)tk)->method_at_vtable(vmindex); |
328 } | |
329 } | |
330 } | |
331 | |
332 // MemberName and DirectMethodHandle have the same linkage to the JVM internals. | |
333 // (MemberName is the non-operational name used for queries and setup.) | |
334 | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
335 methodHandle MethodHandles::decode_DirectMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) { |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
336 oop vmtarget = java_lang_invoke_DirectMethodHandle::vmtarget(mh); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
337 int vmindex = java_lang_invoke_DirectMethodHandle::vmindex(mh); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
338 oop mtype = java_lang_invoke_DirectMethodHandle::type(mh); |
710 | 339 return decode_vmtarget(vmtarget, vmindex, mtype, receiver_limit_result, decode_flags_result); |
340 } | |
341 | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
342 methodHandle MethodHandles::decode_BoundMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) { |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
343 assert(java_lang_invoke_BoundMethodHandle::is_instance(mh), ""); |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
344 assert(mh->klass() != SystemDictionary::AdapterMethodHandle_klass(), ""); |
710 | 345 for (oop bmh = mh;;) { |
346 // Bound MHs can be stacked to bind several arguments. | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
347 oop target = java_lang_invoke_MethodHandle::vmtarget(bmh); |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
348 if (target == NULL) return methodHandle(); |
710 | 349 decode_flags_result |= MethodHandles::_dmf_binds_argument; |
350 klassOop tk = target->klass(); | |
351 if (tk == SystemDictionary::BoundMethodHandle_klass()) { | |
352 bmh = target; | |
353 continue; | |
354 } else { | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
355 if (java_lang_invoke_MethodHandle::is_subclass(tk)) { |
710 | 356 //assert(tk == SystemDictionary::DirectMethodHandle_klass(), "end of BMH chain must be DMH"); |
357 return decode_MethodHandle(target, receiver_limit_result, decode_flags_result); | |
358 } else { | |
359 // Optimized case: binding a receiver to a non-dispatched DMH | |
360 // short-circuits directly to the methodOop. | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
361 // (It might be another argument besides a receiver also.) |
710 | 362 assert(target->is_method(), "must be a simple method"); |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
363 decode_flags_result |= MethodHandles::_dmf_binds_method; |
710 | 364 methodOop m = (methodOop) target; |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
365 if (!m->is_static()) |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
366 decode_flags_result |= MethodHandles::_dmf_has_receiver; |
710 | 367 return m; |
368 } | |
369 } | |
370 } | |
371 } | |
372 | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
373 methodHandle MethodHandles::decode_AdapterMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) { |
710 | 374 assert(mh->klass() == SystemDictionary::AdapterMethodHandle_klass(), ""); |
375 for (oop amh = mh;;) { | |
376 // Adapter MHs can be stacked to convert several arguments. | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
377 int conv_op = adapter_conversion_op(java_lang_invoke_AdapterMethodHandle::conversion(amh)); |
710 | 378 decode_flags_result |= (_dmf_adapter_lsb << conv_op) & _DMF_ADAPTER_MASK; |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
379 oop target = java_lang_invoke_MethodHandle::vmtarget(amh); |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
380 if (target == NULL) return methodHandle(); |
710 | 381 klassOop tk = target->klass(); |
382 if (tk == SystemDictionary::AdapterMethodHandle_klass()) { | |
383 amh = target; | |
384 continue; | |
385 } else { | |
386 // must be a BMH (which will bind some more arguments) or a DMH (for the final call) | |
387 return MethodHandles::decode_MethodHandle(target, receiver_limit_result, decode_flags_result); | |
388 } | |
389 } | |
390 } | |
391 | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
392 methodHandle MethodHandles::decode_MethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) { |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
393 if (mh == NULL) return methodHandle(); |
710 | 394 klassOop mhk = mh->klass(); |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
395 assert(java_lang_invoke_MethodHandle::is_subclass(mhk), "must be a MethodHandle"); |
710 | 396 if (mhk == SystemDictionary::DirectMethodHandle_klass()) { |
397 return decode_DirectMethodHandle(mh, receiver_limit_result, decode_flags_result); | |
398 } else if (mhk == SystemDictionary::BoundMethodHandle_klass()) { | |
399 return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result); | |
400 } else if (mhk == SystemDictionary::AdapterMethodHandle_klass()) { | |
401 return decode_AdapterMethodHandle(mh, receiver_limit_result, decode_flags_result); | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
402 } else if (java_lang_invoke_BoundMethodHandle::is_subclass(mhk)) { |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
403 // could be a JavaMethodHandle (but not an adapter MH) |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
404 return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result); |
710 | 405 } else { |
406 assert(false, "cannot parse this MH"); | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
407 return methodHandle(); // random MH? |
710 | 408 } |
409 } | |
410 | |
411 methodOop MethodHandles::decode_methodOop(methodOop m, int& decode_flags_result) { | |
412 assert(m->is_method(), ""); | |
413 if (m->is_static()) { | |
414 // check that signature begins '(L' or '([' (not '(I', '()', etc.) | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
415 Symbol* sig = m->signature(); |
710 | 416 BasicType recv_bt = char2type(sig->byte_at(1)); |
417 // Note: recv_bt might be T_ILLEGAL if byte_at(2) is ')' | |
418 assert(sig->byte_at(0) == '(', "must be method sig"); | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
419 // if (recv_bt == T_OBJECT || recv_bt == T_ARRAY) |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
420 // decode_flags_result |= _dmf_has_receiver; |
710 | 421 } else { |
422 // non-static method | |
423 decode_flags_result |= _dmf_has_receiver; | |
424 if (!m->can_be_statically_bound() && !m->is_initializer()) { | |
425 decode_flags_result |= _dmf_does_dispatch; | |
426 if (Klass::cast(m->method_holder())->is_interface()) | |
427 decode_flags_result |= _dmf_from_interface; | |
428 } | |
429 } | |
430 return m; | |
431 } | |
432 | |
433 | |
434 // A trusted party is handing us a cookie to determine a method. | |
435 // Let's boil it down to the method oop they really want. | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
436 methodHandle MethodHandles::decode_method(oop x, KlassHandle& receiver_limit_result, int& decode_flags_result) { |
710 | 437 decode_flags_result = 0; |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
438 receiver_limit_result = KlassHandle(); |
710 | 439 klassOop xk = x->klass(); |
440 if (xk == Universe::methodKlassObj()) { | |
441 return decode_methodOop((methodOop) x, decode_flags_result); | |
442 } else if (xk == SystemDictionary::MemberName_klass()) { | |
443 // Note: This only works if the MemberName has already been resolved. | |
444 return decode_MemberName(x, receiver_limit_result, decode_flags_result); | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
445 } else if (java_lang_invoke_MethodHandle::is_subclass(xk)) { |
710 | 446 return decode_MethodHandle(x, receiver_limit_result, decode_flags_result); |
1142 | 447 } else if (xk == SystemDictionary::reflect_Method_klass()) { |
710 | 448 oop clazz = java_lang_reflect_Method::clazz(x); |
449 int slot = java_lang_reflect_Method::slot(x); | |
450 klassOop k = java_lang_Class::as_klassOop(clazz); | |
451 if (k != NULL && Klass::cast(k)->oop_is_instance()) | |
452 return decode_methodOop(instanceKlass::cast(k)->method_with_idnum(slot), | |
453 decode_flags_result); | |
1142 | 454 } else if (xk == SystemDictionary::reflect_Constructor_klass()) { |
710 | 455 oop clazz = java_lang_reflect_Constructor::clazz(x); |
456 int slot = java_lang_reflect_Constructor::slot(x); | |
457 klassOop k = java_lang_Class::as_klassOop(clazz); | |
458 if (k != NULL && Klass::cast(k)->oop_is_instance()) | |
459 return decode_methodOop(instanceKlass::cast(k)->method_with_idnum(slot), | |
460 decode_flags_result); | |
461 } else { | |
462 // unrecognized object | |
463 assert(!x->is_method(), "already checked"); | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
464 assert(!java_lang_invoke_MemberName::is_instance(x), "already checked"); |
710 | 465 } |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
466 return methodHandle(); |
710 | 467 } |
468 | |
469 | |
470 int MethodHandles::decode_MethodHandle_stack_pushes(oop mh) { | |
471 if (mh->klass() == SystemDictionary::DirectMethodHandle_klass()) | |
472 return 0; // no push/pop | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
473 int this_vmslots = java_lang_invoke_MethodHandle::vmslots(mh); |
710 | 474 int last_vmslots = 0; |
475 oop last_mh = mh; | |
476 for (;;) { | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
477 oop target = java_lang_invoke_MethodHandle::vmtarget(last_mh); |
710 | 478 if (target->klass() == SystemDictionary::DirectMethodHandle_klass()) { |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
479 last_vmslots = java_lang_invoke_MethodHandle::vmslots(target); |
710 | 480 break; |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
481 } else if (!java_lang_invoke_MethodHandle::is_instance(target)) { |
710 | 482 // might be klass or method |
483 assert(target->is_method(), "must get here with a direct ref to method"); | |
484 last_vmslots = methodOop(target)->size_of_parameters(); | |
485 break; | |
486 } | |
487 last_mh = target; | |
488 } | |
489 // If I am called with fewer VM slots than my ultimate callee, | |
490 // it must be that I push the additionally needed slots. | |
491 // Likewise if am called with more VM slots, I will pop them. | |
492 return (last_vmslots - this_vmslots); | |
493 } | |
494 | |
495 | |
496 // MemberName support | |
497 | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
498 // import java_lang_invoke_MemberName.* |
710 | 499 enum { |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
500 IS_METHOD = java_lang_invoke_MemberName::MN_IS_METHOD, |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
501 IS_CONSTRUCTOR = java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR, |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
502 IS_FIELD = java_lang_invoke_MemberName::MN_IS_FIELD, |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
503 IS_TYPE = java_lang_invoke_MemberName::MN_IS_TYPE, |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
504 SEARCH_SUPERCLASSES = java_lang_invoke_MemberName::MN_SEARCH_SUPERCLASSES, |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
505 SEARCH_INTERFACES = java_lang_invoke_MemberName::MN_SEARCH_INTERFACES, |
710 | 506 ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE, |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
507 VM_INDEX_UNINITIALIZED = java_lang_invoke_MemberName::VM_INDEX_UNINITIALIZED |
710 | 508 }; |
509 | |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
510 Handle MethodHandles::new_MemberName(TRAPS) { |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
511 Handle empty; |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
512 instanceKlassHandle k(THREAD, SystemDictionary::MemberName_klass()); |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
513 if (!k->is_initialized()) k->initialize(CHECK_(empty)); |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
514 return Handle(THREAD, k->allocate_instance(THREAD)); |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
515 } |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
516 |
710 | 517 void MethodHandles::init_MemberName(oop mname_oop, oop target_oop) { |
1142 | 518 if (target_oop->klass() == SystemDictionary::reflect_Field_klass()) { |
710 | 519 oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder() |
520 int slot = java_lang_reflect_Field::slot(target_oop); // fd.index() | |
521 int mods = java_lang_reflect_Field::modifiers(target_oop); | |
522 klassOop k = java_lang_Class::as_klassOop(clazz); | |
3938 | 523 int offset = instanceKlass::cast(k)->field_offset(slot); |
710 | 524 init_MemberName(mname_oop, k, accessFlags_from(mods), offset); |
525 } else { | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
526 KlassHandle receiver_limit; int decode_flags = 0; |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
527 methodHandle m = MethodHandles::decode_method(target_oop, receiver_limit, decode_flags); |
710 | 528 bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0); |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
529 init_MemberName(mname_oop, m(), do_dispatch); |
710 | 530 } |
531 } | |
532 | |
533 void MethodHandles::init_MemberName(oop mname_oop, methodOop m, bool do_dispatch) { | |
534 int flags = ((m->is_initializer() ? IS_CONSTRUCTOR : IS_METHOD) | |
535 | (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS )); | |
536 oop vmtarget = m; | |
537 int vmindex = methodOopDesc::invalid_vtable_index; // implies no info yet | |
538 if (!do_dispatch || (flags & IS_CONSTRUCTOR) || m->can_be_statically_bound()) | |
539 vmindex = methodOopDesc::nonvirtual_vtable_index; // implies never any dispatch | |
540 assert(vmindex != VM_INDEX_UNINITIALIZED, "Java sentinel value"); | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
541 java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
542 java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
543 java_lang_invoke_MemberName::set_flags(mname_oop, flags); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
544 java_lang_invoke_MemberName::set_clazz(mname_oop, Klass::cast(m->method_holder())->java_mirror()); |
710 | 545 } |
546 | |
547 void MethodHandles::init_MemberName(oop mname_oop, klassOop field_holder, AccessFlags mods, int offset) { | |
548 int flags = (IS_FIELD | (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS )); | |
549 oop vmtarget = field_holder; | |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
550 int vmindex = offset; // determines the field uniquely when combined with static bit |
710 | 551 assert(vmindex != VM_INDEX_UNINITIALIZED, "bad alias on vmindex"); |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
552 java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
553 java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
554 java_lang_invoke_MemberName::set_flags(mname_oop, flags); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
555 java_lang_invoke_MemberName::set_clazz(mname_oop, Klass::cast(field_holder)->java_mirror()); |
710 | 556 } |
557 | |
558 | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
559 methodHandle MethodHandles::decode_MemberName(oop mname, KlassHandle& receiver_limit_result, int& decode_flags_result) { |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
560 methodHandle empty; |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
561 int flags = java_lang_invoke_MemberName::flags(mname); |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
562 if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) == 0) return empty; // not invocable |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
563 oop vmtarget = java_lang_invoke_MemberName::vmtarget(mname); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
564 int vmindex = java_lang_invoke_MemberName::vmindex(mname); |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
565 if (vmindex == VM_INDEX_UNINITIALIZED) return empty; // not resolved |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
566 methodHandle m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result); |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
567 oop clazz = java_lang_invoke_MemberName::clazz(mname); |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
568 if (clazz != NULL && java_lang_Class::is_instance(clazz)) { |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
569 klassOop klass = java_lang_Class::as_klassOop(clazz); |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
570 if (klass != NULL) receiver_limit_result = klass; |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
571 } |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
572 return m; |
710 | 573 } |
574 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
575 // convert the external string or reflective type to an internal signature |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
576 Symbol* MethodHandles::convert_to_signature(oop type_str, bool polymorphic, TRAPS) { |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
577 if (java_lang_invoke_MethodType::is_instance(type_str)) { |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
578 return java_lang_invoke_MethodType::as_signature(type_str, polymorphic, CHECK_NULL); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
579 } else if (java_lang_Class::is_instance(type_str)) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
580 return java_lang_Class::as_signature(type_str, false, CHECK_NULL); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
581 } else if (java_lang_String::is_instance(type_str)) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
582 if (polymorphic) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
583 return java_lang_String::as_symbol(type_str, CHECK_NULL); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
584 } else { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
585 return java_lang_String::as_symbol_or_null(type_str); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
586 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
587 } else { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
588 THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized type", NULL); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
589 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
590 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
591 |
710 | 592 // An unresolved member name is a mere symbolic reference. |
593 // Resolving it plants a vmtarget/vmindex in it, | |
594 // which refers dirctly to JVM internals. | |
595 void MethodHandles::resolve_MemberName(Handle mname, TRAPS) { | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
596 assert(java_lang_invoke_MemberName::is_instance(mname()), ""); |
710 | 597 #ifdef ASSERT |
598 // If this assert throws, renegotiate the sentinel value used by the Java code, | |
599 // so that it is distinct from any valid vtable index value, and any special | |
600 // values defined in methodOopDesc::VtableIndexFlag. | |
601 // The point of the slop is to give the Java code and the JVM some room | |
602 // to independently specify sentinel values. | |
603 const int sentinel_slop = 10; | |
604 const int sentinel_limit = methodOopDesc::highest_unused_vtable_index_value - sentinel_slop; | |
605 assert(VM_INDEX_UNINITIALIZED < sentinel_limit, "Java sentinel != JVM sentinels"); | |
606 #endif | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
607 if (java_lang_invoke_MemberName::vmindex(mname()) != VM_INDEX_UNINITIALIZED) |
710 | 608 return; // already resolved |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
609 Handle defc_oop(THREAD, java_lang_invoke_MemberName::clazz(mname())); |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
610 Handle name_str(THREAD, java_lang_invoke_MemberName::name( mname())); |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
611 Handle type_str(THREAD, java_lang_invoke_MemberName::type( mname())); |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
612 int flags = java_lang_invoke_MemberName::flags(mname()); |
710 | 613 |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
614 if (defc_oop.is_null() || name_str.is_null() || type_str.is_null()) { |
710 | 615 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve"); |
616 } | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
617 |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
618 instanceKlassHandle defc; |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
619 { |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
620 klassOop defc_klassOop = java_lang_Class::as_klassOop(defc_oop()); |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
621 if (defc_klassOop == NULL) return; // a primitive; no resolution possible |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
622 if (!Klass::cast(defc_klassOop)->oop_is_instance()) { |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
623 if (!Klass::cast(defc_klassOop)->oop_is_array()) return; |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
624 defc_klassOop = SystemDictionary::Object_klass(); |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
625 } |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
626 defc = instanceKlassHandle(THREAD, defc_klassOop); |
710 | 627 } |
628 if (defc.is_null()) { | |
629 THROW_MSG(vmSymbols::java_lang_InternalError(), "primitive class"); | |
630 } | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
631 defc->link_class(CHECK); // possible safepoint |
710 | 632 |
633 // convert the external string name to an internal symbol | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
634 TempNewSymbol name = java_lang_String::as_symbol_or_null(name_str()); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
635 if (name == NULL) return; // no such name |
3781
d83ac25d0304
7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents:
3757
diff
changeset
|
636 if (name == vmSymbols::class_initializer_name()) |
d83ac25d0304
7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents:
3757
diff
changeset
|
637 return; // illegal name |
710 | 638 |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
639 Handle polymorphic_method_type; |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
640 bool polymorphic_signature = false; |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
641 if ((flags & ALL_KINDS) == IS_METHOD && |
2001
f2da85a9b08e
7001363: java/dyn/InvokeDynamic should not be a well-known class in the JVM
twisti
parents:
1972
diff
changeset
|
642 (defc() == SystemDictionary::MethodHandle_klass() && |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
643 methodOopDesc::is_method_handle_invoke_name(name))) { |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
644 polymorphic_signature = true; |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
645 } |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
646 |
710 | 647 // convert the external string or reflective type to an internal signature |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
648 TempNewSymbol type = convert_to_signature(type_str(), polymorphic_signature, CHECK); |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
649 if (java_lang_invoke_MethodType::is_instance(type_str()) && polymorphic_signature) { |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
650 polymorphic_method_type = type_str; // preserve exactly |
710 | 651 } |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
652 if (type == NULL) return; // no such signature exists in the VM |
710 | 653 |
654 // Time to do the lookup. | |
655 switch (flags & ALL_KINDS) { | |
656 case IS_METHOD: | |
657 { | |
658 CallInfo result; | |
659 { | |
660 EXCEPTION_MARK; | |
661 if ((flags & JVM_ACC_STATIC) != 0) { | |
662 LinkResolver::resolve_static_call(result, | |
663 defc, name, type, KlassHandle(), false, false, THREAD); | |
664 } else if (defc->is_interface()) { | |
665 LinkResolver::resolve_interface_call(result, Handle(), defc, | |
666 defc, name, type, KlassHandle(), false, false, THREAD); | |
667 } else { | |
668 LinkResolver::resolve_virtual_call(result, Handle(), defc, | |
669 defc, name, type, KlassHandle(), false, false, THREAD); | |
670 } | |
671 if (HAS_PENDING_EXCEPTION) { | |
672 CLEAR_PENDING_EXCEPTION; | |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
673 break; // go to second chance |
710 | 674 } |
675 } | |
676 methodHandle m = result.resolved_method(); | |
677 oop vmtarget = NULL; | |
678 int vmindex = methodOopDesc::nonvirtual_vtable_index; | |
679 if (defc->is_interface()) { | |
680 vmindex = klassItable::compute_itable_index(m()); | |
681 assert(vmindex >= 0, ""); | |
682 } else if (result.has_vtable_index()) { | |
683 vmindex = result.vtable_index(); | |
684 assert(vmindex >= 0, ""); | |
685 } | |
686 assert(vmindex != VM_INDEX_UNINITIALIZED, ""); | |
687 if (vmindex < 0) { | |
688 assert(result.is_statically_bound(), ""); | |
689 vmtarget = m(); | |
690 } else { | |
691 vmtarget = result.resolved_klass()->as_klassOop(); | |
692 } | |
693 int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS); | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
694 java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
695 java_lang_invoke_MemberName::set_vmindex(mname(), vmindex); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
696 java_lang_invoke_MemberName::set_modifiers(mname(), mods); |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
697 DEBUG_ONLY(KlassHandle junk1; int junk2); |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
698 assert(decode_MemberName(mname(), junk1, junk2) == result.resolved_method(), |
710 | 699 "properly stored for later decoding"); |
700 return; | |
701 } | |
702 case IS_CONSTRUCTOR: | |
703 { | |
704 CallInfo result; | |
705 { | |
706 EXCEPTION_MARK; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
707 if (name == vmSymbols::object_initializer_name()) { |
710 | 708 LinkResolver::resolve_special_call(result, |
709 defc, name, type, KlassHandle(), false, THREAD); | |
710 } else { | |
711 break; // will throw after end of switch | |
712 } | |
713 if (HAS_PENDING_EXCEPTION) { | |
714 CLEAR_PENDING_EXCEPTION; | |
715 return; | |
716 } | |
717 } | |
718 assert(result.is_statically_bound(), ""); | |
719 methodHandle m = result.resolved_method(); | |
720 oop vmtarget = m(); | |
721 int vmindex = methodOopDesc::nonvirtual_vtable_index; | |
722 int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS); | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
723 java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
724 java_lang_invoke_MemberName::set_vmindex(mname(), vmindex); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
725 java_lang_invoke_MemberName::set_modifiers(mname(), mods); |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
726 DEBUG_ONLY(KlassHandle junk1; int junk2); |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
727 assert(decode_MemberName(mname(), junk1, junk2) == result.resolved_method(), |
710 | 728 "properly stored for later decoding"); |
729 return; | |
730 } | |
731 case IS_FIELD: | |
732 { | |
733 // This is taken from LinkResolver::resolve_field, sans access checks. | |
734 fieldDescriptor fd; // find_field initializes fd if found | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
735 KlassHandle sel_klass(THREAD, instanceKlass::cast(defc())->find_field(name, type, &fd)); |
710 | 736 // check if field exists; i.e., if a klass containing the field def has been selected |
737 if (sel_klass.is_null()) return; | |
738 oop vmtarget = sel_klass->as_klassOop(); | |
739 int vmindex = fd.offset(); | |
740 int mods = (fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS); | |
741 if (vmindex == VM_INDEX_UNINITIALIZED) break; // should not happen | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
742 java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
743 java_lang_invoke_MemberName::set_vmindex(mname(), vmindex); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
744 java_lang_invoke_MemberName::set_modifiers(mname(), mods); |
710 | 745 return; |
746 } | |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
747 default: |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
748 THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format"); |
710 | 749 } |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
750 |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
751 // Second chance. |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
752 if (polymorphic_method_type.not_null()) { |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
753 // Look on a non-null class loader. |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
754 Handle cur_class_loader; |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
755 const int nptypes = java_lang_invoke_MethodType::ptype_count(polymorphic_method_type()); |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
756 for (int i = 0; i <= nptypes; i++) { |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
757 oop type_mirror; |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
758 if (i < nptypes) type_mirror = java_lang_invoke_MethodType::ptype(polymorphic_method_type(), i); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
759 else type_mirror = java_lang_invoke_MethodType::rtype(polymorphic_method_type()); |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
760 klassOop example_type = java_lang_Class::as_klassOop(type_mirror); |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
761 if (example_type == NULL) continue; |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
762 oop class_loader = Klass::cast(example_type)->class_loader(); |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
763 if (class_loader == NULL || class_loader == cur_class_loader()) continue; |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
764 cur_class_loader = Handle(THREAD, class_loader); |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
765 methodOop m = SystemDictionary::find_method_handle_invoke(name, |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
766 type, |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
767 KlassHandle(THREAD, example_type), |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
768 THREAD); |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
769 if (HAS_PENDING_EXCEPTION) { |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
770 CLEAR_PENDING_EXCEPTION; |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
771 m = NULL; |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
772 // try again with a different class loader... |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
773 } |
3785
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
774 if (m != NULL && |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
775 m->is_method_handle_invoke() && |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
776 java_lang_invoke_MethodType::equals(polymorphic_method_type(), m->method_handle_type())) { |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
777 int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS); |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
778 java_lang_invoke_MemberName::set_vmtarget(mname(), m); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
779 java_lang_invoke_MemberName::set_vmindex(mname(), m->vtable_index()); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
780 java_lang_invoke_MemberName::set_modifiers(mname(), mods); |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
781 return; |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
782 } |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
783 } |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
784 } |
710 | 785 } |
786 | |
787 // Conversely, a member name which is only initialized from JVM internals | |
788 // may have null defc, name, and type fields. | |
789 // Resolving it plants a vmtarget/vmindex in it, | |
790 // which refers directly to JVM internals. | |
791 void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) { | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
792 assert(java_lang_invoke_MemberName::is_instance(mname()), ""); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
793 oop vmtarget = java_lang_invoke_MemberName::vmtarget(mname()); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
794 int vmindex = java_lang_invoke_MemberName::vmindex(mname()); |
710 | 795 if (vmtarget == NULL || vmindex == VM_INDEX_UNINITIALIZED) { |
796 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to expand"); | |
797 } | |
798 | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
799 bool have_defc = (java_lang_invoke_MemberName::clazz(mname()) != NULL); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
800 bool have_name = (java_lang_invoke_MemberName::name(mname()) != NULL); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
801 bool have_type = (java_lang_invoke_MemberName::type(mname()) != NULL); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
802 int flags = java_lang_invoke_MemberName::flags(mname()); |
710 | 803 |
804 if (suppress != 0) { | |
805 if (suppress & _suppress_defc) have_defc = true; | |
806 if (suppress & _suppress_name) have_name = true; | |
807 if (suppress & _suppress_type) have_type = true; | |
808 } | |
809 | |
810 if (have_defc && have_name && have_type) return; // nothing needed | |
811 | |
812 switch (flags & ALL_KINDS) { | |
813 case IS_METHOD: | |
814 case IS_CONSTRUCTOR: | |
815 { | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
816 KlassHandle receiver_limit; int decode_flags = 0; |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
817 methodHandle m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit, decode_flags); |
710 | 818 if (m.is_null()) break; |
819 if (!have_defc) { | |
820 klassOop defc = m->method_holder(); | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
821 if (receiver_limit.not_null() && receiver_limit() != defc |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
822 && Klass::cast(receiver_limit())->is_subtype_of(defc)) |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
823 defc = receiver_limit(); |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
824 java_lang_invoke_MemberName::set_clazz(mname(), Klass::cast(defc)->java_mirror()); |
710 | 825 } |
826 if (!have_name) { | |
827 //not java_lang_String::create_from_symbol; let's intern member names | |
828 Handle name = StringTable::intern(m->name(), CHECK); | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
829 java_lang_invoke_MemberName::set_name(mname(), name()); |
710 | 830 } |
831 if (!have_type) { | |
832 Handle type = java_lang_String::create_from_symbol(m->signature(), CHECK); | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
833 java_lang_invoke_MemberName::set_type(mname(), type()); |
710 | 834 } |
835 return; | |
836 } | |
837 case IS_FIELD: | |
838 { | |
839 // This is taken from LinkResolver::resolve_field, sans access checks. | |
840 if (!vmtarget->is_klass()) break; | |
841 if (!Klass::cast((klassOop) vmtarget)->oop_is_instance()) break; | |
842 instanceKlassHandle defc(THREAD, (klassOop) vmtarget); | |
843 bool is_static = ((flags & JVM_ACC_STATIC) != 0); | |
844 fieldDescriptor fd; // find_field initializes fd if found | |
845 if (!defc->find_field_from_offset(vmindex, is_static, &fd)) | |
846 break; // cannot expand | |
847 if (!have_defc) { | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
848 java_lang_invoke_MemberName::set_clazz(mname(), defc->java_mirror()); |
710 | 849 } |
850 if (!have_name) { | |
851 //not java_lang_String::create_from_symbol; let's intern member names | |
852 Handle name = StringTable::intern(fd.name(), CHECK); | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
853 java_lang_invoke_MemberName::set_name(mname(), name()); |
710 | 854 } |
855 if (!have_type) { | |
856 Handle type = java_lang_String::create_from_symbol(fd.signature(), CHECK); | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
857 java_lang_invoke_MemberName::set_type(mname(), type()); |
710 | 858 } |
859 return; | |
860 } | |
861 } | |
862 THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format"); | |
863 } | |
864 | |
865 int MethodHandles::find_MemberNames(klassOop k, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
866 Symbol* name, Symbol* sig, |
710 | 867 int mflags, klassOop caller, |
868 int skip, objArrayOop results) { | |
869 DEBUG_ONLY(No_Safepoint_Verifier nsv); | |
870 // this code contains no safepoints! | |
871 | |
872 // %%% take caller into account! | |
873 | |
874 if (k == NULL || !Klass::cast(k)->oop_is_instance()) return -1; | |
875 | |
876 int rfill = 0, rlimit = results->length(), rskip = skip; | |
877 // overflow measurement: | |
878 int overflow = 0, overflow_limit = MAX2(1000, rlimit); | |
879 | |
880 int match_flags = mflags; | |
881 bool search_superc = ((match_flags & SEARCH_SUPERCLASSES) != 0); | |
882 bool search_intfc = ((match_flags & SEARCH_INTERFACES) != 0); | |
883 bool local_only = !(search_superc | search_intfc); | |
884 bool classes_only = false; | |
885 | |
886 if (name != NULL) { | |
887 if (name->utf8_length() == 0) return 0; // a match is not possible | |
888 } | |
889 if (sig != NULL) { | |
890 if (sig->utf8_length() == 0) return 0; // a match is not possible | |
891 if (sig->byte_at(0) == '(') | |
892 match_flags &= ~(IS_FIELD | IS_TYPE); | |
893 else | |
894 match_flags &= ~(IS_CONSTRUCTOR | IS_METHOD); | |
895 } | |
896 | |
897 if ((match_flags & IS_TYPE) != 0) { | |
898 // NYI, and Core Reflection works quite well for this query | |
899 } | |
900 | |
901 if ((match_flags & IS_FIELD) != 0) { | |
902 for (FieldStream st(k, local_only, !search_intfc); !st.eos(); st.next()) { | |
903 if (name != NULL && st.name() != name) | |
904 continue; | |
905 if (sig != NULL && st.signature() != sig) | |
906 continue; | |
907 // passed the filters | |
908 if (rskip > 0) { | |
909 --rskip; | |
910 } else if (rfill < rlimit) { | |
911 oop result = results->obj_at(rfill++); | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
912 if (!java_lang_invoke_MemberName::is_instance(result)) |
710 | 913 return -99; // caller bug! |
914 MethodHandles::init_MemberName(result, st.klass()->as_klassOop(), st.access_flags(), st.offset()); | |
915 } else if (++overflow >= overflow_limit) { | |
916 match_flags = 0; break; // got tired of looking at overflow | |
917 } | |
918 } | |
919 } | |
920 | |
921 if ((match_flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) { | |
922 // watch out for these guys: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
923 Symbol* init_name = vmSymbols::object_initializer_name(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
924 Symbol* clinit_name = vmSymbols::class_initializer_name(); |
710 | 925 if (name == clinit_name) clinit_name = NULL; // hack for exposing <clinit> |
926 bool negate_name_test = false; | |
927 // fix name so that it captures the intention of IS_CONSTRUCTOR | |
928 if (!(match_flags & IS_METHOD)) { | |
929 // constructors only | |
930 if (name == NULL) { | |
931 name = init_name; | |
932 } else if (name != init_name) { | |
933 return 0; // no constructors of this method name | |
934 } | |
935 } else if (!(match_flags & IS_CONSTRUCTOR)) { | |
936 // methods only | |
937 if (name == NULL) { | |
938 name = init_name; | |
939 negate_name_test = true; // if we see the name, we *omit* the entry | |
940 } else if (name == init_name) { | |
941 return 0; // no methods of this constructor name | |
942 } | |
943 } else { | |
944 // caller will accept either sort; no need to adjust name | |
945 } | |
946 for (MethodStream st(k, local_only, !search_intfc); !st.eos(); st.next()) { | |
947 methodOop m = st.method(); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
948 Symbol* m_name = m->name(); |
710 | 949 if (m_name == clinit_name) |
950 continue; | |
951 if (name != NULL && ((m_name != name) ^ negate_name_test)) | |
952 continue; | |
953 if (sig != NULL && m->signature() != sig) | |
954 continue; | |
955 // passed the filters | |
956 if (rskip > 0) { | |
957 --rskip; | |
958 } else if (rfill < rlimit) { | |
959 oop result = results->obj_at(rfill++); | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
960 if (!java_lang_invoke_MemberName::is_instance(result)) |
710 | 961 return -99; // caller bug! |
962 MethodHandles::init_MemberName(result, m, true); | |
963 } else if (++overflow >= overflow_limit) { | |
964 match_flags = 0; break; // got tired of looking at overflow | |
965 } | |
966 } | |
967 } | |
968 | |
969 // return number of elements we at leasted wanted to initialize | |
970 return rfill + overflow; | |
971 } | |
972 | |
973 | |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
974 // Decode this java.lang.Class object into an instanceKlass, if possible. |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
975 // Throw IAE if not |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
976 instanceKlassHandle MethodHandles::resolve_instance_klass(oop java_mirror_oop, TRAPS) { |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
977 instanceKlassHandle empty; |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
978 klassOop caller = NULL; |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
979 if (java_lang_Class::is_instance(java_mirror_oop)) { |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
980 caller = java_lang_Class::as_klassOop(java_mirror_oop); |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
981 } |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
982 if (caller == NULL || !Klass::cast(caller)->oop_is_instance()) { |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
983 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "not a class", empty); |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
984 } |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
985 return instanceKlassHandle(THREAD, caller); |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
986 } |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
987 |
710 | 988 |
989 | |
990 // Decode the vmtarget field of a method handle. | |
991 // Sanitize out methodOops, klassOops, and any other non-Java data. | |
992 // This is for debugging and reflection. | |
993 oop MethodHandles::encode_target(Handle mh, int format, TRAPS) { | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
994 assert(java_lang_invoke_MethodHandle::is_instance(mh()), "must be a MH"); |
3785
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
995 if (format == ETF_FORCE_DIRECT_HANDLE || |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
996 format == ETF_COMPILE_DIRECT_HANDLE) { |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
997 // Internal function for stress testing. |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
998 Handle mt = java_lang_invoke_MethodHandle::type(mh()); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
999 int invocation_count = 10000; |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1000 TempNewSymbol signature = java_lang_invoke_MethodType::as_signature(mt(), true, CHECK_NULL); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1001 bool omit_receiver_argument = true; |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1002 MethodHandleCompiler mhc(mh, vmSymbols::invoke_name(), signature, invocation_count, omit_receiver_argument, CHECK_NULL); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1003 methodHandle m = mhc.compile(CHECK_NULL); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1004 if (StressMethodHandleWalk && Verbose || PrintMiscellaneous) { |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1005 tty->print_cr("MethodHandleNatives.getTarget(%s)", |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1006 format == ETF_FORCE_DIRECT_HANDLE ? "FORCE_DIRECT" : "COMPILE_DIRECT"); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1007 if (Verbose) { |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1008 m->print_codes(); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1009 } |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1010 } |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1011 if (StressMethodHandleWalk) { |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1012 InterpreterOopMap mask; |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1013 OopMapCache::compute_one_oop_map(m, m->code_size() - 1, &mask); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1014 } |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1015 if ((format == ETF_COMPILE_DIRECT_HANDLE || |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1016 CompilationPolicy::must_be_compiled(m)) |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1017 && !instanceKlass::cast(m->method_holder())->is_not_initialized() |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1018 && CompilationPolicy::can_be_compiled(m)) { |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1019 // Force compilation |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1020 CompileBroker::compile_method(m, InvocationEntryBci, |
3837
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3785
diff
changeset
|
1021 CompilationPolicy::policy()->initial_compile_level(), |
3785
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1022 methodHandle(), 0, "MethodHandleNatives.getTarget", |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1023 CHECK_NULL); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1024 } |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1025 // Now wrap m in a DirectMethodHandle. |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1026 instanceKlassHandle dmh_klass(THREAD, SystemDictionary::DirectMethodHandle_klass()); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1027 Handle dmh = dmh_klass->allocate_instance_handle(CHECK_NULL); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1028 JavaValue ignore_result(T_VOID); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1029 Symbol* init_name = vmSymbols::object_initializer_name(); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1030 Symbol* init_sig = vmSymbols::notifyGenericMethodType_signature(); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1031 JavaCalls::call_special(&ignore_result, dmh, |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1032 SystemDictionaryHandles::MethodHandle_klass(), init_name, init_sig, |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1033 java_lang_invoke_MethodHandle::type(mh()), CHECK_NULL); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1034 MethodHandles::init_DirectMethodHandle(dmh, m, false, CHECK_NULL); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1035 return dmh(); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1036 } |
710 | 1037 if (format == ETF_HANDLE_OR_METHOD_NAME) { |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1038 oop target = java_lang_invoke_MethodHandle::vmtarget(mh()); |
710 | 1039 if (target == NULL) { |
1040 return NULL; // unformed MH | |
1041 } | |
1042 klassOop tklass = target->klass(); | |
1142 | 1043 if (Klass::cast(tklass)->is_subclass_of(SystemDictionary::Object_klass())) { |
710 | 1044 return target; // target is another MH (or something else?) |
1045 } | |
1046 } | |
1047 if (format == ETF_DIRECT_HANDLE) { | |
1048 oop target = mh(); | |
1049 for (;;) { | |
1050 if (target->klass() == SystemDictionary::DirectMethodHandle_klass()) { | |
1051 return target; | |
1052 } | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1053 if (!java_lang_invoke_MethodHandle::is_instance(target)){ |
710 | 1054 return NULL; // unformed MH |
1055 } | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1056 target = java_lang_invoke_MethodHandle::vmtarget(target); |
710 | 1057 } |
1058 } | |
1059 // cases of metadata in MH.vmtarget: | |
1060 // - AMH can have methodOop for static invoke with bound receiver | |
1061 // - DMH can have methodOop for static invoke (on variable receiver) | |
1062 // - DMH can have klassOop for dispatched (non-static) invoke | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1063 KlassHandle receiver_limit; int decode_flags = 0; |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1064 methodHandle m = decode_MethodHandle(mh(), receiver_limit, decode_flags); |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1065 if (m.is_null()) return NULL; |
710 | 1066 switch (format) { |
1067 case ETF_REFLECT_METHOD: | |
1068 // same as jni_ToReflectedMethod: | |
1069 if (m->is_initializer()) { | |
1070 return Reflection::new_constructor(m, THREAD); | |
1071 } else { | |
1072 return Reflection::new_method(m, UseNewReflection, false, THREAD); | |
1073 } | |
1074 | |
1075 case ETF_HANDLE_OR_METHOD_NAME: // method, not handle | |
1076 case ETF_METHOD_NAME: | |
1077 { | |
1078 if (SystemDictionary::MemberName_klass() == NULL) break; | |
1079 instanceKlassHandle mname_klass(THREAD, SystemDictionary::MemberName_klass()); | |
1080 mname_klass->initialize(CHECK_NULL); | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1081 Handle mname = mname_klass->allocate_instance_handle(CHECK_NULL); // possible safepoint |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1082 java_lang_invoke_MemberName::set_vmindex(mname(), VM_INDEX_UNINITIALIZED); |
710 | 1083 bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0); |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1084 init_MemberName(mname(), m(), do_dispatch); |
710 | 1085 expand_MemberName(mname, 0, CHECK_NULL); |
1086 return mname(); | |
1087 } | |
1088 } | |
1089 | |
1090 // Unknown format code. | |
1091 char msg[50]; | |
1092 jio_snprintf(msg, sizeof(msg), "unknown getTarget format=%d", format); | |
1093 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), msg); | |
1094 } | |
1095 | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1096 static const char* always_null_names[] = { |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1097 "java/lang/Void", |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1098 "java/lang/Null", |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1099 //"java/lang/Nothing", |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1100 "sun/dyn/empty/Empty", |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1101 "sun/invoke/empty/Empty", |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1102 NULL |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1103 }; |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1104 |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1105 static bool is_always_null_type(klassOop klass) { |
2478
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1106 if (klass == NULL) return false; // safety |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1107 if (!Klass::cast(klass)->oop_is_instance()) return false; |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1108 instanceKlass* ik = instanceKlass::cast(klass); |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1109 // Must be on the boot class path: |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1110 if (ik->class_loader() != NULL) return false; |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1111 // Check the name. |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
1112 Symbol* name = ik->name(); |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1113 for (int i = 0; ; i++) { |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1114 const char* test_name = always_null_names[i]; |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1115 if (test_name == NULL) break; |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
1116 if (name->equals(test_name)) |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1117 return true; |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1118 } |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1119 return false; |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1120 } |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1121 |
710 | 1122 bool MethodHandles::class_cast_needed(klassOop src, klassOop dst) { |
2478
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1123 if (dst == NULL) return true; |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1124 if (src == NULL) return (dst != SystemDictionary::Object_klass()); |
1142 | 1125 if (src == dst || dst == SystemDictionary::Object_klass()) |
710 | 1126 return false; // quickest checks |
1127 Klass* srck = Klass::cast(src); | |
1128 Klass* dstk = Klass::cast(dst); | |
1129 if (dstk->is_interface()) { | |
1130 // interface receivers can safely be viewed as untyped, | |
1131 // because interface calls always include a dynamic check | |
1142 | 1132 //dstk = Klass::cast(SystemDictionary::Object_klass()); |
710 | 1133 return false; |
1134 } | |
1135 if (srck->is_interface()) { | |
1136 // interface arguments must be viewed as untyped | |
1142 | 1137 //srck = Klass::cast(SystemDictionary::Object_klass()); |
710 | 1138 return true; |
1139 } | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1140 if (is_always_null_type(src)) { |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1141 // some source types are known to be never instantiated; |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1142 // they represent references which are always null |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1143 // such null references never fail to convert safely |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1144 return false; |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1145 } |
710 | 1146 return !srck->is_subclass_of(dstk->as_klassOop()); |
1147 } | |
1148 | |
1149 static oop object_java_mirror() { | |
1142 | 1150 return Klass::cast(SystemDictionary::Object_klass())->java_mirror(); |
710 | 1151 } |
1152 | |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
1153 bool MethodHandles::is_float_fixed_reinterpretation_cast(BasicType src, BasicType dst) { |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
1154 if (src == T_FLOAT) return dst == T_INT; |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
1155 if (src == T_INT) return dst == T_FLOAT; |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
1156 if (src == T_DOUBLE) return dst == T_LONG; |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
1157 if (src == T_LONG) return dst == T_DOUBLE; |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
1158 return false; |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
1159 } |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
1160 |
710 | 1161 bool MethodHandles::same_basic_type_for_arguments(BasicType src, |
1162 BasicType dst, | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1163 bool raw, |
710 | 1164 bool for_return) { |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1165 if (for_return) { |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1166 // return values can always be forgotten: |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1167 if (dst == T_VOID) return true; |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1168 if (src == T_VOID) return raw && (dst == T_INT); |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1169 // We allow caller to receive a garbage int, which is harmless. |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1170 // This trick is pulled by trusted code (see VerifyType.canPassRaw). |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1171 } |
710 | 1172 assert(src != T_VOID && dst != T_VOID, "should not be here"); |
1173 if (src == dst) return true; | |
1174 if (type2size[src] != type2size[dst]) return false; | |
1912
8213b0f5c92d
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
1849
diff
changeset
|
1175 if (src == T_OBJECT || dst == T_OBJECT) return false; |
8213b0f5c92d
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
1849
diff
changeset
|
1176 if (raw) return true; // bitwise reinterpretation; caller guarantees safety |
710 | 1177 // allow reinterpretation casts for integral widening |
1178 if (is_subword_type(src)) { // subwords can fit in int or other subwords | |
1179 if (dst == T_INT) // any subword fits in an int | |
1180 return true; | |
1181 if (src == T_BOOLEAN) // boolean fits in any subword | |
1182 return is_subword_type(dst); | |
1183 if (src == T_BYTE && dst == T_SHORT) | |
1184 return true; // remaining case: byte fits in short | |
1185 } | |
1186 // allow float/fixed reinterpretation casts | |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
1187 if (is_float_fixed_reinterpretation_cast(src, dst)) |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
1188 return true; |
710 | 1189 return false; |
1190 } | |
1191 | |
1192 const char* MethodHandles::check_method_receiver(methodOop m, | |
1193 klassOop passed_recv_type) { | |
1194 assert(!m->is_static(), "caller resp."); | |
1195 if (passed_recv_type == NULL) | |
1196 return "receiver type is primitive"; | |
1197 if (class_cast_needed(passed_recv_type, m->method_holder())) { | |
1198 Klass* formal = Klass::cast(m->method_holder()); | |
1199 return SharedRuntime::generate_class_cast_message("receiver type", | |
1200 formal->external_name()); | |
1201 } | |
1202 return NULL; // checks passed | |
1203 } | |
1204 | |
1205 // Verify that m's signature can be called type-safely by a method handle | |
1206 // of the given method type 'mtype'. | |
1207 // It takes a TRAPS argument because it must perform symbol lookups. | |
1208 void MethodHandles::verify_method_signature(methodHandle m, | |
1209 Handle mtype, | |
1210 int first_ptype_pos, | |
1211 KlassHandle insert_ptype, | |
1212 TRAPS) { | |
2478
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1213 Handle mhi_type; |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1214 if (m->is_method_handle_invoke()) { |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1215 // use this more exact typing instead of the symbolic signature: |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1216 mhi_type = Handle(THREAD, m->method_handle_type()); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1217 } |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1218 objArrayHandle ptypes(THREAD, java_lang_invoke_MethodType::ptypes(mtype())); |
710 | 1219 int pnum = first_ptype_pos; |
1220 int pmax = ptypes->length(); | |
2478
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1221 int anum = 0; // method argument |
710 | 1222 const char* err = NULL; |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
1223 ResourceMark rm(THREAD); |
710 | 1224 for (SignatureStream ss(m->signature()); !ss.is_done(); ss.next()) { |
1225 oop ptype_oop = NULL; | |
1226 if (ss.at_return_type()) { | |
1227 if (pnum != pmax) | |
1228 { err = "too many arguments"; break; } | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1229 ptype_oop = java_lang_invoke_MethodType::rtype(mtype()); |
710 | 1230 } else { |
1231 if (pnum >= pmax) | |
1232 { err = "not enough arguments"; break; } | |
1233 if (pnum >= 0) | |
1234 ptype_oop = ptypes->obj_at(pnum); | |
1235 else if (insert_ptype.is_null()) | |
1236 ptype_oop = NULL; | |
1237 else | |
1238 ptype_oop = insert_ptype->java_mirror(); | |
1239 pnum += 1; | |
2478
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1240 anum += 1; |
710 | 1241 } |
2478
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1242 KlassHandle pklass; |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1243 BasicType ptype = T_OBJECT; |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1244 bool have_ptype = false; |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1245 // missing ptype_oop does not match any non-reference; use Object to report the error |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1246 pklass = SystemDictionaryHandles::Object_klass(); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1247 if (ptype_oop != NULL) { |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1248 have_ptype = true; |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1249 klassOop pklass_oop = NULL; |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1250 ptype = java_lang_Class::as_BasicType(ptype_oop, &pklass_oop); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1251 pklass = KlassHandle(THREAD, pklass_oop); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1252 } |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1253 ptype_oop = NULL; //done with this |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1254 KlassHandle aklass; |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1255 BasicType atype = ss.type(); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1256 if (atype == T_ARRAY) atype = T_OBJECT; // fold all refs to T_OBJECT |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1257 if (atype == T_OBJECT) { |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1258 if (!have_ptype) { |
710 | 1259 // null matches any reference |
1260 continue; | |
1261 } | |
2478
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1262 if (mhi_type.is_null()) { |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1263 // If we fail to resolve types at this point, we will usually throw an error. |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1264 TempNewSymbol name = ss.as_symbol_or_null(); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1265 if (name != NULL) { |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1266 instanceKlass* mk = instanceKlass::cast(m->method_holder()); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1267 Handle loader(THREAD, mk->class_loader()); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1268 Handle domain(THREAD, mk->protection_domain()); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1269 klassOop aklass_oop = SystemDictionary::resolve_or_null(name, loader, domain, CHECK); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1270 if (aklass_oop != NULL) |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1271 aklass = KlassHandle(THREAD, aklass_oop); |
3785
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1272 if (aklass.is_null() && |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1273 pklass.not_null() && |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1274 loader.is_null() && |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1275 pklass->name() == name) |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1276 // accept name equivalence here, since that's the best we can do |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
1277 aklass = pklass; |
2478
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1278 } |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1279 } else { |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1280 // for method handle invokers we don't look at the name in the signature |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1281 oop atype_oop; |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1282 if (ss.at_return_type()) |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1283 atype_oop = java_lang_invoke_MethodType::rtype(mhi_type()); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1284 else |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1285 atype_oop = java_lang_invoke_MethodType::ptype(mhi_type(), anum-1); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1286 klassOop aklass_oop = NULL; |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1287 atype = java_lang_Class::as_BasicType(atype_oop, &aklass_oop); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1288 aklass = KlassHandle(THREAD, aklass_oop); |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
1289 } |
710 | 1290 } |
1291 if (!ss.at_return_type()) { | |
2478
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1292 err = check_argument_type_change(ptype, pklass(), atype, aklass(), anum); |
710 | 1293 } else { |
2478
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1294 err = check_return_type_change(atype, aklass(), ptype, pklass()); // note reversal! |
710 | 1295 } |
1296 if (err != NULL) break; | |
1297 } | |
1298 | |
1299 if (err != NULL) { | |
2478
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1300 #ifndef PRODUCT |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1301 if (PrintMiscellaneous && (Verbose || WizardMode)) { |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1302 tty->print("*** verify_method_signature failed: "); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1303 java_lang_invoke_MethodType::print_signature(mtype(), tty); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1304 tty->cr(); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1305 tty->print_cr(" first_ptype_pos = %d, insert_ptype = "UINTX_FORMAT, first_ptype_pos, insert_ptype()); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1306 tty->print(" Failing method: "); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1307 m->print(); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1308 } |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1309 #endif //PRODUCT |
710 | 1310 THROW_MSG(vmSymbols::java_lang_InternalError(), err); |
1311 } | |
1312 } | |
1313 | |
1314 // Main routine for verifying the MethodHandle.type of a proposed | |
1315 // direct or bound-direct method handle. | |
1316 void MethodHandles::verify_method_type(methodHandle m, | |
1317 Handle mtype, | |
1318 bool has_bound_recv, | |
1319 KlassHandle bound_recv_type, | |
1320 TRAPS) { | |
1321 bool m_needs_receiver = !m->is_static(); | |
1322 | |
1323 const char* err = NULL; | |
1324 | |
1325 int first_ptype_pos = m_needs_receiver ? 1 : 0; | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1326 if (has_bound_recv) { |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1327 first_ptype_pos -= 1; // ptypes do not include the bound argument; start earlier in them |
710 | 1328 if (m_needs_receiver && bound_recv_type.is_null()) |
1329 { err = "bound receiver is not an object"; goto die; } | |
1330 } | |
1331 | |
1332 if (m_needs_receiver && err == NULL) { | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1333 objArrayOop ptypes = java_lang_invoke_MethodType::ptypes(mtype()); |
710 | 1334 if (ptypes->length() < first_ptype_pos) |
1335 { err = "receiver argument is missing"; goto die; } | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1336 if (has_bound_recv) |
710 | 1337 err = check_method_receiver(m(), bound_recv_type->as_klassOop()); |
1338 else | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1339 err = check_method_receiver(m(), java_lang_Class::as_klassOop(ptypes->obj_at(first_ptype_pos-1))); |
710 | 1340 if (err != NULL) goto die; |
1341 } | |
1342 | |
1343 // Check the other arguments for mistypes. | |
1344 verify_method_signature(m, mtype, first_ptype_pos, bound_recv_type, CHECK); | |
1345 return; | |
1346 | |
1347 die: | |
1348 THROW_MSG(vmSymbols::java_lang_InternalError(), err); | |
1349 } | |
1350 | |
1351 void MethodHandles::verify_vmslots(Handle mh, TRAPS) { | |
1352 // Verify vmslots. | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1353 int check_slots = argument_slot_count(java_lang_invoke_MethodHandle::type(mh())); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1354 if (java_lang_invoke_MethodHandle::vmslots(mh()) != check_slots) { |
710 | 1355 THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in BMH"); |
1356 } | |
1357 } | |
1358 | |
1359 void MethodHandles::verify_vmargslot(Handle mh, int argnum, int argslot, TRAPS) { | |
1360 // Verify that argslot points at the given argnum. | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1361 int check_slot = argument_slot(java_lang_invoke_MethodHandle::type(mh()), argnum); |
710 | 1362 if (argslot != check_slot || argslot < 0) { |
3740
5ac411b3b8fc
7047961: JSR 292 MethodHandleWalk swap args doesn't handle T_LONG and T_DOUBLE properly
never
parents:
3389
diff
changeset
|
1363 ResourceMark rm; |
710 | 1364 const char* fmt = "for argnum of %d, vmargslot is %d, should be %d"; |
1365 size_t msglen = strlen(fmt) + 3*11 + 1; | |
1366 char* msg = NEW_RESOURCE_ARRAY(char, msglen); | |
1367 jio_snprintf(msg, msglen, fmt, argnum, argslot, check_slot); | |
1368 THROW_MSG(vmSymbols::java_lang_InternalError(), msg); | |
1369 } | |
1370 } | |
1371 | |
1372 // Verify the correspondence between two method types. | |
1373 // Apart from the advertised changes, caller method type X must | |
1374 // be able to invoke the callee method Y type with no violations | |
1375 // of type integrity. | |
1376 // Return NULL if all is well, else a short error message. | |
1377 const char* MethodHandles::check_method_type_change(oop src_mtype, int src_beg, int src_end, | |
1378 int insert_argnum, oop insert_type, | |
1379 int change_argnum, oop change_type, | |
1380 int delete_argnum, | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1381 oop dst_mtype, int dst_beg, int dst_end, |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1382 bool raw) { |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1383 objArrayOop src_ptypes = java_lang_invoke_MethodType::ptypes(src_mtype); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1384 objArrayOop dst_ptypes = java_lang_invoke_MethodType::ptypes(dst_mtype); |
710 | 1385 |
1386 int src_max = src_ptypes->length(); | |
1387 int dst_max = dst_ptypes->length(); | |
1388 | |
1389 if (src_end == -1) src_end = src_max; | |
1390 if (dst_end == -1) dst_end = dst_max; | |
1391 | |
1392 assert(0 <= src_beg && src_beg <= src_end && src_end <= src_max, "oob"); | |
1393 assert(0 <= dst_beg && dst_beg <= dst_end && dst_end <= dst_max, "oob"); | |
1394 | |
1395 // pending actions; set to -1 when done: | |
1396 int ins_idx = insert_argnum, chg_idx = change_argnum, del_idx = delete_argnum; | |
1397 | |
1398 const char* err = NULL; | |
1399 | |
1400 // Walk along each array of parameter types, including a virtual | |
1401 // NULL end marker at the end of each. | |
1402 for (int src_idx = src_beg, dst_idx = dst_beg; | |
1403 (src_idx <= src_end && dst_idx <= dst_end); | |
1404 src_idx++, dst_idx++) { | |
1405 oop src_type = (src_idx == src_end) ? oop(NULL) : src_ptypes->obj_at(src_idx); | |
1406 oop dst_type = (dst_idx == dst_end) ? oop(NULL) : dst_ptypes->obj_at(dst_idx); | |
1407 bool fix_null_src_type = false; | |
1408 | |
1409 // Perform requested edits. | |
1410 if (ins_idx == src_idx) { | |
1411 // note that the inserted guy is never affected by a change or deletion | |
1412 ins_idx = -1; | |
1413 src_type = insert_type; | |
1414 fix_null_src_type = true; | |
1415 --src_idx; // back up to process src type on next loop | |
1416 src_idx = src_end; | |
1417 } else { | |
1418 // note that the changed guy can be immediately deleted | |
1419 if (chg_idx == src_idx) { | |
1420 chg_idx = -1; | |
1421 assert(src_idx < src_end, "oob"); | |
1422 src_type = change_type; | |
1423 fix_null_src_type = true; | |
1424 } | |
1425 if (del_idx == src_idx) { | |
1426 del_idx = -1; | |
1427 assert(src_idx < src_end, "oob"); | |
1428 --dst_idx; | |
1429 continue; // rerun loop after skipping this position | |
1430 } | |
1431 } | |
1432 | |
1433 if (src_type == NULL && fix_null_src_type) | |
1434 // explicit null in this case matches any dest reference | |
1435 src_type = (java_lang_Class::is_primitive(dst_type) ? object_java_mirror() : dst_type); | |
1436 | |
1437 // Compare the two argument types. | |
1438 if (src_type != dst_type) { | |
1439 if (src_type == NULL) return "not enough arguments"; | |
1440 if (dst_type == NULL) return "too many arguments"; | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1441 err = check_argument_type_change(src_type, dst_type, dst_idx, raw); |
710 | 1442 if (err != NULL) return err; |
1443 } | |
1444 } | |
1445 | |
1446 // Now compare return types also. | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1447 oop src_rtype = java_lang_invoke_MethodType::rtype(src_mtype); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1448 oop dst_rtype = java_lang_invoke_MethodType::rtype(dst_mtype); |
710 | 1449 if (src_rtype != dst_rtype) { |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1450 err = check_return_type_change(dst_rtype, src_rtype, raw); // note reversal! |
710 | 1451 if (err != NULL) return err; |
1452 } | |
1453 | |
1454 assert(err == NULL, ""); | |
1455 return NULL; // all is well | |
1456 } | |
1457 | |
1458 | |
1459 const char* MethodHandles::check_argument_type_change(BasicType src_type, | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1460 klassOop src_klass, |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1461 BasicType dst_type, |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1462 klassOop dst_klass, |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1463 int argnum, |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1464 bool raw) { |
710 | 1465 const char* err = NULL; |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
1466 const bool for_return = (argnum < 0); |
710 | 1467 |
1468 // just in case: | |
1469 if (src_type == T_ARRAY) src_type = T_OBJECT; | |
1470 if (dst_type == T_ARRAY) dst_type = T_OBJECT; | |
1471 | |
1472 // Produce some nice messages if VerifyMethodHandles is turned on: | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1473 if (!same_basic_type_for_arguments(src_type, dst_type, raw, for_return)) { |
710 | 1474 if (src_type == T_OBJECT) { |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
1475 if (raw && is_java_primitive(dst_type)) |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
1476 return NULL; // ref-to-prim discards ref and returns zero |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
1477 err = (!for_return |
710 | 1478 ? "type mismatch: passing a %s for method argument #%d, which expects primitive %s" |
1479 : "type mismatch: returning a %s, but caller expects primitive %s"); | |
1480 } else if (dst_type == T_OBJECT) { | |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
1481 err = (!for_return |
710 | 1482 ? "type mismatch: passing a primitive %s for method argument #%d, which expects %s" |
1483 : "type mismatch: returning a primitive %s, but caller expects %s"); | |
1484 } else { | |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
1485 err = (!for_return |
710 | 1486 ? "type mismatch: passing a %s for method argument #%d, which expects %s" |
1487 : "type mismatch: returning a %s, but caller expects %s"); | |
1488 } | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1489 } else if (src_type == T_OBJECT && dst_type == T_OBJECT && |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1490 class_cast_needed(src_klass, dst_klass)) { |
710 | 1491 if (!class_cast_needed(dst_klass, src_klass)) { |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1492 if (raw) |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1493 return NULL; // reverse cast is OK; the MH target is trusted to enforce it |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
1494 err = (!for_return |
710 | 1495 ? "cast required: passing a %s for method argument #%d, which expects %s" |
1496 : "cast required: returning a %s, but caller expects %s"); | |
1497 } else { | |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
1498 err = (!for_return |
710 | 1499 ? "reference mismatch: passing a %s for method argument #%d, which expects %s" |
1500 : "reference mismatch: returning a %s, but caller expects %s"); | |
1501 } | |
1502 } else { | |
1503 // passed the obstacle course | |
1504 return NULL; | |
1505 } | |
1506 | |
1507 // format, format, format | |
1508 const char* src_name = type2name(src_type); | |
1509 const char* dst_name = type2name(dst_type); | |
1510 if (src_name == NULL) src_name = "unknown type"; | |
1511 if (dst_name == NULL) dst_name = "unknown type"; | |
2478
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1512 if (src_type == T_OBJECT) |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1513 src_name = (src_klass != NULL) ? Klass::cast(src_klass)->external_name() : "an unresolved class"; |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1514 if (dst_type == T_OBJECT) |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
1515 dst_name = (dst_klass != NULL) ? Klass::cast(dst_klass)->external_name() : "an unresolved class"; |
710 | 1516 |
1517 size_t msglen = strlen(err) + strlen(src_name) + strlen(dst_name) + (argnum < 10 ? 1 : 11); | |
1518 char* msg = NEW_RESOURCE_ARRAY(char, msglen + 1); | |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
1519 if (!for_return) { |
710 | 1520 assert(strstr(err, "%d") != NULL, ""); |
1521 jio_snprintf(msg, msglen, err, src_name, argnum, dst_name); | |
1522 } else { | |
1523 assert(strstr(err, "%d") == NULL, ""); | |
1524 jio_snprintf(msg, msglen, err, src_name, dst_name); | |
1525 } | |
1526 return msg; | |
1527 } | |
1528 | |
1529 // Compute the depth within the stack of the given argument, i.e., | |
1530 // the combined size of arguments to the right of the given argument. | |
1531 // For the last argument (ptypes.length-1) this will be zero. | |
1532 // For the first argument (0) this will be the size of all | |
1533 // arguments but that one. For the special number -1, this | |
1534 // will be the size of all arguments, including the first. | |
1535 // If the argument is neither -1 nor a valid argument index, | |
1536 // then return a negative number. Otherwise, the result | |
1537 // is in the range [0..vmslots] inclusive. | |
1538 int MethodHandles::argument_slot(oop method_type, int arg) { | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1539 objArrayOop ptypes = java_lang_invoke_MethodType::ptypes(method_type); |
710 | 1540 int argslot = 0; |
1541 int len = ptypes->length(); | |
1542 if (arg < -1 || arg >= len) return -99; | |
1543 for (int i = len-1; i > arg; i--) { | |
1544 BasicType bt = java_lang_Class::as_BasicType(ptypes->obj_at(i)); | |
1545 argslot += type2size[bt]; | |
1546 } | |
1547 assert(argument_slot_to_argnum(method_type, argslot) == arg, "inverse works"); | |
1548 return argslot; | |
1549 } | |
1550 | |
1551 // Given a slot number, return the argument number. | |
1552 int MethodHandles::argument_slot_to_argnum(oop method_type, int query_argslot) { | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1553 objArrayOop ptypes = java_lang_invoke_MethodType::ptypes(method_type); |
710 | 1554 int argslot = 0; |
1555 int len = ptypes->length(); | |
1556 for (int i = len-1; i >= 0; i--) { | |
1557 if (query_argslot == argslot) return i; | |
1558 BasicType bt = java_lang_Class::as_BasicType(ptypes->obj_at(i)); | |
1559 argslot += type2size[bt]; | |
1560 } | |
1561 // return pseudo-arg deepest in stack: | |
1562 if (query_argslot == argslot) return -1; | |
1563 return -99; // oob slot, or splitting a double-slot arg | |
1564 } | |
1565 | |
1566 methodHandle MethodHandles::dispatch_decoded_method(methodHandle m, | |
1567 KlassHandle receiver_limit, | |
1568 int decode_flags, | |
1569 KlassHandle receiver_klass, | |
1570 TRAPS) { | |
1571 assert((decode_flags & ~_DMF_DIRECT_MASK) == 0, "must be direct method reference"); | |
1572 assert((decode_flags & _dmf_has_receiver) != 0, "must have a receiver or first reference argument"); | |
1573 | |
1574 if (!m->is_static() && | |
1575 (receiver_klass.is_null() || !receiver_klass->is_subtype_of(m->method_holder()))) | |
1576 // given type does not match class of method, or receiver is null! | |
1577 // caller should have checked this, but let's be extra careful... | |
1578 return methodHandle(); | |
1579 | |
1580 if (receiver_limit.not_null() && | |
1581 (receiver_klass.not_null() && !receiver_klass->is_subtype_of(receiver_limit()))) | |
1582 // given type is not limited to the receiver type | |
1583 // note that a null receiver can match any reference value, for a static method | |
1584 return methodHandle(); | |
1585 | |
1586 if (!(decode_flags & MethodHandles::_dmf_does_dispatch)) { | |
1587 // pre-dispatched or static method (null receiver is OK for static) | |
1588 return m; | |
1589 | |
1590 } else if (receiver_klass.is_null()) { | |
1591 // null receiver value; cannot dispatch | |
1592 return methodHandle(); | |
1593 | |
1594 } else if (!(decode_flags & MethodHandles::_dmf_from_interface)) { | |
1595 // perform virtual dispatch | |
1596 int vtable_index = m->vtable_index(); | |
1597 guarantee(vtable_index >= 0, "valid vtable index"); | |
1598 | |
1599 // receiver_klass might be an arrayKlassOop but all vtables start at | |
1600 // the same place. The cast is to avoid virtual call and assertion. | |
1601 // See also LinkResolver::runtime_resolve_virtual_method. | |
1602 instanceKlass* inst = (instanceKlass*)Klass::cast(receiver_klass()); | |
1603 DEBUG_ONLY(inst->verify_vtable_index(vtable_index)); | |
1604 methodOop m_oop = inst->method_at_vtable(vtable_index); | |
1605 return methodHandle(THREAD, m_oop); | |
1606 | |
1607 } else { | |
1608 // perform interface dispatch | |
1609 int itable_index = klassItable::compute_itable_index(m()); | |
1610 guarantee(itable_index >= 0, "valid itable index"); | |
1611 instanceKlass* inst = instanceKlass::cast(receiver_klass()); | |
1612 methodOop m_oop = inst->method_at_itable(m->method_holder(), itable_index, THREAD); | |
1613 return methodHandle(THREAD, m_oop); | |
1614 } | |
1615 } | |
1616 | |
1617 void MethodHandles::verify_DirectMethodHandle(Handle mh, methodHandle m, TRAPS) { | |
1618 // Verify type. | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1619 Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(mh())); |
710 | 1620 verify_method_type(m, mtype, false, KlassHandle(), CHECK); |
1621 | |
1622 // Verify vmslots. | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1623 if (java_lang_invoke_MethodHandle::vmslots(mh()) != m->size_of_parameters()) { |
710 | 1624 THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in DMH"); |
1625 } | |
1626 } | |
1627 | |
1628 void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_dispatch, TRAPS) { | |
1629 // Check arguments. | |
1630 if (mh.is_null() || m.is_null() || | |
1631 (!do_dispatch && m->is_abstract())) { | |
1632 THROW(vmSymbols::java_lang_InternalError()); | |
1633 } | |
1634 | |
1635 if (VerifyMethodHandles) { | |
1636 // The privileged code which invokes this routine should not make | |
1637 // a mistake about types, but it's better to verify. | |
1638 verify_DirectMethodHandle(mh, m, CHECK); | |
1639 } | |
1640 | |
1641 // Finally, after safety checks are done, link to the target method. | |
1642 // We will follow the same path as the latter part of | |
1643 // InterpreterRuntime::resolve_invoke(), which first finds the method | |
1644 // and then decides how to populate the constant pool cache entry | |
1645 // that links the interpreter calls to the method. We need the same | |
1646 // bits, and will use the same calling sequence code. | |
1647 | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1648 int vmindex = methodOopDesc::garbage_vtable_index; |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1649 Handle vmtarget; |
710 | 1650 |
1651 instanceKlass::cast(m->method_holder())->link_class(CHECK); | |
1652 | |
1653 MethodHandleEntry* me = NULL; | |
1654 if (do_dispatch && Klass::cast(m->method_holder())->is_interface()) { | |
1655 // We are simulating an invokeinterface instruction. | |
1656 // (We might also be simulating an invokevirtual on a miranda method, | |
1657 // but it is safe to treat it as an invokeinterface.) | |
1658 assert(!m->can_be_statically_bound(), "no final methods on interfaces"); | |
1659 vmindex = klassItable::compute_itable_index(m()); | |
1660 assert(vmindex >= 0, "(>=0) == do_dispatch"); | |
1661 // Set up same bits as ConstantPoolCacheEntry::set_interface_call(). | |
1662 vmtarget = m->method_holder(); // the interface | |
1663 me = MethodHandles::entry(MethodHandles::_invokeinterface_mh); | |
1664 } else if (!do_dispatch || m->can_be_statically_bound()) { | |
1665 // We are simulating an invokestatic or invokespecial instruction. | |
1666 // Set up the method pointer, just like ConstantPoolCacheEntry::set_method(). | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1667 vmtarget = m; |
710 | 1668 // this does not help dispatch, but it will make it possible to parse this MH: |
1669 vmindex = methodOopDesc::nonvirtual_vtable_index; | |
1670 assert(vmindex < 0, "(>=0) == do_dispatch"); | |
1671 if (!m->is_static()) { | |
1672 me = MethodHandles::entry(MethodHandles::_invokespecial_mh); | |
1673 } else { | |
1674 me = MethodHandles::entry(MethodHandles::_invokestatic_mh); | |
1675 // Part of the semantics of a static call is an initialization barrier. | |
1676 // For a DMH, it is done now, when the handle is created. | |
1677 Klass* k = Klass::cast(m->method_holder()); | |
1678 if (k->should_be_initialized()) { | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1679 k->initialize(CHECK); // possible safepoint |
710 | 1680 } |
1681 } | |
1682 } else { | |
1683 // We are simulating an invokevirtual instruction. | |
1684 // Set up the vtable index, just like ConstantPoolCacheEntry::set_method(). | |
1685 // The key logic is LinkResolver::runtime_resolve_virtual_method. | |
1686 vmindex = m->vtable_index(); | |
1687 vmtarget = m->method_holder(); | |
1688 me = MethodHandles::entry(MethodHandles::_invokevirtual_mh); | |
1689 } | |
1690 | |
1691 if (me == NULL) { THROW(vmSymbols::java_lang_InternalError()); } | |
1692 | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1693 java_lang_invoke_DirectMethodHandle::set_vmtarget(mh(), vmtarget()); |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1694 java_lang_invoke_DirectMethodHandle::set_vmindex( mh(), vmindex); |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1695 DEBUG_ONLY(KlassHandle rlimit; int flags); |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1696 assert(MethodHandles::decode_method(mh(), rlimit, flags) == m, |
710 | 1697 "properly stored for later decoding"); |
1698 DEBUG_ONLY(bool actual_do_dispatch = ((flags & _dmf_does_dispatch) != 0)); | |
1699 assert(!(actual_do_dispatch && !do_dispatch), | |
1700 "do not perform dispatch if !do_dispatch specified"); | |
1701 assert(actual_do_dispatch == (vmindex >= 0), "proper later decoding of do_dispatch"); | |
1702 assert(decode_MethodHandle_stack_pushes(mh()) == 0, "DMH does not move stack"); | |
1703 | |
1704 // Done! | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1705 java_lang_invoke_MethodHandle::set_vmentry(mh(), me); |
710 | 1706 } |
1707 | |
1708 void MethodHandles::verify_BoundMethodHandle_with_receiver(Handle mh, | |
1709 methodHandle m, | |
1710 TRAPS) { | |
1711 // Verify type. | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1712 KlassHandle bound_recv_type; |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1713 { |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1714 oop receiver = java_lang_invoke_BoundMethodHandle::argument(mh()); |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1715 if (receiver != NULL) |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1716 bound_recv_type = KlassHandle(THREAD, receiver->klass()); |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1717 } |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1718 Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(mh())); |
710 | 1719 verify_method_type(m, mtype, true, bound_recv_type, CHECK); |
1720 | |
1721 int receiver_pos = m->size_of_parameters() - 1; | |
1722 | |
1723 // Verify MH.vmargslot, which should point at the bound receiver. | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1724 verify_vmargslot(mh, -1, java_lang_invoke_BoundMethodHandle::vmargslot(mh()), CHECK); |
710 | 1725 //verify_vmslots(mh, CHECK); |
1726 | |
1727 // Verify vmslots. | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1728 if (java_lang_invoke_MethodHandle::vmslots(mh()) != receiver_pos) { |
710 | 1729 THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in BMH (receiver)"); |
1730 } | |
1731 } | |
1732 | |
1733 // Initialize a BMH with a receiver bound directly to a methodOop. | |
1734 void MethodHandles::init_BoundMethodHandle_with_receiver(Handle mh, | |
1735 methodHandle original_m, | |
1736 KlassHandle receiver_limit, | |
1737 int decode_flags, | |
1738 TRAPS) { | |
1739 // Check arguments. | |
1740 if (mh.is_null() || original_m.is_null()) { | |
1741 THROW(vmSymbols::java_lang_InternalError()); | |
1742 } | |
1743 | |
1744 KlassHandle receiver_klass; | |
1745 { | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1746 oop receiver_oop = java_lang_invoke_BoundMethodHandle::argument(mh()); |
710 | 1747 if (receiver_oop != NULL) |
1748 receiver_klass = KlassHandle(THREAD, receiver_oop->klass()); | |
1749 } | |
1750 methodHandle m = dispatch_decoded_method(original_m, | |
1751 receiver_limit, decode_flags, | |
1752 receiver_klass, | |
1753 CHECK); | |
1754 if (m.is_null()) { THROW(vmSymbols::java_lang_InternalError()); } | |
1755 if (m->is_abstract()) { THROW(vmSymbols::java_lang_AbstractMethodError()); } | |
1756 | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
1757 int vmargslot = m->size_of_parameters() - 1; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
1758 assert(java_lang_invoke_BoundMethodHandle::vmargslot(mh()) == vmargslot, ""); |
710 | 1759 |
1760 if (VerifyMethodHandles) { | |
1761 verify_BoundMethodHandle_with_receiver(mh, m, CHECK); | |
1762 } | |
1763 | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1764 java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), m()); |
710 | 1765 |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1766 DEBUG_ONLY(KlassHandle junk1; int junk2); |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1767 assert(MethodHandles::decode_method(mh(), junk1, junk2) == m, "properly stored for later decoding"); |
710 | 1768 assert(decode_MethodHandle_stack_pushes(mh()) == 1, "BMH pushes one stack slot"); |
1769 | |
1770 // Done! | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1771 java_lang_invoke_MethodHandle::set_vmentry(mh(), MethodHandles::entry(MethodHandles::_bound_ref_direct_mh)); |
710 | 1772 } |
1773 | |
1774 void MethodHandles::verify_BoundMethodHandle(Handle mh, Handle target, int argnum, | |
1775 bool direct_to_method, TRAPS) { | |
3753
cba7b5c2d53f
7045514: SPARC assembly code for JSR 292 ricochet frames
never
parents:
3744
diff
changeset
|
1776 ResourceMark rm; |
710 | 1777 Handle ptype_handle(THREAD, |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1778 java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum)); |
710 | 1779 KlassHandle ptype_klass; |
1780 BasicType ptype = java_lang_Class::as_BasicType(ptype_handle(), &ptype_klass); | |
1781 int slots_pushed = type2size[ptype]; | |
1782 | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1783 oop argument = java_lang_invoke_BoundMethodHandle::argument(mh()); |
710 | 1784 |
1785 const char* err = NULL; | |
1786 | |
1787 switch (ptype) { | |
1788 case T_OBJECT: | |
1789 if (argument != NULL) | |
1790 // we must implicitly convert from the arg type to the outgoing ptype | |
1791 err = check_argument_type_change(T_OBJECT, argument->klass(), ptype, ptype_klass(), argnum); | |
1792 break; | |
1793 | |
1794 case T_ARRAY: case T_VOID: | |
1795 assert(false, "array, void do not appear here"); | |
1796 default: | |
1797 if (ptype != T_INT && !is_subword_type(ptype)) { | |
1798 err = "unexpected parameter type"; | |
1799 break; | |
1800 } | |
1801 // check subrange of Integer.value, if necessary | |
1142 | 1802 if (argument == NULL || argument->klass() != SystemDictionary::Integer_klass()) { |
710 | 1803 err = "bound integer argument must be of type java.lang.Integer"; |
1804 break; | |
1805 } | |
1806 if (ptype != T_INT) { | |
1807 int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_INT); | |
1808 jint value = argument->int_field(value_offset); | |
1849
5beba6174298
6987555: JSR 292 unboxing to a boolean value fails on big-endian SPARC
twisti
parents:
1748
diff
changeset
|
1809 int vminfo = adapter_unbox_subword_vminfo(ptype); |
710 | 1810 jint subword = truncate_subword_from_vminfo(value, vminfo); |
1811 if (value != subword) { | |
1812 err = "bound subword value does not fit into the subword type"; | |
1813 break; | |
1814 } | |
1815 } | |
1816 break; | |
1817 case T_FLOAT: | |
1818 case T_DOUBLE: | |
1819 case T_LONG: | |
1820 { | |
1821 // we must implicitly convert from the unboxed arg type to the outgoing ptype | |
1822 BasicType argbox = java_lang_boxing_object::basic_type(argument); | |
1823 if (argbox != ptype) { | |
1824 err = check_argument_type_change(T_OBJECT, (argument == NULL | |
1142 | 1825 ? SystemDictionary::Object_klass() |
710 | 1826 : argument->klass()), |
1827 ptype, ptype_klass(), argnum); | |
1828 assert(err != NULL, "this must be an error"); | |
1829 } | |
1830 break; | |
1831 } | |
1832 } | |
1833 | |
1834 if (err == NULL) { | |
1835 DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh())); | |
1836 if (direct_to_method) { | |
1837 assert(this_pushes == slots_pushed, "BMH pushes one or two stack slots"); | |
1838 } else { | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1839 int target_pushes = decode_MethodHandle_stack_pushes(target()); |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
1840 assert(this_pushes == slots_pushed + target_pushes, "BMH stack motion must be correct"); |
710 | 1841 } |
1842 } | |
1843 | |
1844 if (err == NULL) { | |
1845 // Verify the rest of the method type. | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1846 err = check_method_type_insertion(java_lang_invoke_MethodHandle::type(mh()), |
710 | 1847 argnum, ptype_handle(), |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1848 java_lang_invoke_MethodHandle::type(target())); |
710 | 1849 } |
1850 | |
1851 if (err != NULL) { | |
1852 THROW_MSG(vmSymbols::java_lang_InternalError(), err); | |
1853 } | |
1854 } | |
1855 | |
1856 void MethodHandles::init_BoundMethodHandle(Handle mh, Handle target, int argnum, TRAPS) { | |
1857 // Check arguments. | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1858 if (mh.is_null() || target.is_null() || !java_lang_invoke_MethodHandle::is_instance(target())) { |
710 | 1859 THROW(vmSymbols::java_lang_InternalError()); |
1860 } | |
1861 | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
1862 int argslot = java_lang_invoke_BoundMethodHandle::vmargslot(mh()); |
710 | 1863 |
1864 if (VerifyMethodHandles) { | |
1865 int insert_after = argnum - 1; | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
1866 verify_vmargslot(mh, insert_after, argslot, CHECK); |
710 | 1867 verify_vmslots(mh, CHECK); |
1868 } | |
1869 | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
1870 // Get bound type and required slots. |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1871 BasicType ptype; |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1872 { |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1873 oop ptype_oop = java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum); |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1874 ptype = java_lang_Class::as_BasicType(ptype_oop); |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1875 } |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
1876 int slots_pushed = type2size[ptype]; |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
1877 |
710 | 1878 // If (a) the target is a direct non-dispatched method handle, |
1879 // or (b) the target is a dispatched direct method handle and we | |
1880 // are binding the receiver, cut out the middle-man. | |
1881 // Do this by decoding the DMH and using its methodOop directly as vmtarget. | |
1882 bool direct_to_method = false; | |
1883 if (OptimizeMethodHandles && | |
1884 target->klass() == SystemDictionary::DirectMethodHandle_klass() && | |
3740
5ac411b3b8fc
7047961: JSR 292 MethodHandleWalk swap args doesn't handle T_LONG and T_DOUBLE properly
never
parents:
3389
diff
changeset
|
1885 (argnum != 0 || java_lang_invoke_BoundMethodHandle::argument(mh()) != NULL) && |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1886 (argnum == 0 || java_lang_invoke_DirectMethodHandle::vmindex(target()) < 0)) { |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1887 KlassHandle receiver_limit; int decode_flags = 0; |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
1888 methodHandle m = decode_method(target(), receiver_limit, decode_flags); |
710 | 1889 if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "DMH failed to decode"); } |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
1890 DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - slots_pushed); // pos. of 1st arg. |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1891 assert(java_lang_invoke_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig"); |
710 | 1892 if (argnum == 0 && (decode_flags & _dmf_has_receiver) != 0) { |
1893 init_BoundMethodHandle_with_receiver(mh, m, | |
1894 receiver_limit, decode_flags, | |
1895 CHECK); | |
1896 return; | |
1897 } | |
1898 | |
1899 // Even if it is not a bound receiver, we still might be able | |
1900 // to bind another argument and still invoke the methodOop directly. | |
1901 if (!(decode_flags & _dmf_does_dispatch)) { | |
1902 direct_to_method = true; | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1903 java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), m()); |
710 | 1904 } |
1905 } | |
1906 if (!direct_to_method) | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1907 java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), target()); |
710 | 1908 |
1909 if (VerifyMethodHandles) { | |
1910 verify_BoundMethodHandle(mh, target, argnum, direct_to_method, CHECK); | |
1911 } | |
1912 | |
1913 // Next question: Is this a ref, int, or long bound value? | |
1914 MethodHandleEntry* me = NULL; | |
1915 if (ptype == T_OBJECT) { | |
1916 if (direct_to_method) me = MethodHandles::entry(_bound_ref_direct_mh); | |
1917 else me = MethodHandles::entry(_bound_ref_mh); | |
1918 } else if (slots_pushed == 2) { | |
1919 if (direct_to_method) me = MethodHandles::entry(_bound_long_direct_mh); | |
1920 else me = MethodHandles::entry(_bound_long_mh); | |
1921 } else if (slots_pushed == 1) { | |
1922 if (direct_to_method) me = MethodHandles::entry(_bound_int_direct_mh); | |
1923 else me = MethodHandles::entry(_bound_int_mh); | |
1924 } else { | |
1925 assert(false, ""); | |
1926 } | |
1927 | |
1928 // Done! | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1929 java_lang_invoke_MethodHandle::set_vmentry(mh(), me); |
710 | 1930 } |
1931 | |
1932 static void throw_InternalError_for_bad_conversion(int conversion, const char* err, TRAPS) { | |
1933 char msg[200]; | |
1934 jio_snprintf(msg, sizeof(msg), "bad adapter (conversion=0x%08x): %s", conversion, err); | |
1935 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), msg); | |
1936 } | |
1937 | |
1938 void MethodHandles::verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS) { | |
3753
cba7b5c2d53f
7045514: SPARC assembly code for JSR 292 ricochet frames
never
parents:
3744
diff
changeset
|
1939 ResourceMark rm; |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1940 jint conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh()); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1941 int argslot = java_lang_invoke_AdapterMethodHandle::vmargslot(mh()); |
710 | 1942 |
1943 verify_vmargslot(mh, argnum, argslot, CHECK); | |
1944 verify_vmslots(mh, CHECK); | |
1945 | |
1946 jint conv_op = adapter_conversion_op(conversion); | |
1947 if (!conv_op_valid(conv_op)) { | |
1948 throw_InternalError_for_bad_conversion(conversion, "unknown conversion op", THREAD); | |
1949 return; | |
1950 } | |
1951 EntryKind ek = adapter_entry_kind(conv_op); | |
1952 | |
1953 int stack_move = adapter_conversion_stack_move(conversion); | |
1954 BasicType src = adapter_conversion_src_type(conversion); | |
1955 BasicType dest = adapter_conversion_dest_type(conversion); | |
1956 int vminfo = adapter_conversion_vminfo(conversion); // should be zero | |
1957 | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1958 Handle argument(THREAD, java_lang_invoke_AdapterMethodHandle::argument(mh())); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1959 Handle target(THREAD, java_lang_invoke_AdapterMethodHandle::vmtarget(mh())); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1960 Handle src_mtype(THREAD, java_lang_invoke_MethodHandle::type(mh())); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1961 Handle dst_mtype(THREAD, java_lang_invoke_MethodHandle::type(target())); |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
1962 Handle arg_mtype; |
710 | 1963 |
1964 const char* err = NULL; | |
1965 | |
1966 if (err == NULL) { | |
1967 // Check that the correct argument is supplied, but only if it is required. | |
1968 switch (ek) { | |
1969 case _adapter_check_cast: // target type of cast | |
1970 case _adapter_ref_to_prim: // wrapper type from which to unbox | |
1971 case _adapter_spread_args: // array type to spread from | |
1972 if (!java_lang_Class::is_instance(argument()) | |
1973 || java_lang_Class::is_primitive(argument())) | |
1974 { err = "adapter requires argument of type java.lang.Class"; break; } | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
1975 if (ek == _adapter_spread_args) { |
710 | 1976 // Make sure it is a suitable collection type. (Array, for now.) |
1977 Klass* ak = Klass::cast(java_lang_Class::as_klassOop(argument())); | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
1978 if (!ak->oop_is_array()) |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
1979 { err = "spread adapter requires argument representing an array class"; break; } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
1980 BasicType et = arrayKlass::cast(ak->as_klassOop())->element_type(); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
1981 if (et != dest && stack_move <= 0) |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
1982 { err = "spread adapter requires array class argument of correct type"; break; } |
710 | 1983 } |
1984 break; | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
1985 case _adapter_prim_to_ref: // boxer MH to use |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
1986 case _adapter_collect_args: // method handle which collects the args |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
1987 case _adapter_fold_args: // method handle which collects the args |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
1988 if (!UseRicochetFrames) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
1989 { err = "box/collect/fold operators are not supported"; break; } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
1990 } |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1991 if (!java_lang_invoke_MethodHandle::is_instance(argument())) |
710 | 1992 { err = "MethodHandle adapter argument required"; break; } |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
1993 arg_mtype = Handle(THREAD, java_lang_invoke_MethodHandle::type(argument())); |
710 | 1994 break; |
1995 default: | |
1996 if (argument.not_null()) | |
1997 { err = "adapter has spurious argument"; break; } | |
1998 break; | |
1999 } | |
2000 } | |
2001 | |
2002 if (err == NULL) { | |
2003 // Check that the src/dest types are supplied if needed. | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2004 // Also check relevant parameter or return types. |
710 | 2005 switch (ek) { |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
2006 case _adapter_check_cast: |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
2007 if (src != T_OBJECT || dest != T_OBJECT) { |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
2008 err = "adapter requires object src/dest conversion subfields"; |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
2009 } |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
2010 break; |
710 | 2011 case _adapter_prim_to_prim: |
2012 if (!is_java_primitive(src) || !is_java_primitive(dest) || src == dest) { | |
2013 err = "adapter requires primitive src/dest conversion subfields"; break; | |
2014 } | |
2015 if ( (src == T_FLOAT || src == T_DOUBLE) && !(dest == T_FLOAT || dest == T_DOUBLE) || | |
2016 !(src == T_FLOAT || src == T_DOUBLE) && (dest == T_FLOAT || dest == T_DOUBLE)) { | |
2017 err = "adapter cannot convert beween floating and fixed-point"; break; | |
2018 } | |
2019 break; | |
2020 case _adapter_ref_to_prim: | |
2021 if (src != T_OBJECT || !is_java_primitive(dest) | |
2022 || argument() != Klass::cast(SystemDictionary::box_klass(dest))->java_mirror()) { | |
2023 err = "adapter requires primitive dest conversion subfield"; break; | |
2024 } | |
2025 break; | |
2026 case _adapter_prim_to_ref: | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2027 if (!is_java_primitive(src) || dest != T_OBJECT) { |
710 | 2028 err = "adapter requires primitive src conversion subfield"; break; |
2029 } | |
2030 break; | |
2031 case _adapter_swap_args: | |
2032 { | |
3757
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2033 if (!src || !dest) { |
710 | 2034 err = "adapter requires src/dest conversion subfields for swap"; break; |
2035 } | |
3757
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2036 int src_size = type2size[src]; |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2037 if (src_size != type2size[dest]) { |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2038 err = "adapter requires equal sizes for src/dest"; break; |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2039 } |
710 | 2040 int src_slot = argslot; |
2041 int dest_slot = vminfo; | |
2042 int src_arg = argnum; | |
3757
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2043 int dest_arg = argument_slot_to_argnum(src_mtype(), dest_slot); |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2044 verify_vmargslot(mh, dest_arg, dest_slot, CHECK); |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2045 if (!(dest_slot >= src_slot + src_size) && |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2046 !(src_slot >= dest_slot + src_size)) { |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2047 err = "source, destination slots must be distinct"; break; |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2048 } else if (!(src_slot > dest_slot)) { |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2049 err = "source of swap must be deeper in stack"; break; |
710 | 2050 } |
3757
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2051 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), dest_arg), |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2052 java_lang_invoke_MethodType::ptype(dst_mtype(), src_arg), |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2053 dest_arg); |
710 | 2054 if (err == NULL) |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2055 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), src_arg), |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2056 java_lang_invoke_MethodType::ptype(dst_mtype(), dest_arg), |
710 | 2057 src_arg); |
3757
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2058 break; |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2059 } |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2060 case _adapter_rot_args: |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2061 { |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2062 if (!src || !dest) { |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2063 err = "adapter requires src/dest conversion subfields for rotate"; break; |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2064 } |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2065 int src_slot = argslot; |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2066 int limit_raw = vminfo; |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2067 bool rot_down = (src_slot < limit_raw); |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2068 int limit_bias = (rot_down ? MethodHandles::OP_ROT_ARGS_DOWN_LIMIT_BIAS : 0); |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2069 int limit_slot = limit_raw - limit_bias; |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2070 int src_arg = argnum; |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2071 int limit_arg = argument_slot_to_argnum(src_mtype(), limit_slot); |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2072 verify_vmargslot(mh, limit_arg, limit_slot, CHECK); |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2073 if (src_slot == limit_slot) { |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2074 err = "source, destination slots must be distinct"; break; |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2075 } |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2076 if (!rot_down) { // rotate slots up == shift arguments left |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2077 // limit_slot is an inclusive lower limit |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2078 assert((src_slot > limit_slot) && (src_arg < limit_arg), ""); |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2079 // rotate up: [limit_slot..src_slot-ss] --> [limit_slot+ss..src_slot] |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2080 // that is: [src_arg+1..limit_arg] --> [src_arg..limit_arg-1] |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2081 for (int i = src_arg+1; i <= limit_arg && err == NULL; i++) { |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2082 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), i), |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2083 java_lang_invoke_MethodType::ptype(dst_mtype(), i-1), |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2084 i); |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2085 } |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2086 } else { // rotate slots down == shfit arguments right |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2087 // limit_slot is an exclusive upper limit |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2088 assert((src_slot < limit_slot - limit_bias) && (src_arg > limit_arg + limit_bias), ""); |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2089 // rotate down: [src_slot+ss..limit_slot) --> [src_slot..limit_slot-ss) |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2090 // that is: (limit_arg..src_arg-1] --> (dst_arg+1..src_arg] |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2091 for (int i = limit_arg+1; i <= src_arg-1 && err == NULL; i++) { |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2092 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), i), |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2093 java_lang_invoke_MethodType::ptype(dst_mtype(), i+1), |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2094 i); |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2095 } |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2096 } |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2097 if (err == NULL) { |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2098 int dest_arg = (rot_down ? limit_arg+1 : limit_arg); |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2099 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), src_arg), |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2100 java_lang_invoke_MethodType::ptype(dst_mtype(), dest_arg), |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2101 src_arg); |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2102 } |
710 | 2103 } |
2104 break; | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2105 case _adapter_spread_args: |
710 | 2106 case _adapter_collect_args: |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2107 case _adapter_fold_args: |
710 | 2108 { |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2109 bool is_spread = (ek == _adapter_spread_args); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2110 bool is_fold = (ek == _adapter_fold_args); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2111 BasicType coll_type = is_spread ? src : dest; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2112 BasicType elem_type = is_spread ? dest : src; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2113 // coll_type is type of args in collected form (or T_VOID if none) |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2114 // elem_type is common type of args in spread form (or T_VOID if missing or heterogeneous) |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2115 if (coll_type == 0 || elem_type == 0) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2116 err = "adapter requires src/dest subfields for spread or collect"; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2117 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2118 if (is_spread && coll_type != T_OBJECT) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2119 err = "spread adapter requires object type for argument bundle"; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2120 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2121 Handle spread_mtype = (is_spread ? dst_mtype : src_mtype); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2122 int spread_slot = argslot; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2123 int spread_arg = argnum; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2124 int slots_pushed = stack_move / stack_move_unit(); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2125 int coll_slot_count = type2size[coll_type]; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2126 int spread_slot_count = (is_spread ? slots_pushed : -slots_pushed) + coll_slot_count; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2127 if (is_fold) spread_slot_count = argument_slot_count(arg_mtype()); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2128 if (!is_spread) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2129 int init_slots = argument_slot_count(src_mtype()); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2130 int coll_slots = argument_slot_count(arg_mtype()); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2131 if (spread_slot_count > init_slots || |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2132 spread_slot_count != coll_slots) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2133 err = "collect adapter has inconsistent arg counts"; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2134 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2135 int next_slots = argument_slot_count(dst_mtype()); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2136 int unchanged_slots_in = (init_slots - spread_slot_count); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2137 int unchanged_slots_out = (next_slots - coll_slot_count - (is_fold ? spread_slot_count : 0)); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2138 if (unchanged_slots_in != unchanged_slots_out) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2139 err = "collect adapter continuation has inconsistent arg counts"; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2140 } |
710 | 2141 } |
2142 } | |
2143 break; | |
2144 default: | |
2145 if (src != 0 || dest != 0) { | |
2146 err = "adapter has spurious src/dest conversion subfields"; break; | |
2147 } | |
2148 break; | |
2149 } | |
2150 } | |
2151 | |
2152 if (err == NULL) { | |
2153 // Check the stack_move subfield. | |
2154 // It must always report the net change in stack size, positive or negative. | |
2155 int slots_pushed = stack_move / stack_move_unit(); | |
2156 switch (ek) { | |
2157 case _adapter_prim_to_prim: | |
2158 case _adapter_ref_to_prim: | |
2159 case _adapter_prim_to_ref: | |
2160 if (slots_pushed != type2size[dest] - type2size[src]) { | |
2161 err = "wrong stack motion for primitive conversion"; | |
2162 } | |
2163 break; | |
2164 case _adapter_dup_args: | |
2165 if (slots_pushed <= 0) { | |
2166 err = "adapter requires conversion subfield slots_pushed > 0"; | |
2167 } | |
2168 break; | |
2169 case _adapter_drop_args: | |
2170 if (slots_pushed >= 0) { | |
2171 err = "adapter requires conversion subfield slots_pushed < 0"; | |
2172 } | |
2173 break; | |
2174 case _adapter_collect_args: | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2175 case _adapter_fold_args: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2176 if (slots_pushed > 2) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2177 err = "adapter requires conversion subfield slots_pushed <= 2"; |
710 | 2178 } |
2179 break; | |
2180 case _adapter_spread_args: | |
2181 if (slots_pushed < -1) { | |
2182 err = "adapter requires conversion subfield slots_pushed >= -1"; | |
2183 } | |
2184 break; | |
2185 default: | |
2186 if (stack_move != 0) { | |
2187 err = "adapter has spurious stack_move conversion subfield"; | |
2188 } | |
2189 break; | |
2190 } | |
2191 if (err == NULL && stack_move != slots_pushed * stack_move_unit()) { | |
2192 err = "stack_move conversion subfield must be multiple of stack_move_unit"; | |
2193 } | |
2194 } | |
2195 | |
2196 if (err == NULL) { | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2197 // Make sure this adapter's stack pushing is accurately recorded. |
710 | 2198 int slots_pushed = stack_move / stack_move_unit(); |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2199 int this_vmslots = java_lang_invoke_MethodHandle::vmslots(mh()); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2200 int target_vmslots = java_lang_invoke_MethodHandle::vmslots(target()); |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2201 int target_pushes = decode_MethodHandle_stack_pushes(target()); |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
2202 if (slots_pushed != (target_vmslots - this_vmslots)) { |
710 | 2203 err = "stack_move inconsistent with previous and current MethodType vmslots"; |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2204 } else { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2205 int this_pushes = decode_MethodHandle_stack_pushes(mh()); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2206 if (slots_pushed + target_pushes != this_pushes) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2207 if (this_pushes == 0) |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2208 err = "adapter push count not initialized"; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2209 else |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2210 err = "adapter push count is wrong"; |
710 | 2211 } |
2212 } | |
2213 | |
2214 // While we're at it, check that the stack motion decoder works: | |
2215 DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh())); | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
2216 assert(this_pushes == slots_pushed + target_pushes, "AMH stack motion must be correct"); |
710 | 2217 } |
2218 | |
2219 if (err == NULL && vminfo != 0) { | |
2220 switch (ek) { | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2221 case _adapter_swap_args: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2222 case _adapter_rot_args: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2223 case _adapter_prim_to_ref: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2224 case _adapter_collect_args: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2225 case _adapter_fold_args: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2226 break; // OK |
710 | 2227 default: |
2228 err = "vminfo subfield is reserved to the JVM"; | |
2229 } | |
2230 } | |
2231 | |
2232 // Do additional ad hoc checks. | |
2233 if (err == NULL) { | |
2234 switch (ek) { | |
2235 case _adapter_retype_only: | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
2236 err = check_method_type_passthrough(src_mtype(), dst_mtype(), false); |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
2237 break; |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
2238 |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
2239 case _adapter_retype_raw: |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
2240 err = check_method_type_passthrough(src_mtype(), dst_mtype(), true); |
710 | 2241 break; |
2242 | |
2243 case _adapter_check_cast: | |
2244 { | |
2245 // The actual value being checked must be a reference: | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2246 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), argnum), |
710 | 2247 object_java_mirror(), argnum); |
2248 if (err != NULL) break; | |
2249 | |
2250 // The output of the cast must fit with the destination argument: | |
2251 Handle cast_class = argument; | |
2252 err = check_method_type_conversion(src_mtype(), | |
2253 argnum, cast_class(), | |
2254 dst_mtype()); | |
2255 } | |
2256 break; | |
2257 | |
2258 // %%% TO DO: continue in remaining cases to verify src/dst_mtype if VerifyMethodHandles | |
2259 } | |
2260 } | |
2261 | |
2262 if (err != NULL) { | |
2263 throw_InternalError_for_bad_conversion(conversion, err, THREAD); | |
2264 return; | |
2265 } | |
2266 | |
2267 } | |
2268 | |
2269 void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) { | |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2270 Handle argument = java_lang_invoke_AdapterMethodHandle::argument(mh()); |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2271 int argslot = java_lang_invoke_AdapterMethodHandle::vmargslot(mh()); |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2272 jint conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh()); |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2273 jint conv_op = adapter_conversion_op(conversion); |
710 | 2274 |
2275 // adjust the adapter code to the internal EntryKind enumeration: | |
2276 EntryKind ek_orig = adapter_entry_kind(conv_op); | |
2277 EntryKind ek_opt = ek_orig; // may be optimized | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2278 EntryKind ek_try; // temp |
710 | 2279 |
2280 // Finalize the vmtarget field (Java initialized it to null). | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2281 if (!java_lang_invoke_MethodHandle::is_instance(target())) { |
710 | 2282 throw_InternalError_for_bad_conversion(conversion, "bad target", THREAD); |
2283 return; | |
2284 } | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2285 java_lang_invoke_AdapterMethodHandle::set_vmtarget(mh(), target()); |
710 | 2286 |
2287 int stack_move = adapter_conversion_stack_move(conversion); | |
2288 BasicType src = adapter_conversion_src_type(conversion); | |
2289 BasicType dest = adapter_conversion_dest_type(conversion); | |
2290 int vminfo = adapter_conversion_vminfo(conversion); // should be zero | |
2291 | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2292 int slots_pushed = stack_move / stack_move_unit(); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2293 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2294 if (VerifyMethodHandles) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2295 verify_AdapterMethodHandle(mh, argnum, CHECK); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2296 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2297 |
710 | 2298 const char* err = NULL; |
2299 | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2300 if (!conv_op_supported(conv_op)) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2301 err = "adapter not yet implemented in the JVM"; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2302 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2303 |
710 | 2304 // Now it's time to finish the case analysis and pick a MethodHandleEntry. |
2305 switch (ek_orig) { | |
2306 case _adapter_retype_only: | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
2307 case _adapter_retype_raw: |
710 | 2308 case _adapter_check_cast: |
2309 case _adapter_dup_args: | |
2310 case _adapter_drop_args: | |
2311 // these work fine via general case code | |
2312 break; | |
2313 | |
2314 case _adapter_prim_to_prim: | |
2315 { | |
2316 // Non-subword cases are {int,float,long,double} -> {int,float,long,double}. | |
2317 // And, the {float,double} -> {int,long} cases must be handled by Java. | |
2318 switch (type2size[src] *4+ type2size[dest]) { | |
2319 case 1 *4+ 1: | |
2320 assert(src == T_INT || is_subword_type(src), "source is not float"); | |
2321 // Subword-related cases are int -> {boolean,byte,char,short}. | |
2322 ek_opt = _adapter_opt_i2i; | |
1849
5beba6174298
6987555: JSR 292 unboxing to a boolean value fails on big-endian SPARC
twisti
parents:
1748
diff
changeset
|
2323 vminfo = adapter_prim_to_prim_subword_vminfo(dest); |
710 | 2324 break; |
2325 case 2 *4+ 1: | |
2326 if (src == T_LONG && (dest == T_INT || is_subword_type(dest))) { | |
2327 ek_opt = _adapter_opt_l2i; | |
1849
5beba6174298
6987555: JSR 292 unboxing to a boolean value fails on big-endian SPARC
twisti
parents:
1748
diff
changeset
|
2328 vminfo = adapter_prim_to_prim_subword_vminfo(dest); |
710 | 2329 } else if (src == T_DOUBLE && dest == T_FLOAT) { |
2330 ek_opt = _adapter_opt_d2f; | |
2331 } else { | |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2332 goto throw_not_impl; // runs user code, hence could block |
710 | 2333 } |
2334 break; | |
2335 case 1 *4+ 2: | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2336 if ((src == T_INT || is_subword_type(src)) && dest == T_LONG) { |
710 | 2337 ek_opt = _adapter_opt_i2l; |
2338 } else if (src == T_FLOAT && dest == T_DOUBLE) { | |
2339 ek_opt = _adapter_opt_f2d; | |
2340 } else { | |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2341 goto throw_not_impl; // runs user code, hence could block |
710 | 2342 } |
2343 break; | |
2344 default: | |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2345 goto throw_not_impl; // runs user code, hence could block |
710 | 2346 break; |
2347 } | |
2348 } | |
2349 break; | |
2350 | |
2351 case _adapter_ref_to_prim: | |
2352 { | |
2353 switch (type2size[dest]) { | |
2354 case 1: | |
2355 ek_opt = _adapter_opt_unboxi; | |
1849
5beba6174298
6987555: JSR 292 unboxing to a boolean value fails on big-endian SPARC
twisti
parents:
1748
diff
changeset
|
2356 vminfo = adapter_unbox_subword_vminfo(dest); |
710 | 2357 break; |
2358 case 2: | |
2359 ek_opt = _adapter_opt_unboxl; | |
2360 break; | |
2361 default: | |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2362 goto throw_not_impl; |
710 | 2363 break; |
2364 } | |
2365 } | |
2366 break; | |
2367 | |
2368 case _adapter_prim_to_ref: | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2369 { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2370 assert(UseRicochetFrames, "else don't come here"); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2371 // vminfo will be the location to insert the return value |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2372 vminfo = argslot; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2373 ek_opt = _adapter_opt_collect_ref; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2374 ensure_vmlayout_field(target, CHECK); |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2375 // for MethodHandleWalk: |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2376 if (java_lang_invoke_AdapterMethodHandle::is_instance(argument())) |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2377 ensure_vmlayout_field(argument, CHECK); |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2378 if (!OptimizeMethodHandles) break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2379 switch (type2size[src]) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2380 case 1: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2381 ek_try = EntryKind(_adapter_opt_filter_S0_ref + argslot); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2382 if (ek_try < _adapter_opt_collect_LAST && |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2383 ek_adapter_opt_collect_slot(ek_try) == argslot) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2384 assert(ek_adapter_opt_collect_count(ek_try) == 1 && |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2385 ek_adapter_opt_collect_type(ek_try) == T_OBJECT, ""); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2386 ek_opt = ek_try; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2387 break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2388 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2389 // else downgrade to variable slot: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2390 ek_opt = _adapter_opt_collect_1_ref; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2391 break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2392 case 2: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2393 ek_try = EntryKind(_adapter_opt_collect_2_S0_ref + argslot); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2394 if (ek_try < _adapter_opt_collect_LAST && |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2395 ek_adapter_opt_collect_slot(ek_try) == argslot) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2396 assert(ek_adapter_opt_collect_count(ek_try) == 2 && |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2397 ek_adapter_opt_collect_type(ek_try) == T_OBJECT, ""); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2398 ek_opt = ek_try; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2399 break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2400 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2401 // else downgrade to variable slot: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2402 ek_opt = _adapter_opt_collect_2_ref; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2403 break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2404 default: |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2405 goto throw_not_impl; |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2406 break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2407 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2408 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2409 break; |
710 | 2410 |
2411 case _adapter_swap_args: | |
2412 case _adapter_rot_args: | |
2413 { | |
2414 int swap_slots = type2size[src]; | |
2415 int src_slot = argslot; | |
2416 int dest_slot = vminfo; | |
2417 int rotate = (ek_orig == _adapter_swap_args) ? 0 : (src_slot > dest_slot) ? 1 : -1; | |
2418 switch (swap_slots) { | |
2419 case 1: | |
2420 ek_opt = (!rotate ? _adapter_opt_swap_1 : | |
2421 rotate > 0 ? _adapter_opt_rot_1_up : _adapter_opt_rot_1_down); | |
2422 break; | |
2423 case 2: | |
2424 ek_opt = (!rotate ? _adapter_opt_swap_2 : | |
2425 rotate > 0 ? _adapter_opt_rot_2_up : _adapter_opt_rot_2_down); | |
2426 break; | |
2427 default: | |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2428 goto throw_not_impl; |
710 | 2429 break; |
2430 } | |
2431 } | |
2432 break; | |
2433 | |
2434 case _adapter_spread_args: | |
2435 { | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2436 #ifdef TARGET_ARCH_NYI_6939861 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2437 // ports before 6939861 supported only three kinds of spread ops |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2438 if (!UseRicochetFrames) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2439 int array_size = slots_pushed + 1; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2440 assert(array_size >= 0, ""); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2441 vminfo = array_size; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2442 switch (array_size) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2443 case 0: ek_opt = _adapter_opt_spread_0; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2444 case 1: ek_opt = _adapter_opt_spread_1; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2445 default: ek_opt = _adapter_opt_spread_more; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2446 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2447 break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2448 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2449 #endif //TARGET_ARCH_NYI_6939861 |
710 | 2450 // vminfo will be the required length of the array |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2451 int array_size = (slots_pushed + 1) / (type2size[dest] == 2 ? 2 : 1); |
710 | 2452 vminfo = array_size; |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2453 // general case |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2454 switch (dest) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2455 case T_BOOLEAN : // fall through to T_BYTE: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2456 case T_BYTE : ek_opt = _adapter_opt_spread_byte; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2457 case T_CHAR : ek_opt = _adapter_opt_spread_char; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2458 case T_SHORT : ek_opt = _adapter_opt_spread_short; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2459 case T_INT : ek_opt = _adapter_opt_spread_int; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2460 case T_LONG : ek_opt = _adapter_opt_spread_long; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2461 case T_FLOAT : ek_opt = _adapter_opt_spread_float; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2462 case T_DOUBLE : ek_opt = _adapter_opt_spread_double; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2463 case T_OBJECT : ek_opt = _adapter_opt_spread_ref; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2464 case T_VOID : if (array_size != 0) goto throw_not_impl; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2465 ek_opt = _adapter_opt_spread_ref; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2466 default : goto throw_not_impl; |
710 | 2467 } |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2468 assert(array_size == 0 || // it doesn't matter what the spreader is |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2469 (ek_adapter_opt_spread_count(ek_opt) == -1 && |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2470 (ek_adapter_opt_spread_type(ek_opt) == dest || |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2471 (ek_adapter_opt_spread_type(ek_opt) == T_BYTE && dest == T_BOOLEAN))), |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2472 err_msg("dest=%d ek_opt=%d", dest, ek_opt)); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2473 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2474 if (array_size <= 0) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2475 // since the general case does not handle length 0, this case is required: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2476 ek_opt = _adapter_opt_spread_0; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2477 break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2478 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2479 if (dest == T_OBJECT) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2480 ek_try = EntryKind(_adapter_opt_spread_1_ref - 1 + array_size); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2481 if (ek_try < _adapter_opt_spread_LAST && |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2482 ek_adapter_opt_spread_count(ek_try) == array_size) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2483 assert(ek_adapter_opt_spread_type(ek_try) == dest, ""); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2484 ek_opt = ek_try; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2485 break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2486 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2487 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2488 break; |
710 | 2489 } |
2490 break; | |
2491 | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2492 case _adapter_collect_args: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2493 { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2494 assert(UseRicochetFrames, "else don't come here"); |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2495 int elem_slots = argument_slot_count(java_lang_invoke_MethodHandle::type(argument())); |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2496 // vminfo will be the location to insert the return value |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2497 vminfo = argslot; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2498 ensure_vmlayout_field(target, CHECK); |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2499 ensure_vmlayout_field(argument, CHECK); |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2500 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2501 // general case: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2502 switch (dest) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2503 default : if (!is_subword_type(dest)) goto throw_not_impl; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2504 // else fall through: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2505 case T_INT : ek_opt = _adapter_opt_collect_int; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2506 case T_LONG : ek_opt = _adapter_opt_collect_long; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2507 case T_FLOAT : ek_opt = _adapter_opt_collect_float; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2508 case T_DOUBLE : ek_opt = _adapter_opt_collect_double; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2509 case T_OBJECT : ek_opt = _adapter_opt_collect_ref; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2510 case T_VOID : ek_opt = _adapter_opt_collect_void; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2511 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2512 assert(ek_adapter_opt_collect_slot(ek_opt) == -1 && |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2513 ek_adapter_opt_collect_count(ek_opt) == -1 && |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2514 (ek_adapter_opt_collect_type(ek_opt) == dest || |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2515 ek_adapter_opt_collect_type(ek_opt) == T_INT && is_subword_type(dest)), |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2516 ""); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2517 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2518 if (dest == T_OBJECT && elem_slots == 1 && OptimizeMethodHandles) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2519 // filter operation on a ref |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2520 ek_try = EntryKind(_adapter_opt_filter_S0_ref + argslot); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2521 if (ek_try < _adapter_opt_collect_LAST && |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2522 ek_adapter_opt_collect_slot(ek_try) == argslot) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2523 assert(ek_adapter_opt_collect_count(ek_try) == elem_slots && |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2524 ek_adapter_opt_collect_type(ek_try) == dest, ""); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2525 ek_opt = ek_try; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2526 break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2527 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2528 ek_opt = _adapter_opt_collect_1_ref; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2529 break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2530 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2531 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2532 if (dest == T_OBJECT && elem_slots == 2 && OptimizeMethodHandles) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2533 // filter of two arguments |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2534 ek_try = EntryKind(_adapter_opt_collect_2_S0_ref + argslot); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2535 if (ek_try < _adapter_opt_collect_LAST && |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2536 ek_adapter_opt_collect_slot(ek_try) == argslot) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2537 assert(ek_adapter_opt_collect_count(ek_try) == elem_slots && |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2538 ek_adapter_opt_collect_type(ek_try) == dest, ""); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2539 ek_opt = ek_try; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2540 break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2541 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2542 ek_opt = _adapter_opt_collect_2_ref; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2543 break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2544 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2545 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2546 if (dest == T_OBJECT && OptimizeMethodHandles) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2547 // try to use a fixed length adapter |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2548 ek_try = EntryKind(_adapter_opt_collect_0_ref + elem_slots); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2549 if (ek_try < _adapter_opt_collect_LAST && |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2550 ek_adapter_opt_collect_count(ek_try) == elem_slots) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2551 assert(ek_adapter_opt_collect_slot(ek_try) == -1 && |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2552 ek_adapter_opt_collect_type(ek_try) == dest, ""); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2553 ek_opt = ek_try; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2554 break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2555 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2556 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2557 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2558 break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2559 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2560 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2561 case _adapter_fold_args: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2562 { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2563 assert(UseRicochetFrames, "else don't come here"); |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2564 int elem_slots = argument_slot_count(java_lang_invoke_MethodHandle::type(argument())); |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2565 // vminfo will be the location to insert the return value |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2566 vminfo = argslot + elem_slots; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2567 ensure_vmlayout_field(target, CHECK); |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2568 ensure_vmlayout_field(argument, CHECK); |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2569 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2570 switch (dest) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2571 default : if (!is_subword_type(dest)) goto throw_not_impl; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2572 // else fall through: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2573 case T_INT : ek_opt = _adapter_opt_fold_int; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2574 case T_LONG : ek_opt = _adapter_opt_fold_long; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2575 case T_FLOAT : ek_opt = _adapter_opt_fold_float; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2576 case T_DOUBLE : ek_opt = _adapter_opt_fold_double; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2577 case T_OBJECT : ek_opt = _adapter_opt_fold_ref; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2578 case T_VOID : ek_opt = _adapter_opt_fold_void; break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2579 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2580 assert(ek_adapter_opt_collect_slot(ek_opt) == -1 && |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2581 ek_adapter_opt_collect_count(ek_opt) == -1 && |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2582 (ek_adapter_opt_collect_type(ek_opt) == dest || |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2583 ek_adapter_opt_collect_type(ek_opt) == T_INT && is_subword_type(dest)), |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2584 ""); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2585 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2586 if (dest == T_OBJECT && elem_slots == 0 && OptimizeMethodHandles) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2587 // if there are no args, just pretend it's a collect |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2588 ek_opt = _adapter_opt_collect_0_ref; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2589 break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2590 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2591 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2592 if (dest == T_OBJECT && OptimizeMethodHandles) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2593 // try to use a fixed length adapter |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2594 ek_try = EntryKind(_adapter_opt_fold_1_ref - 1 + elem_slots); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2595 if (ek_try < _adapter_opt_fold_LAST && |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2596 ek_adapter_opt_collect_count(ek_try) == elem_slots) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2597 assert(ek_adapter_opt_collect_slot(ek_try) == -1 && |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2598 ek_adapter_opt_collect_type(ek_try) == dest, ""); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2599 ek_opt = ek_try; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2600 break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2601 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2602 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2603 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2604 break; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2605 } |
710 | 2606 |
2607 default: | |
2608 // should have failed much earlier; must be a missing case here | |
2609 assert(false, "incomplete switch"); | |
2610 // and fall through: | |
2611 | |
2612 throw_not_impl: | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2613 if (err == NULL) |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2614 err = "unknown adapter type"; |
710 | 2615 break; |
2616 } | |
2617 | |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2618 if (err == NULL && (vminfo & CONV_VMINFO_MASK) != vminfo) { |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2619 // should not happen, since vminfo is used to encode arg/slot indexes < 255 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2620 err = "vminfo overflow"; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2621 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2622 |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2623 if (err == NULL && !have_entry(ek_opt)) { |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2624 err = "adapter stub for this kind of method handle is missing"; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2625 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2626 |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2627 if (err == NULL && ek_opt == ek_orig) { |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2628 switch (ek_opt) { |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2629 case _adapter_prim_to_prim: |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2630 case _adapter_ref_to_prim: |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2631 case _adapter_prim_to_ref: |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2632 case _adapter_swap_args: |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2633 case _adapter_rot_args: |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2634 case _adapter_collect_args: |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2635 case _adapter_fold_args: |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2636 case _adapter_spread_args: |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2637 // should be handled completely by optimized cases; see above |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2638 err = "init_AdapterMethodHandle should not issue this"; |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2639 break; |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2640 } |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2641 } |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
3363
diff
changeset
|
2642 |
710 | 2643 if (err != NULL) { |
3753
cba7b5c2d53f
7045514: SPARC assembly code for JSR 292 ricochet frames
never
parents:
3744
diff
changeset
|
2644 throw_InternalError_for_bad_conversion(conversion, err_msg("%s: conv_op %d ek_opt %d", err, conv_op, ek_opt), THREAD); |
710 | 2645 return; |
2646 } | |
2647 | |
2648 // Rebuild the conversion value; maybe parts of it were changed. | |
2649 jint new_conversion = adapter_conversion(conv_op, src, dest, stack_move, vminfo); | |
2650 | |
2651 // Finalize the conversion field. (Note that it is final to Java code.) | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2652 java_lang_invoke_AdapterMethodHandle::set_conversion(mh(), new_conversion); |
710 | 2653 |
3905
c26de9aef2ed
7071307: MethodHandle bimorphic inlining should consider the frequency
never
parents:
3837
diff
changeset
|
2654 if (java_lang_invoke_CountingMethodHandle::is_instance(mh())) { |
c26de9aef2ed
7071307: MethodHandle bimorphic inlining should consider the frequency
never
parents:
3837
diff
changeset
|
2655 assert(ek_orig == _adapter_retype_only, "only one handled"); |
c26de9aef2ed
7071307: MethodHandle bimorphic inlining should consider the frequency
never
parents:
3837
diff
changeset
|
2656 ek_opt = _adapter_opt_profiling; |
c26de9aef2ed
7071307: MethodHandle bimorphic inlining should consider the frequency
never
parents:
3837
diff
changeset
|
2657 } |
c26de9aef2ed
7071307: MethodHandle bimorphic inlining should consider the frequency
never
parents:
3837
diff
changeset
|
2658 |
710 | 2659 // Done! |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2660 java_lang_invoke_MethodHandle::set_vmentry(mh(), entry(ek_opt)); |
710 | 2661 |
2662 // There should be enough memory barriers on exit from native methods | |
2663 // to ensure that the MH is fully initialized to all threads before | |
2664 // Java code can publish it in global data structures. | |
2665 } | |
2666 | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2667 void MethodHandles::ensure_vmlayout_field(Handle target, TRAPS) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2668 Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(target())); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2669 Handle mtform(THREAD, java_lang_invoke_MethodType::form(mtype())); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2670 if (mtform.is_null()) { THROW(vmSymbols::java_lang_InternalError()); } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2671 if (java_lang_invoke_MethodTypeForm::vmlayout_offset_in_bytes() > 0) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2672 if (java_lang_invoke_MethodTypeForm::vmlayout(mtform()) == NULL) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2673 // fill it in |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2674 Handle erased_mtype(THREAD, java_lang_invoke_MethodTypeForm::erasedType(mtform())); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2675 TempNewSymbol erased_signature |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2676 = java_lang_invoke_MethodType::as_signature(erased_mtype(), /*intern:*/true, CHECK); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2677 methodOop cookie |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2678 = SystemDictionary::find_method_handle_invoke(vmSymbols::invokeExact_name(), |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2679 erased_signature, |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2680 SystemDictionaryHandles::Object_klass(), |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2681 THREAD); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2682 java_lang_invoke_MethodTypeForm::init_vmlayout(mtform(), cookie); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2683 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2684 } |
3938 | 2685 assert(java_lang_invoke_MethodTypeForm::vmslots(mtform()) == argument_slot_count(mtype()), "must agree"); |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2686 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2687 |
3388
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2688 #ifdef ASSERT |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2689 |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2690 extern "C" |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2691 void print_method_handle(oop mh); |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2692 |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2693 static void stress_method_handle_walk_impl(Handle mh, TRAPS) { |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2694 if (StressMethodHandleWalk) { |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2695 // Exercise the MethodHandleWalk code in various ways and validate |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2696 // the resulting method oop. Some of these produce output so they |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2697 // are guarded under Verbose. |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2698 ResourceMark rm; |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2699 HandleMark hm; |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2700 if (Verbose) { |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2701 print_method_handle(mh()); |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2702 } |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2703 TempNewSymbol name = SymbolTable::new_symbol("invoke", CHECK); |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2704 Handle mt = java_lang_invoke_MethodHandle::type(mh()); |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2705 TempNewSymbol signature = java_lang_invoke_MethodType::as_signature(mt(), true, CHECK); |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2706 MethodHandleCompiler mhc(mh, name, signature, 10000, false, CHECK); |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2707 methodHandle m = mhc.compile(CHECK); |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2708 if (Verbose) { |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2709 m->print_codes(); |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2710 } |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2711 InterpreterOopMap mask; |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2712 OopMapCache::compute_one_oop_map(m, m->code_size() - 1, &mask); |
3785
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
2713 // compile to object code if -Xcomp or WizardMode |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
2714 if ((WizardMode || |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
2715 CompilationPolicy::must_be_compiled(m)) |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
2716 && !instanceKlass::cast(m->method_holder())->is_not_initialized() |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
2717 && CompilationPolicy::can_be_compiled(m)) { |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
2718 // Force compilation |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
2719 CompileBroker::compile_method(m, InvocationEntryBci, |
3837
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3785
diff
changeset
|
2720 CompilationPolicy::policy()->initial_compile_level(), |
3785
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
2721 methodHandle(), 0, "StressMethodHandleWalk", |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
2722 CHECK); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
2723 } |
3388
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2724 } |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2725 } |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2726 |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2727 static void stress_method_handle_walk(Handle mh, TRAPS) { |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2728 stress_method_handle_walk_impl(mh, THREAD); |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2729 if (HAS_PENDING_EXCEPTION) { |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2730 oop ex = PENDING_EXCEPTION; |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2731 CLEAR_PENDING_EXCEPTION; |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2732 tty->print("StressMethodHandleWalk: "); |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2733 java_lang_Throwable::print(ex, tty); |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2734 tty->cr(); |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2735 } |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2736 } |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2737 #else |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2738 |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2739 static void stress_method_handle_walk(Handle mh, TRAPS) {} |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2740 |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2741 #endif |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2742 |
710 | 2743 // |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2744 // Here are the native methods on sun.invoke.MethodHandleImpl. |
710 | 2745 // They are the private interface between this JVM and the HotSpot-specific |
2746 // Java code that implements JSR 292 method handles. | |
2747 // | |
2748 // Note: We use a JVM_ENTRY macro to define each of these, for this is the way | |
2749 // that intrinsic (non-JNI) native methods are defined in HotSpot. | |
2750 // | |
2751 | |
2752 // direct method handles for invokestatic or invokespecial | |
2753 // void init(DirectMethodHandle self, MemberName ref, boolean doDispatch, Class<?> caller); | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2754 JVM_ENTRY(void, MHN_init_DMH(JNIEnv *env, jobject igcls, jobject mh_jh, |
710 | 2755 jobject target_jh, jboolean do_dispatch, jobject caller_jh)) { |
2756 ResourceMark rm; // for error messages | |
2757 | |
2758 // This is the guy we are initializing: | |
3740
5ac411b3b8fc
7047961: JSR 292 MethodHandleWalk swap args doesn't handle T_LONG and T_DOUBLE properly
never
parents:
3389
diff
changeset
|
2759 if (mh_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "self is null"); } |
710 | 2760 Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh)); |
2761 | |
2762 // Early returns out of this method leave the DMH in an unfinished state. | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2763 assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null"); |
710 | 2764 |
2765 // which method are we really talking about? | |
3740
5ac411b3b8fc
7047961: JSR 292 MethodHandleWalk swap args doesn't handle T_LONG and T_DOUBLE properly
never
parents:
3389
diff
changeset
|
2766 if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); } |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
2767 Handle target(THREAD, JNIHandles::resolve_non_null(target_jh)); |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
2768 if (java_lang_invoke_MemberName::is_instance(target()) && |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
2769 java_lang_invoke_MemberName::vmindex(target()) == VM_INDEX_UNINITIALIZED) { |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
2770 MethodHandles::resolve_MemberName(target, CHECK); |
710 | 2771 } |
2772 | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
2773 KlassHandle receiver_limit; int decode_flags = 0; |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
2774 methodHandle m = MethodHandles::decode_method(target(), receiver_limit, decode_flags); |
710 | 2775 if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "no such method"); } |
2776 | |
2777 // The trusted Java code that calls this method should already have performed | |
2778 // access checks on behalf of the given caller. But, we can verify this. | |
2779 if (VerifyMethodHandles && caller_jh != NULL) { | |
2780 KlassHandle caller(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(caller_jh))); | |
2781 // If this were a bytecode, the first access check would be against | |
2782 // the "reference class" mentioned in the CONSTANT_Methodref. | |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
2783 // We don't know at this point which class that was, and if we |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
2784 // check against m.method_holder we might get the wrong answer. |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
2785 // So we just make sure to handle this check when the resolution |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
2786 // happens, when we call resolve_MemberName. |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
2787 // |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
2788 // (A public class can inherit public members from private supers, |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
2789 // and it would be wrong to check access against the private super |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
2790 // if the original symbolic reference was against the public class.) |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
2791 // |
710 | 2792 // If there were a bytecode, the next step would be to lookup the method |
2793 // in the reference class, then then check the method's access bits. | |
2794 // Emulate LinkResolver::check_method_accessability. | |
2795 klassOop resolved_klass = m->method_holder(); | |
2796 if (!Reflection::verify_field_access(caller->as_klassOop(), | |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
2797 resolved_klass, resolved_klass, |
710 | 2798 m->access_flags(), |
2799 true)) { | |
2800 // %%% following cutout belongs in Reflection::verify_field_access? | |
2801 bool same_pm = Reflection::is_same_package_member(caller->as_klassOop(), | |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
2802 resolved_klass, THREAD); |
710 | 2803 if (!same_pm) { |
2804 THROW_MSG(vmSymbols::java_lang_InternalError(), m->name_and_sig_as_C_string()); | |
2805 } | |
2806 } | |
2807 } | |
2808 | |
2809 MethodHandles::init_DirectMethodHandle(mh, m, (do_dispatch != JNI_FALSE), CHECK); | |
3388
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2810 stress_method_handle_walk(mh, CHECK); |
710 | 2811 } |
2812 JVM_END | |
2813 | |
2814 // bound method handles | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2815 JVM_ENTRY(void, MHN_init_BMH(JNIEnv *env, jobject igcls, jobject mh_jh, |
710 | 2816 jobject target_jh, int argnum)) { |
2817 ResourceMark rm; // for error messages | |
2818 | |
2819 // This is the guy we are initializing: | |
3740
5ac411b3b8fc
7047961: JSR 292 MethodHandleWalk swap args doesn't handle T_LONG and T_DOUBLE properly
never
parents:
3389
diff
changeset
|
2820 if (mh_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "self is null"); } |
710 | 2821 Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh)); |
2822 | |
2823 // Early returns out of this method leave the BMH in an unfinished state. | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2824 assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null"); |
710 | 2825 |
3740
5ac411b3b8fc
7047961: JSR 292 MethodHandleWalk swap args doesn't handle T_LONG and T_DOUBLE properly
never
parents:
3389
diff
changeset
|
2826 if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); } |
710 | 2827 Handle target(THREAD, JNIHandles::resolve_non_null(target_jh)); |
2828 | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2829 if (!java_lang_invoke_MethodHandle::is_instance(target())) { |
710 | 2830 // Target object is a reflective method. (%%% Do we need this alternate path?) |
2831 Untested("init_BMH of non-MH"); | |
2832 if (argnum != 0) { THROW(vmSymbols::java_lang_InternalError()); } | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
2833 KlassHandle receiver_limit; int decode_flags = 0; |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
2834 methodHandle m = MethodHandles::decode_method(target(), receiver_limit, decode_flags); |
710 | 2835 MethodHandles::init_BoundMethodHandle_with_receiver(mh, m, |
2836 receiver_limit, | |
2837 decode_flags, | |
2838 CHECK); | |
3388
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2839 } else { |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2840 // Build a BMH on top of a DMH or another BMH: |
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2841 MethodHandles::init_BoundMethodHandle(mh, target, argnum, CHECK); |
710 | 2842 } |
3785
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
2843 |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
2844 if (StressMethodHandleWalk) { |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
2845 if (mh->klass() == SystemDictionary::BoundMethodHandle_klass()) |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
2846 stress_method_handle_walk(mh, CHECK); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
2847 // else don't, since the subclass has not yet initialized its own fields |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3781
diff
changeset
|
2848 } |
710 | 2849 } |
2850 JVM_END | |
2851 | |
2852 // adapter method handles | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2853 JVM_ENTRY(void, MHN_init_AMH(JNIEnv *env, jobject igcls, jobject mh_jh, |
710 | 2854 jobject target_jh, int argnum)) { |
2855 // This is the guy we are initializing: | |
3740
5ac411b3b8fc
7047961: JSR 292 MethodHandleWalk swap args doesn't handle T_LONG and T_DOUBLE properly
never
parents:
3389
diff
changeset
|
2856 if (mh_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "self is null"); } |
5ac411b3b8fc
7047961: JSR 292 MethodHandleWalk swap args doesn't handle T_LONG and T_DOUBLE properly
never
parents:
3389
diff
changeset
|
2857 if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); } |
710 | 2858 Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh)); |
2859 Handle target(THREAD, JNIHandles::resolve_non_null(target_jh)); | |
2860 | |
2861 // Early returns out of this method leave the AMH in an unfinished state. | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2862 assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null"); |
710 | 2863 |
2864 MethodHandles::init_AdapterMethodHandle(mh, target, argnum, CHECK); | |
3388
a80577f854f9
7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents:
3371
diff
changeset
|
2865 stress_method_handle_walk(mh, CHECK); |
710 | 2866 } |
2867 JVM_END | |
2868 | |
2869 // method type forms | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2870 JVM_ENTRY(void, MHN_init_MT(JNIEnv *env, jobject igcls, jobject erased_jh)) { |
710 | 2871 if (erased_jh == NULL) return; |
2872 if (TraceMethodHandles) { | |
2873 tty->print("creating MethodType form "); | |
2874 if (WizardMode || Verbose) { // Warning: this calls Java code on the MH! | |
2875 // call Object.toString() | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
2876 Symbol* name = vmSymbols::toString_name(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
2877 Symbol* sig = vmSymbols::void_string_signature(); |
710 | 2878 JavaCallArguments args(Handle(THREAD, JNIHandles::resolve_non_null(erased_jh))); |
2879 JavaValue result(T_OBJECT); | |
1142 | 2880 JavaCalls::call_virtual(&result, SystemDictionary::Object_klass(), name, sig, |
710 | 2881 &args, CHECK); |
2882 Handle str(THREAD, (oop)result.get_jobject()); | |
2883 java_lang_String::print(str, tty); | |
2884 } | |
2885 tty->cr(); | |
2886 } | |
2887 } | |
2888 JVM_END | |
2889 | |
2890 // debugging and reflection | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2891 JVM_ENTRY(jobject, MHN_getTarget(JNIEnv *env, jobject igcls, jobject mh_jh, jint format)) { |
710 | 2892 Handle mh(THREAD, JNIHandles::resolve(mh_jh)); |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2893 if (!java_lang_invoke_MethodHandle::is_instance(mh())) { |
710 | 2894 THROW_NULL(vmSymbols::java_lang_IllegalArgumentException()); |
2895 } | |
2896 oop target = MethodHandles::encode_target(mh, format, CHECK_NULL); | |
2897 return JNIHandles::make_local(THREAD, target); | |
2898 } | |
2899 JVM_END | |
2900 | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2901 JVM_ENTRY(jint, MHN_getConstant(JNIEnv *env, jobject igcls, jint which)) { |
710 | 2902 switch (which) { |
2903 case MethodHandles::GC_JVM_PUSH_LIMIT: | |
2904 guarantee(MethodHandlePushLimit >= 2 && MethodHandlePushLimit <= 0xFF, | |
2905 "MethodHandlePushLimit parameter must be in valid range"); | |
2906 return MethodHandlePushLimit; | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
2907 case MethodHandles::GC_JVM_STACK_MOVE_UNIT: |
710 | 2908 // return number of words per slot, signed according to stack direction |
2909 return MethodHandles::stack_move_unit(); | |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
2910 case MethodHandles::GC_CONV_OP_IMPLEMENTED_MASK: |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
2911 return MethodHandles::adapter_conversion_ops_supported_mask(); |
3905
c26de9aef2ed
7071307: MethodHandle bimorphic inlining should consider the frequency
never
parents:
3837
diff
changeset
|
2912 case MethodHandles::GC_COUNT_GWT: |
c26de9aef2ed
7071307: MethodHandle bimorphic inlining should consider the frequency
never
parents:
3837
diff
changeset
|
2913 #ifdef COMPILER2 |
c26de9aef2ed
7071307: MethodHandle bimorphic inlining should consider the frequency
never
parents:
3837
diff
changeset
|
2914 return true; |
c26de9aef2ed
7071307: MethodHandle bimorphic inlining should consider the frequency
never
parents:
3837
diff
changeset
|
2915 #else |
c26de9aef2ed
7071307: MethodHandle bimorphic inlining should consider the frequency
never
parents:
3837
diff
changeset
|
2916 return false; |
c26de9aef2ed
7071307: MethodHandle bimorphic inlining should consider the frequency
never
parents:
3837
diff
changeset
|
2917 #endif |
710 | 2918 } |
2919 return 0; | |
2920 } | |
2921 JVM_END | |
2922 | |
2923 #ifndef PRODUCT | |
2924 #define EACH_NAMED_CON(template) \ | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2925 /* hold back this one until JDK stabilizes */ \ |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2926 /* template(MethodHandles,GC_JVM_PUSH_LIMIT) */ \ |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2927 /* hold back this one until JDK stabilizes */ \ |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2928 /* template(MethodHandles,GC_JVM_STACK_MOVE_UNIT) */ \ |
3757
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2929 /* hold back this one until JDK stabilizes */ \ |
f8c9417e3571
7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
never
parents:
3753
diff
changeset
|
2930 /* template(MethodHandles,GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS) */ \ |
710 | 2931 template(MethodHandles,ETF_HANDLE_OR_METHOD_NAME) \ |
2932 template(MethodHandles,ETF_DIRECT_HANDLE) \ | |
2933 template(MethodHandles,ETF_METHOD_NAME) \ | |
2934 template(MethodHandles,ETF_REFLECT_METHOD) \ | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2935 template(java_lang_invoke_MemberName,MN_IS_METHOD) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2936 template(java_lang_invoke_MemberName,MN_IS_CONSTRUCTOR) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2937 template(java_lang_invoke_MemberName,MN_IS_FIELD) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2938 template(java_lang_invoke_MemberName,MN_IS_TYPE) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2939 template(java_lang_invoke_MemberName,MN_SEARCH_SUPERCLASSES) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2940 template(java_lang_invoke_MemberName,MN_SEARCH_INTERFACES) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2941 template(java_lang_invoke_MemberName,VM_INDEX_UNINITIALIZED) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2942 template(java_lang_invoke_AdapterMethodHandle,OP_RETYPE_ONLY) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2943 template(java_lang_invoke_AdapterMethodHandle,OP_RETYPE_RAW) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2944 template(java_lang_invoke_AdapterMethodHandle,OP_CHECK_CAST) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2945 template(java_lang_invoke_AdapterMethodHandle,OP_PRIM_TO_PRIM) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2946 template(java_lang_invoke_AdapterMethodHandle,OP_REF_TO_PRIM) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2947 template(java_lang_invoke_AdapterMethodHandle,OP_PRIM_TO_REF) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2948 template(java_lang_invoke_AdapterMethodHandle,OP_SWAP_ARGS) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2949 template(java_lang_invoke_AdapterMethodHandle,OP_ROT_ARGS) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2950 template(java_lang_invoke_AdapterMethodHandle,OP_DUP_ARGS) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2951 template(java_lang_invoke_AdapterMethodHandle,OP_DROP_ARGS) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2952 template(java_lang_invoke_AdapterMethodHandle,OP_COLLECT_ARGS) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2953 template(java_lang_invoke_AdapterMethodHandle,OP_SPREAD_ARGS) \ |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2954 /* hold back this one until JDK stabilizes */ \ |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3274
diff
changeset
|
2955 /*template(java_lang_invoke_AdapterMethodHandle,CONV_OP_LIMIT)*/ \ |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2956 template(java_lang_invoke_AdapterMethodHandle,CONV_OP_MASK) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2957 template(java_lang_invoke_AdapterMethodHandle,CONV_VMINFO_MASK) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2958 template(java_lang_invoke_AdapterMethodHandle,CONV_VMINFO_SHIFT) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2959 template(java_lang_invoke_AdapterMethodHandle,CONV_OP_SHIFT) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2960 template(java_lang_invoke_AdapterMethodHandle,CONV_DEST_TYPE_SHIFT) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2961 template(java_lang_invoke_AdapterMethodHandle,CONV_SRC_TYPE_SHIFT) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2962 template(java_lang_invoke_AdapterMethodHandle,CONV_STACK_MOVE_SHIFT) \ |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2963 template(java_lang_invoke_AdapterMethodHandle,CONV_STACK_MOVE_MASK) \ |
710 | 2964 /*end*/ |
2965 | |
2966 #define ONE_PLUS(scope,value) 1+ | |
2967 static const int con_value_count = EACH_NAMED_CON(ONE_PLUS) 0; | |
2968 #define VALUE_COMMA(scope,value) scope::value, | |
2969 static const int con_values[con_value_count+1] = { EACH_NAMED_CON(VALUE_COMMA) 0 }; | |
2970 #define STRING_NULL(scope,value) #value "\0" | |
2971 static const char con_names[] = { EACH_NAMED_CON(STRING_NULL) }; | |
2972 | |
2973 #undef ONE_PLUS | |
2974 #undef VALUE_COMMA | |
2975 #undef STRING_NULL | |
2976 #undef EACH_NAMED_CON | |
2977 #endif | |
2978 | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2979 JVM_ENTRY(jint, MHN_getNamedCon(JNIEnv *env, jobject igcls, jint which, jobjectArray box_jh)) { |
710 | 2980 #ifndef PRODUCT |
2981 if (which >= 0 && which < con_value_count) { | |
2982 int con = con_values[which]; | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
2983 objArrayHandle box(THREAD, (objArrayOop) JNIHandles::resolve(box_jh)); |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
2984 if (box.not_null() && box->klass() == Universe::objectArrayKlassObj() && box->length() > 0) { |
710 | 2985 const char* str = &con_names[0]; |
2986 for (int i = 0; i < which; i++) | |
2987 str += strlen(str) + 1; // skip name and null | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
2988 oop name = java_lang_String::create_oop_from_str(str, CHECK_0); // possible safepoint |
710 | 2989 box->obj_at_put(0, name); |
2990 } | |
2991 return con; | |
2992 } | |
2993 #endif | |
2994 return 0; | |
2995 } | |
2996 JVM_END | |
2997 | |
2998 // void init(MemberName self, AccessibleObject ref) | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
2999 JVM_ENTRY(void, MHN_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) { |
3740
5ac411b3b8fc
7047961: JSR 292 MethodHandleWalk swap args doesn't handle T_LONG and T_DOUBLE properly
never
parents:
3389
diff
changeset
|
3000 if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); } |
5ac411b3b8fc
7047961: JSR 292 MethodHandleWalk swap args doesn't handle T_LONG and T_DOUBLE properly
never
parents:
3389
diff
changeset
|
3001 if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); } |
710 | 3002 Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); |
3003 oop target_oop = JNIHandles::resolve_non_null(target_jh); | |
3004 MethodHandles::init_MemberName(mname(), target_oop); | |
3005 } | |
3006 JVM_END | |
3007 | |
3008 // void expand(MemberName self) | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
3009 JVM_ENTRY(void, MHN_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) { |
3740
5ac411b3b8fc
7047961: JSR 292 MethodHandleWalk swap args doesn't handle T_LONG and T_DOUBLE properly
never
parents:
3389
diff
changeset
|
3010 if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); } |
710 | 3011 Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); |
3012 MethodHandles::expand_MemberName(mname, 0, CHECK); | |
3013 } | |
3014 JVM_END | |
3015 | |
3016 // void resolve(MemberName self, Class<?> caller) | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
3017 JVM_ENTRY(void, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) { |
3740
5ac411b3b8fc
7047961: JSR 292 MethodHandleWalk swap args doesn't handle T_LONG and T_DOUBLE properly
never
parents:
3389
diff
changeset
|
3018 if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); } |
710 | 3019 Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
3020 |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
3021 // The trusted Java code that calls this method should already have performed |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
3022 // access checks on behalf of the given caller. But, we can verify this. |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
3023 if (VerifyMethodHandles && caller_jh != NULL) { |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
3024 klassOop reference_klass = java_lang_Class::as_klassOop(java_lang_invoke_MemberName::clazz(mname())); |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
3025 if (reference_klass != NULL) { |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
3026 // Emulate LinkResolver::check_klass_accessability. |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
3027 klassOop caller = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(caller_jh)); |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
3028 if (!Reflection::verify_class_access(caller, |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
3029 reference_klass, |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
3030 true)) { |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
3031 THROW_MSG(vmSymbols::java_lang_InternalError(), Klass::cast(reference_klass)->external_name()); |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
3032 } |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
3033 } |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
3034 } |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1299
diff
changeset
|
3035 |
710 | 3036 MethodHandles::resolve_MemberName(mname, CHECK); |
3037 } | |
3038 JVM_END | |
3039 | |
3040 // static native int getMembers(Class<?> defc, String matchName, String matchSig, | |
3041 // int matchFlags, Class<?> caller, int skip, MemberName[] results); | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
3042 JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls, |
710 | 3043 jclass clazz_jh, jstring name_jh, jstring sig_jh, |
3044 int mflags, jclass caller_jh, jint skip, jobjectArray results_jh)) { | |
3045 if (clazz_jh == NULL || results_jh == NULL) return -1; | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
3046 KlassHandle k(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz_jh))); |
710 | 3047 |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
3048 objArrayHandle results(THREAD, (objArrayOop) JNIHandles::resolve(results_jh)); |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
3049 if (results.is_null() || !results->is_objArray()) return -1; |
710 | 3050 |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
3051 TempNewSymbol name = NULL; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2116
diff
changeset
|
3052 TempNewSymbol sig = NULL; |
710 | 3053 if (name_jh != NULL) { |
3054 name = java_lang_String::as_symbol_or_null(JNIHandles::resolve_non_null(name_jh)); | |
3055 if (name == NULL) return 0; // a match is not possible | |
3056 } | |
3057 if (sig_jh != NULL) { | |
3058 sig = java_lang_String::as_symbol_or_null(JNIHandles::resolve_non_null(sig_jh)); | |
3059 if (sig == NULL) return 0; // a match is not possible | |
3060 } | |
3061 | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
3062 KlassHandle caller; |
710 | 3063 if (caller_jh != NULL) { |
3064 oop caller_oop = JNIHandles::resolve_non_null(caller_jh); | |
3065 if (!java_lang_Class::is_instance(caller_oop)) return -1; | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
3066 caller = KlassHandle(THREAD, java_lang_Class::as_klassOop(caller_oop)); |
710 | 3067 } |
3068 | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
3069 if (name != NULL && sig != NULL && results.not_null()) { |
710 | 3070 // try a direct resolve |
3071 // %%% TO DO | |
3072 } | |
3073 | |
3274
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
3074 int res = MethodHandles::find_MemberNames(k(), name, sig, mflags, |
2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
twisti
parents:
2478
diff
changeset
|
3075 caller(), skip, results()); |
710 | 3076 // TO DO: expand at least some of the MemberNames, to avoid massive callbacks |
3077 return res; | |
3078 } | |
3079 JVM_END | |
3080 | |
3932
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3081 JVM_ENTRY(void, MHN_setCallSiteTargetNormal(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) { |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3082 oop call_site = JNIHandles::resolve_non_null(call_site_jh); |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3083 oop target = JNIHandles::resolve(target_jh); |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3084 { |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3085 // Walk all nmethods depending on this call site. |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3086 MutexLocker mu(Compile_lock, thread); |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3087 Universe::flush_dependents_on(call_site, target); |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3088 } |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3089 java_lang_invoke_CallSite::set_target(call_site, target); |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3090 } |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3091 JVM_END |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3092 |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3093 JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) { |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3094 oop call_site = JNIHandles::resolve_non_null(call_site_jh); |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3095 oop target = JNIHandles::resolve(target_jh); |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3096 { |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3097 // Walk all nmethods depending on this call site. |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3098 MutexLocker mu(Compile_lock, thread); |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3099 Universe::flush_dependents_on(call_site, target); |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3100 } |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3101 java_lang_invoke_CallSite::set_target_volatile(call_site, target); |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3102 } |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3103 JVM_END |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3104 |
3744
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3105 methodOop MethodHandles::resolve_raise_exception_method(TRAPS) { |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3106 if (_raise_exception_method != NULL) { |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3107 // no need to do it twice |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3108 return raise_exception_method(); |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3109 } |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3110 // LinkResolver::resolve_invokedynamic can reach this point |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3111 // because an invokedynamic has failed very early (7049415) |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3112 KlassHandle MHN_klass = SystemDictionaryHandles::MethodHandleNatives_klass(); |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3113 if (MHN_klass.not_null()) { |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3114 TempNewSymbol raiseException_name = SymbolTable::new_symbol("raiseException", CHECK_NULL); |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3115 TempNewSymbol raiseException_sig = SymbolTable::new_symbol("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK_NULL); |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3116 methodOop raiseException_method = instanceKlass::cast(MHN_klass->as_klassOop()) |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3117 ->find_method(raiseException_name, raiseException_sig); |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3118 if (raiseException_method != NULL && raiseException_method->is_static()) { |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3119 return raiseException_method; |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3120 } |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3121 } |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3122 // not found; let the caller deal with it |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3123 return NULL; |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3124 } |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3125 void MethodHandles::raise_exception(int code, oop actual, oop required, TRAPS) { |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3126 methodOop raiseException_method = resolve_raise_exception_method(CHECK); |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3127 if (raiseException_method != NULL && |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3128 instanceKlass::cast(raiseException_method->method_holder())->is_not_initialized()) { |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3129 instanceKlass::cast(raiseException_method->method_holder())->initialize(CHECK); |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3130 // it had better be resolved by now, or maybe JSR 292 failed to load |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3131 raiseException_method = raise_exception_method(); |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3132 } |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3133 if (raiseException_method == NULL) { |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3134 THROW_MSG(vmSymbols::java_lang_InternalError(), "no raiseException method"); |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3135 } |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3136 JavaCallArguments args; |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3137 args.push_int(code); |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3138 args.push_oop(actual); |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3139 args.push_oop(required); |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3140 JavaValue result(T_VOID); |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3141 JavaCalls::call(&result, raiseException_method, &args, CHECK); |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3142 } |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3143 |
3387
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3144 JVM_ENTRY(jobject, MH_invoke_UOE(JNIEnv *env, jobject igmh, jobjectArray igargs)) { |
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3145 TempNewSymbol UOE_name = SymbolTable::new_symbol("java/lang/UnsupportedOperationException", CHECK_NULL); |
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3146 THROW_MSG_NULL(UOE_name, "MethodHandle.invoke cannot be invoked reflectively"); |
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3147 return NULL; |
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3148 } |
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3149 JVM_END |
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3150 |
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3151 JVM_ENTRY(jobject, MH_invokeExact_UOE(JNIEnv *env, jobject igmh, jobjectArray igargs)) { |
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3152 TempNewSymbol UOE_name = SymbolTable::new_symbol("java/lang/UnsupportedOperationException", CHECK_NULL); |
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3153 THROW_MSG_NULL(UOE_name, "MethodHandle.invokeExact cannot be invoked reflectively"); |
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3154 return NULL; |
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3155 } |
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3156 JVM_END |
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3157 |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
3158 |
710 | 3159 /// JVM_RegisterMethodHandleMethods |
3160 | |
3932
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3161 #undef CS // Solaris builds complain |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3162 |
710 | 3163 #define LANG "Ljava/lang/" |
2460 | 3164 #define JLINV "Ljava/lang/invoke/" |
710 | 3165 |
3166 #define OBJ LANG"Object;" | |
3167 #define CLS LANG"Class;" | |
3168 #define STRG LANG"String;" | |
3932
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3169 #define CS JLINV"CallSite;" |
2460 | 3170 #define MT JLINV"MethodType;" |
3171 #define MH JLINV"MethodHandle;" | |
3172 #define MEM JLINV"MemberName;" | |
3173 #define AMH JLINV"AdapterMethodHandle;" | |
3174 #define BMH JLINV"BoundMethodHandle;" | |
3175 #define DMH JLINV"DirectMethodHandle;" | |
710 | 3176 |
3177 #define CC (char*) /*cast a literal from (const char*)*/ | |
3178 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f) | |
3179 | |
3932
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3180 // These are the native methods on java.lang.invoke.MethodHandleNatives. |
710 | 3181 static JNINativeMethod methods[] = { |
3182 // void init(MemberName self, AccessibleObject ref) | |
3932
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3183 {CC"init", CC"("AMH""MH"I)V", FN_PTR(MHN_init_AMH)}, |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3184 {CC"init", CC"("BMH""OBJ"I)V", FN_PTR(MHN_init_BMH)}, |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3185 {CC"init", CC"("DMH""OBJ"Z"CLS")V", FN_PTR(MHN_init_DMH)}, |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3186 {CC"init", CC"("MT")V", FN_PTR(MHN_init_MT)}, |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3187 {CC"init", CC"("MEM""OBJ")V", FN_PTR(MHN_init_Mem)}, |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3188 {CC"expand", CC"("MEM")V", FN_PTR(MHN_expand_Mem)}, |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3189 {CC"resolve", CC"("MEM""CLS")V", FN_PTR(MHN_resolve_Mem)}, |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3190 {CC"getTarget", CC"("MH"I)"OBJ, FN_PTR(MHN_getTarget)}, |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3191 {CC"getConstant", CC"(I)I", FN_PTR(MHN_getConstant)}, |
710 | 3192 // static native int getNamedCon(int which, Object[] name) |
3932
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3193 {CC"getNamedCon", CC"(I["OBJ")I", FN_PTR(MHN_getNamedCon)}, |
710 | 3194 // static native int getMembers(Class<?> defc, String matchName, String matchSig, |
3195 // int matchFlags, Class<?> caller, int skip, MemberName[] results); | |
3932
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3196 {CC"getMembers", CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)} |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3197 }; |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3198 |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3199 static JNINativeMethod call_site_methods[] = { |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3200 {CC"setCallSiteTargetNormal", CC"("CS""MH")V", FN_PTR(MHN_setCallSiteTargetNormal)}, |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3201 {CC"setCallSiteTargetVolatile", CC"("CS""MH")V", FN_PTR(MHN_setCallSiteTargetVolatile)} |
710 | 3202 }; |
3203 | |
3387
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3204 static JNINativeMethod invoke_methods[] = { |
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3205 // void init(MemberName self, AccessibleObject ref) |
3932
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3206 {CC"invoke", CC"(["OBJ")"OBJ, FN_PTR(MH_invoke_UOE)}, |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3207 {CC"invokeExact", CC"(["OBJ")"OBJ, FN_PTR(MH_invokeExact_UOE)} |
3387
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3208 }; |
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3209 |
710 | 3210 // This one function is exported, used by NativeLookup. |
3211 | |
3212 JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) { | |
3213 assert(MethodHandles::spot_check_entry_names(), "entry enum is OK"); | |
3214 | |
2416
38fea01eb669
6817525: turn on method handle functionality by default for JSR 292
twisti
parents:
2357
diff
changeset
|
3215 if (!EnableInvokeDynamic) { |
38fea01eb669
6817525: turn on method handle functionality by default for JSR 292
twisti
parents:
2357
diff
changeset
|
3216 warning("JSR 292 is disabled in this JVM. Use -XX:+UnlockDiagnosticVMOptions -XX:+EnableInvokeDynamic to enable."); |
710 | 3217 return; // bind nothing |
3218 } | |
3219 | |
3932
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3220 assert(!MethodHandles::enabled(), "must not be enabled"); |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
3221 bool enable_MH = true; |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
3222 |
2460 | 3223 { |
710 | 3224 ThreadToNativeFromVM ttnfv(thread); |
3225 int status = env->RegisterNatives(MHN_class, methods, sizeof(methods)/sizeof(JNINativeMethod)); | |
3387
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3226 if (!env->ExceptionOccurred()) { |
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3227 const char* L_MH_name = (JLINV "MethodHandle"); |
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3228 const char* MH_name = L_MH_name+1; |
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3229 jclass MH_class = env->FindClass(MH_name); |
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3230 status = env->RegisterNatives(MH_class, invoke_methods, sizeof(invoke_methods)/sizeof(JNINativeMethod)); |
2848194272f4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
3371
diff
changeset
|
3231 } |
710 | 3232 if (env->ExceptionOccurred()) { |
2460 | 3233 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); |
3234 enable_MH = false; | |
710 | 3235 env->ExceptionClear(); |
3236 } | |
3932
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3237 |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3238 status = env->RegisterNatives(MHN_class, call_site_methods, sizeof(call_site_methods)/sizeof(JNINativeMethod)); |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3239 if (env->ExceptionOccurred()) { |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3240 // Exception is okay until 7087357 |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3241 env->ExceptionClear(); |
b0efc7ee3b31
7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
twisti
parents:
3905
diff
changeset
|
3242 } |
710 | 3243 } |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
3244 |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
3245 if (enable_MH) { |
3744
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3246 methodOop raiseException_method = MethodHandles::resolve_raise_exception_method(CHECK); |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3247 if (raiseException_method != NULL) { |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3248 MethodHandles::set_raise_exception_method(raiseException_method); |
2460 | 3249 } else { |
3744
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3740
diff
changeset
|
3250 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); |
2116
d810e9a3fc33
7010180: JSR 292 InvokeDynamicPrintArgs fails with: assert(_adapter == NULL) failed: init'd to NULL
twisti
parents:
2088
diff
changeset
|
3251 enable_MH = false; |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
3252 } |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
3253 } |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
3254 |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
3255 if (enable_MH) { |
2116
d810e9a3fc33
7010180: JSR 292 InvokeDynamicPrintArgs fails with: assert(_adapter == NULL) failed: init'd to NULL
twisti
parents:
2088
diff
changeset
|
3256 MethodHandles::generate_adapters(); |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
3257 MethodHandles::set_enabled(true); |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
726
diff
changeset
|
3258 } |
710 | 3259 } |
3260 JVM_END |