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