annotate src/share/vm/prims/methodHandles.cpp @ 1716:be3f9c242c9d

6948538: CMS: BOT walkers can fall into object allocation and initialization cracks Summary: GC workers now recognize an intermediate transient state of blocks which are allocated but have not yet completed initialization. blk_start() calls do not attempt to determine the size of a block in the transient state, rather waiting for the block to become initialized so that it is safe to query its size. Audited and ensured the order of initialization of object fields (klass, free bit and size) to respect block state transition protocol. Also included some new assertion checking code enabled in debug mode. Reviewed-by: chrisphi, johnc, poonam
author ysr
date Mon, 16 Aug 2010 15:58:42 -0700
parents 083fde3b838e
children 3e8fbc61cee8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1508
diff changeset
2 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
4 *
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
7 * published by the Free Software Foundation.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
8 *
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
13 * accompanied this code).
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
14 *
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
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
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
22 *
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
23 */
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
24
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
25 /*
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
26 * JSR 292 reference implementation: method handles
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
27 */
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
28
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
29 #include "incls/_precompiled.incl"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
30 #include "incls/_methodHandles.cpp.incl"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
31
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
32 bool MethodHandles::_enabled = false; // set true after successful native linkage
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
33
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
34 MethodHandleEntry* MethodHandles::_entries[MethodHandles::_EK_LIMIT] = {NULL};
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
35 const char* MethodHandles::_entry_names[_EK_LIMIT+1] = {
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
36 "raise_exception",
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
37 "invokestatic", // how a MH emulates invokestatic
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
38 "invokespecial", // ditto for the other invokes...
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
39 "invokevirtual",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
40 "invokeinterface",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
41 "bound_ref", // these are for BMH...
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
42 "bound_int",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
43 "bound_long",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
44 "bound_ref_direct", // (direct versions have a direct methodOop)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
45 "bound_int_direct",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
46 "bound_long_direct",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
47
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
48 // starting at _adapter_mh_first:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
49 "adapter_retype_only", // these are for AMH...
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
50 "adapter_retype_raw",
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
51 "adapter_check_cast",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
52 "adapter_prim_to_prim",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
53 "adapter_ref_to_prim",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
54 "adapter_prim_to_ref",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
55 "adapter_swap_args",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
56 "adapter_rot_args",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
57 "adapter_dup_args",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
58 "adapter_drop_args",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
59 "adapter_collect_args",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
60 "adapter_spread_args",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
61 "adapter_flyby",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
62 "adapter_ricochet",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
63
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
64 // optimized adapter types:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
65 "adapter_swap_args/1",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
66 "adapter_swap_args/2",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
67 "adapter_rot_args/1,up",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
68 "adapter_rot_args/1,down",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
69 "adapter_rot_args/2,up",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
70 "adapter_rot_args/2,down",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
71 "adapter_prim_to_prim/i2i",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
72 "adapter_prim_to_prim/l2i",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
73 "adapter_prim_to_prim/d2f",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
74 "adapter_prim_to_prim/i2l",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
75 "adapter_prim_to_prim/f2d",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
76 "adapter_ref_to_prim/unboxi",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
77 "adapter_ref_to_prim/unboxl",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
78 "adapter_spread_args/0",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
79 "adapter_spread_args/1",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
80 "adapter_spread_args/more",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
81
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
82 NULL
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
83 };
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
84
1299
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
85 // Adapters.
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
86 MethodHandlesAdapterBlob* MethodHandles::_adapter_code = NULL;
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
87 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
88
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
89 jobject MethodHandles::_raise_exception_method;
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
90
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
91 #ifdef ASSERT
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
92 bool MethodHandles::spot_check_entry_names() {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
93 assert(!strcmp(entry_name(_invokestatic_mh), "invokestatic"), "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
94 assert(!strcmp(entry_name(_bound_ref_mh), "bound_ref"), "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
95 assert(!strcmp(entry_name(_adapter_retype_only), "adapter_retype_only"), "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
96 assert(!strcmp(entry_name(_adapter_ricochet), "adapter_ricochet"), "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
97 assert(!strcmp(entry_name(_adapter_opt_unboxi), "adapter_ref_to_prim/unboxi"), "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
98 return true;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
99 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
100 #endif
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
101
1299
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
102
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
103 //------------------------------------------------------------------------------
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
104 // MethodHandles::generate_adapters
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
105 //
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
106 void MethodHandles::generate_adapters() {
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
107 if (!EnableMethodHandles || SystemDictionary::MethodHandle_klass() == NULL) return;
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
108
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
109 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
110
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
111 ResourceMark rm;
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
112 TraceTime timer("MethodHandles adapters generation", TraceStartupTime);
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
113 _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
114 if (_adapter_code == NULL)
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
115 vm_exit_out_of_memory(_adapter_code_size, "CodeCache: no room for MethodHandles adapters");
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
116 CodeBuffer code(_adapter_code->instructions_begin(), _adapter_code->instructions_size());
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
117
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
118 MethodHandlesAdapterGenerator g(&code);
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
119 g.generate();
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
120 }
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
121
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
122
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
123 //------------------------------------------------------------------------------
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
124 // MethodHandlesAdapterGenerator::generate
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
125 //
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
126 void MethodHandlesAdapterGenerator::generate() {
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
127 // Generate generic method handle adapters.
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
128 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
129 ek < MethodHandles::_EK_LIMIT;
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
130 ek = MethodHandles::EntryKind(1 + (int)ek)) {
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
131 StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek));
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
132 MethodHandles::generate_method_handle_stub(_masm, ek);
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
133 }
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
134 }
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
135
9eba43136cb5 6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents: 1142
diff changeset
136
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
137 void MethodHandles::set_enabled(bool z) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
138 if (_enabled != z) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
139 guarantee(z && EnableMethodHandles, "can only enable once, and only if -XX:+EnableMethodHandles");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
140 _enabled = z;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
141 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
142 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
143
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
144 // Note: A method which does not have a TRAPS argument cannot block in the GC
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
145 // or throw exceptions. Such methods are used in this file to do something quick
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
146 // and local, like parse a data structure. For speed, such methods work on plain
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
147 // oops, not handles. Trapping methods uniformly operate on handles.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
148
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
149 methodOop MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
150 klassOop& receiver_limit_result, int& decode_flags_result) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
151 if (vmtarget == NULL) return NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
152 assert(methodOopDesc::nonvirtual_vtable_index < 0, "encoding");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
153 if (vmindex < 0) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
154 // this DMH performs no dispatch; it is directly bound to a methodOop
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
155 // A MemberName may either be directly bound to a methodOop,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
156 // or it may use the klass/index form; both forms mean the same thing.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
157 methodOop m = decode_methodOop(methodOop(vmtarget), decode_flags_result);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
158 if ((decode_flags_result & _dmf_has_receiver) != 0
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
159 && java_dyn_MethodType::is_instance(mtype)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
160 // Extract receiver type restriction from mtype.ptypes[0].
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
161 objArrayOop ptypes = java_dyn_MethodType::ptypes(mtype);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
162 oop ptype0 = (ptypes == NULL || ptypes->length() < 1) ? oop(NULL) : ptypes->obj_at(0);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
163 if (java_lang_Class::is_instance(ptype0))
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
164 receiver_limit_result = java_lang_Class::as_klassOop(ptype0);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
165 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
166 if (vmindex == methodOopDesc::nonvirtual_vtable_index) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
167 // this DMH can be an "invokespecial" version
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
168 decode_flags_result &= ~_dmf_does_dispatch;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
169 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
170 assert(vmindex == methodOopDesc::invalid_vtable_index, "random vmindex?");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
171 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
172 return m;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
173 } else {
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1059
diff changeset
174 assert(vmtarget->is_klass(), "must be class or interface");
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
175 decode_flags_result |= MethodHandles::_dmf_does_dispatch;
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1059
diff changeset
176 decode_flags_result |= MethodHandles::_dmf_has_receiver;
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
177 receiver_limit_result = (klassOop)vmtarget;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
178 Klass* tk = Klass::cast((klassOop)vmtarget);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
179 if (tk->is_interface()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
180 // an itable linkage is <interface, itable index>
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
181 decode_flags_result |= MethodHandles::_dmf_from_interface;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
182 return klassItable::method_for_itable_index((klassOop)vmtarget, vmindex);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
183 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
184 if (!tk->oop_is_instance())
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1138
diff changeset
185 tk = instanceKlass::cast(SystemDictionary::Object_klass());
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
186 return ((instanceKlass*)tk)->method_at_vtable(vmindex);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
187 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
188 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
189 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
190
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
191 // MemberName and DirectMethodHandle have the same linkage to the JVM internals.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
192 // (MemberName is the non-operational name used for queries and setup.)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
193
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
194 methodOop MethodHandles::decode_DirectMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
195 oop vmtarget = sun_dyn_DirectMethodHandle::vmtarget(mh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
196 int vmindex = sun_dyn_DirectMethodHandle::vmindex(mh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
197 oop mtype = sun_dyn_DirectMethodHandle::type(mh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
198 return decode_vmtarget(vmtarget, vmindex, mtype, receiver_limit_result, decode_flags_result);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
199 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
200
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
201 methodOop MethodHandles::decode_BoundMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) {
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
202 assert(sun_dyn_BoundMethodHandle::is_instance(mh), "");
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
203 assert(mh->klass() != SystemDictionary::AdapterMethodHandle_klass(), "");
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
204 for (oop bmh = mh;;) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
205 // Bound MHs can be stacked to bind several arguments.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
206 oop target = java_dyn_MethodHandle::vmtarget(bmh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
207 if (target == NULL) return NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
208 decode_flags_result |= MethodHandles::_dmf_binds_argument;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
209 klassOop tk = target->klass();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
210 if (tk == SystemDictionary::BoundMethodHandle_klass()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
211 bmh = target;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
212 continue;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
213 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
214 if (java_dyn_MethodHandle::is_subclass(tk)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
215 //assert(tk == SystemDictionary::DirectMethodHandle_klass(), "end of BMH chain must be DMH");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
216 return decode_MethodHandle(target, receiver_limit_result, decode_flags_result);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
217 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
218 // Optimized case: binding a receiver to a non-dispatched DMH
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
219 // short-circuits directly to the methodOop.
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
220 // (It might be another argument besides a receiver also.)
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
221 assert(target->is_method(), "must be a simple method");
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1059
diff changeset
222 decode_flags_result |= MethodHandles::_dmf_binds_method;
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
223 methodOop m = (methodOop) target;
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1059
diff changeset
224 if (!m->is_static())
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1059
diff changeset
225 decode_flags_result |= MethodHandles::_dmf_has_receiver;
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
226 return m;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
227 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
228 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
229 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
230 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
231
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
232 methodOop MethodHandles::decode_AdapterMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
233 assert(mh->klass() == SystemDictionary::AdapterMethodHandle_klass(), "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
234 for (oop amh = mh;;) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
235 // Adapter MHs can be stacked to convert several arguments.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
236 int conv_op = adapter_conversion_op(sun_dyn_AdapterMethodHandle::conversion(amh));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
237 decode_flags_result |= (_dmf_adapter_lsb << conv_op) & _DMF_ADAPTER_MASK;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
238 oop target = java_dyn_MethodHandle::vmtarget(amh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
239 if (target == NULL) return NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
240 klassOop tk = target->klass();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
241 if (tk == SystemDictionary::AdapterMethodHandle_klass()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
242 amh = target;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
243 continue;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
244 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
245 // must be a BMH (which will bind some more arguments) or a DMH (for the final call)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
246 return MethodHandles::decode_MethodHandle(target, receiver_limit_result, decode_flags_result);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
247 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
248 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
249 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
250
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
251 methodOop MethodHandles::decode_MethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
252 if (mh == NULL) return NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
253 klassOop mhk = mh->klass();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
254 assert(java_dyn_MethodHandle::is_subclass(mhk), "must be a MethodHandle");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
255 if (mhk == SystemDictionary::DirectMethodHandle_klass()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
256 return decode_DirectMethodHandle(mh, receiver_limit_result, decode_flags_result);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
257 } else if (mhk == SystemDictionary::BoundMethodHandle_klass()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
258 return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
259 } else if (mhk == SystemDictionary::AdapterMethodHandle_klass()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
260 return decode_AdapterMethodHandle(mh, receiver_limit_result, decode_flags_result);
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
261 } else if (sun_dyn_BoundMethodHandle::is_subclass(mhk)) {
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
262 // could be a JavaMethodHandle (but not an adapter MH)
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
263 return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result);
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
264 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
265 assert(false, "cannot parse this MH");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
266 return NULL; // random MH?
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
267 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
268 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
269
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
270 methodOop MethodHandles::decode_methodOop(methodOop m, int& decode_flags_result) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
271 assert(m->is_method(), "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
272 if (m->is_static()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
273 // check that signature begins '(L' or '([' (not '(I', '()', etc.)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
274 symbolOop sig = m->signature();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
275 BasicType recv_bt = char2type(sig->byte_at(1));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
276 // Note: recv_bt might be T_ILLEGAL if byte_at(2) is ')'
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
277 assert(sig->byte_at(0) == '(', "must be method sig");
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1059
diff changeset
278 // if (recv_bt == T_OBJECT || recv_bt == T_ARRAY)
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1059
diff changeset
279 // decode_flags_result |= _dmf_has_receiver;
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
280 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
281 // non-static method
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
282 decode_flags_result |= _dmf_has_receiver;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
283 if (!m->can_be_statically_bound() && !m->is_initializer()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
284 decode_flags_result |= _dmf_does_dispatch;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
285 if (Klass::cast(m->method_holder())->is_interface())
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
286 decode_flags_result |= _dmf_from_interface;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
287 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
288 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
289 return m;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
290 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
291
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
292
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
293 // A trusted party is handing us a cookie to determine a method.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
294 // Let's boil it down to the method oop they really want.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
295 methodOop MethodHandles::decode_method(oop x, klassOop& receiver_limit_result, int& decode_flags_result) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
296 decode_flags_result = 0;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
297 receiver_limit_result = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
298 klassOop xk = x->klass();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
299 if (xk == Universe::methodKlassObj()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
300 return decode_methodOop((methodOop) x, decode_flags_result);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
301 } else if (xk == SystemDictionary::MemberName_klass()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
302 // Note: This only works if the MemberName has already been resolved.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
303 return decode_MemberName(x, receiver_limit_result, decode_flags_result);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
304 } else if (java_dyn_MethodHandle::is_subclass(xk)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
305 return decode_MethodHandle(x, receiver_limit_result, decode_flags_result);
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1138
diff changeset
306 } else if (xk == SystemDictionary::reflect_Method_klass()) {
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
307 oop clazz = java_lang_reflect_Method::clazz(x);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
308 int slot = java_lang_reflect_Method::slot(x);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
309 klassOop k = java_lang_Class::as_klassOop(clazz);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
310 if (k != NULL && Klass::cast(k)->oop_is_instance())
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
311 return decode_methodOop(instanceKlass::cast(k)->method_with_idnum(slot),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
312 decode_flags_result);
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1138
diff changeset
313 } else if (xk == SystemDictionary::reflect_Constructor_klass()) {
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
314 oop clazz = java_lang_reflect_Constructor::clazz(x);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
315 int slot = java_lang_reflect_Constructor::slot(x);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
316 klassOop k = java_lang_Class::as_klassOop(clazz);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
317 if (k != NULL && Klass::cast(k)->oop_is_instance())
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
318 return decode_methodOop(instanceKlass::cast(k)->method_with_idnum(slot),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
319 decode_flags_result);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
320 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
321 // unrecognized object
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
322 assert(!x->is_method(), "already checked");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
323 assert(!sun_dyn_MemberName::is_instance(x), "already checked");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
324 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
325 return NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
326 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
327
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
328
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
329 int MethodHandles::decode_MethodHandle_stack_pushes(oop mh) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
330 if (mh->klass() == SystemDictionary::DirectMethodHandle_klass())
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
331 return 0; // no push/pop
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
332 int this_vmslots = java_dyn_MethodHandle::vmslots(mh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
333 int last_vmslots = 0;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
334 oop last_mh = mh;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
335 for (;;) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
336 oop target = java_dyn_MethodHandle::vmtarget(last_mh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
337 if (target->klass() == SystemDictionary::DirectMethodHandle_klass()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
338 last_vmslots = java_dyn_MethodHandle::vmslots(target);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
339 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
340 } else if (!java_dyn_MethodHandle::is_instance(target)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
341 // might be klass or method
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
342 assert(target->is_method(), "must get here with a direct ref to method");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
343 last_vmslots = methodOop(target)->size_of_parameters();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
344 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
345 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
346 last_mh = target;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
347 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
348 // If I am called with fewer VM slots than my ultimate callee,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
349 // it must be that I push the additionally needed slots.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
350 // Likewise if am called with more VM slots, I will pop them.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
351 return (last_vmslots - this_vmslots);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
352 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
353
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
354
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
355 // MemberName support
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
356
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
357 // import sun_dyn_MemberName.*
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
358 enum {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
359 IS_METHOD = sun_dyn_MemberName::MN_IS_METHOD,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
360 IS_CONSTRUCTOR = sun_dyn_MemberName::MN_IS_CONSTRUCTOR,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
361 IS_FIELD = sun_dyn_MemberName::MN_IS_FIELD,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
362 IS_TYPE = sun_dyn_MemberName::MN_IS_TYPE,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
363 SEARCH_SUPERCLASSES = sun_dyn_MemberName::MN_SEARCH_SUPERCLASSES,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
364 SEARCH_INTERFACES = sun_dyn_MemberName::MN_SEARCH_INTERFACES,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
365 ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
366 VM_INDEX_UNINITIALIZED = sun_dyn_MemberName::VM_INDEX_UNINITIALIZED
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
367 };
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
368
1507
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
369 Handle MethodHandles::new_MemberName(TRAPS) {
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
370 Handle empty;
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
371 instanceKlassHandle k(THREAD, SystemDictionary::MemberName_klass());
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
372 if (!k->is_initialized()) k->initialize(CHECK_(empty));
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
373 return Handle(THREAD, k->allocate_instance(THREAD));
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
374 }
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
375
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
376 void MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1138
diff changeset
377 if (target_oop->klass() == SystemDictionary::reflect_Field_klass()) {
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
378 oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder()
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
379 int slot = java_lang_reflect_Field::slot(target_oop); // fd.index()
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
380 int mods = java_lang_reflect_Field::modifiers(target_oop);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
381 klassOop k = java_lang_Class::as_klassOop(clazz);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
382 int offset = instanceKlass::cast(k)->offset_from_fields(slot);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
383 init_MemberName(mname_oop, k, accessFlags_from(mods), offset);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
384 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
385 int decode_flags = 0; klassOop receiver_limit = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
386 methodOop m = MethodHandles::decode_method(target_oop,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
387 receiver_limit, decode_flags);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
388 bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
389 init_MemberName(mname_oop, m, do_dispatch);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
390 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
391 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
392
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
393 void MethodHandles::init_MemberName(oop mname_oop, methodOop m, bool do_dispatch) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
394 int flags = ((m->is_initializer() ? IS_CONSTRUCTOR : IS_METHOD)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
395 | (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
396 oop vmtarget = m;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
397 int vmindex = methodOopDesc::invalid_vtable_index; // implies no info yet
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
398 if (!do_dispatch || (flags & IS_CONSTRUCTOR) || m->can_be_statically_bound())
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
399 vmindex = methodOopDesc::nonvirtual_vtable_index; // implies never any dispatch
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
400 assert(vmindex != VM_INDEX_UNINITIALIZED, "Java sentinel value");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
401 sun_dyn_MemberName::set_vmtarget(mname_oop, vmtarget);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
402 sun_dyn_MemberName::set_vmindex(mname_oop, vmindex);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
403 sun_dyn_MemberName::set_flags(mname_oop, flags);
1507
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
404 sun_dyn_MemberName::set_clazz(mname_oop, Klass::cast(m->method_holder())->java_mirror());
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
405 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
406
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
407 void MethodHandles::init_MemberName(oop mname_oop, klassOop field_holder, AccessFlags mods, int offset) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
408 int flags = (IS_FIELD | (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
409 oop vmtarget = field_holder;
1507
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
410 int vmindex = offset; // determines the field uniquely when combined with static bit
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
411 assert(vmindex != VM_INDEX_UNINITIALIZED, "bad alias on vmindex");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
412 sun_dyn_MemberName::set_vmtarget(mname_oop, vmtarget);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
413 sun_dyn_MemberName::set_vmindex(mname_oop, vmindex);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
414 sun_dyn_MemberName::set_flags(mname_oop, flags);
1507
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
415 sun_dyn_MemberName::set_clazz(mname_oop, Klass::cast(field_holder)->java_mirror());
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
416 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
417
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
418
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
419 methodOop MethodHandles::decode_MemberName(oop mname, klassOop& receiver_limit_result, int& decode_flags_result) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
420 int flags = sun_dyn_MemberName::flags(mname);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
421 if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) == 0) return NULL; // not invocable
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
422 oop vmtarget = sun_dyn_MemberName::vmtarget(mname);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
423 int vmindex = sun_dyn_MemberName::vmindex(mname);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
424 if (vmindex == VM_INDEX_UNINITIALIZED) return NULL; // not resolved
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
425 methodOop m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result);
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
426 oop clazz = sun_dyn_MemberName::clazz(mname);
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
427 if (clazz != NULL && java_lang_Class::is_instance(clazz)) {
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
428 klassOop klass = java_lang_Class::as_klassOop(clazz);
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
429 if (klass != NULL) receiver_limit_result = klass;
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
430 }
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
431 return m;
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
432 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
433
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
434 // An unresolved member name is a mere symbolic reference.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
435 // Resolving it plants a vmtarget/vmindex in it,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
436 // which refers dirctly to JVM internals.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
437 void MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
438 assert(sun_dyn_MemberName::is_instance(mname()), "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
439 #ifdef ASSERT
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
440 // If this assert throws, renegotiate the sentinel value used by the Java code,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
441 // so that it is distinct from any valid vtable index value, and any special
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
442 // values defined in methodOopDesc::VtableIndexFlag.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
443 // The point of the slop is to give the Java code and the JVM some room
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
444 // to independently specify sentinel values.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
445 const int sentinel_slop = 10;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
446 const int sentinel_limit = methodOopDesc::highest_unused_vtable_index_value - sentinel_slop;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
447 assert(VM_INDEX_UNINITIALIZED < sentinel_limit, "Java sentinel != JVM sentinels");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
448 #endif
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
449 if (sun_dyn_MemberName::vmindex(mname()) != VM_INDEX_UNINITIALIZED)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
450 return; // already resolved
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
451 oop defc_oop = sun_dyn_MemberName::clazz(mname());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
452 oop name_str = sun_dyn_MemberName::name(mname());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
453 oop type_str = sun_dyn_MemberName::type(mname());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
454 int flags = sun_dyn_MemberName::flags(mname());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
455
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
456 if (defc_oop == NULL || name_str == NULL || type_str == NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
457 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
458 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
459 klassOop defc_klassOop = java_lang_Class::as_klassOop(defc_oop);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
460 defc_oop = NULL; // safety
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
461 if (defc_klassOop == NULL) return; // a primitive; no resolution possible
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
462 if (!Klass::cast(defc_klassOop)->oop_is_instance()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
463 if (!Klass::cast(defc_klassOop)->oop_is_array()) return;
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1138
diff changeset
464 defc_klassOop = SystemDictionary::Object_klass();
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
465 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
466 instanceKlassHandle defc(THREAD, defc_klassOop);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
467 defc_klassOop = NULL; // safety
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
468 if (defc.is_null()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
469 THROW_MSG(vmSymbols::java_lang_InternalError(), "primitive class");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
470 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
471 defc->link_class(CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
472
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
473 // convert the external string name to an internal symbol
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
474 symbolHandle name(THREAD, java_lang_String::as_symbol_or_null(name_str));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
475 if (name.is_null()) return; // no such name
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
476 name_str = NULL; // safety
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
477
1508
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
478 Handle polymorphic_method_type;
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
479 bool polymorphic_signature = false;
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
480 if ((flags & ALL_KINDS) == IS_METHOD &&
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
481 (defc() == SystemDictionary::InvokeDynamic_klass() ||
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
482 (defc() == SystemDictionary::MethodHandle_klass() &&
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
483 methodOopDesc::is_method_handle_invoke_name(name()))))
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
484 polymorphic_signature = true;
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
485
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
486 // convert the external string or reflective type to an internal signature
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
487 symbolHandle type; {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
488 symbolOop type_sym = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
489 if (java_dyn_MethodType::is_instance(type_str)) {
1508
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
490 type_sym = java_dyn_MethodType::as_signature(type_str, polymorphic_signature, CHECK);
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
491 if (polymorphic_signature)
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
492 polymorphic_method_type = Handle(THREAD, type_str); //preserve exactly
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
493 } else if (java_lang_Class::is_instance(type_str)) {
1508
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
494 type_sym = java_lang_Class::as_signature(type_str, false, CHECK);
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
495 } else if (java_lang_String::is_instance(type_str)) {
1508
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
496 if (polymorphic_signature) {
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
497 type = java_lang_String::as_symbol(type_str, CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
498 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
499 type_sym = java_lang_String::as_symbol_or_null(type_str);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
500 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
501 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
502 THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized type");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
503 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
504 if (type_sym != NULL)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
505 type = symbolHandle(THREAD, type_sym);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
506 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
507 if (type.is_null()) return; // no such signature exists in the VM
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
508 type_str = NULL; // safety
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
509
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
510 // Time to do the lookup.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
511 switch (flags & ALL_KINDS) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
512 case IS_METHOD:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
513 {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
514 CallInfo result;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
515 {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
516 EXCEPTION_MARK;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
517 if ((flags & JVM_ACC_STATIC) != 0) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
518 LinkResolver::resolve_static_call(result,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
519 defc, name, type, KlassHandle(), false, false, THREAD);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
520 } else if (defc->is_interface()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
521 LinkResolver::resolve_interface_call(result, Handle(), defc,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
522 defc, name, type, KlassHandle(), false, false, THREAD);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
523 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
524 LinkResolver::resolve_virtual_call(result, Handle(), defc,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
525 defc, name, type, KlassHandle(), false, false, THREAD);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
526 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
527 if (HAS_PENDING_EXCEPTION) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
528 CLEAR_PENDING_EXCEPTION;
1508
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
529 break; // go to second chance
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
530 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
531 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
532 methodHandle m = result.resolved_method();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
533 oop vmtarget = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
534 int vmindex = methodOopDesc::nonvirtual_vtable_index;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
535 if (defc->is_interface()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
536 vmindex = klassItable::compute_itable_index(m());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
537 assert(vmindex >= 0, "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
538 } else if (result.has_vtable_index()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
539 vmindex = result.vtable_index();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
540 assert(vmindex >= 0, "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
541 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
542 assert(vmindex != VM_INDEX_UNINITIALIZED, "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
543 if (vmindex < 0) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
544 assert(result.is_statically_bound(), "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
545 vmtarget = m();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
546 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
547 vmtarget = result.resolved_klass()->as_klassOop();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
548 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
549 int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
550 sun_dyn_MemberName::set_vmtarget(mname(), vmtarget);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
551 sun_dyn_MemberName::set_vmindex(mname(), vmindex);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
552 sun_dyn_MemberName::set_modifiers(mname(), mods);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
553 DEBUG_ONLY(int junk; klassOop junk2);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
554 assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
555 "properly stored for later decoding");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
556 return;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
557 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
558 case IS_CONSTRUCTOR:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
559 {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
560 CallInfo result;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
561 {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
562 EXCEPTION_MARK;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
563 if (name() == vmSymbols::object_initializer_name()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
564 LinkResolver::resolve_special_call(result,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
565 defc, name, type, KlassHandle(), false, THREAD);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
566 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
567 break; // will throw after end of switch
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
568 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
569 if (HAS_PENDING_EXCEPTION) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
570 CLEAR_PENDING_EXCEPTION;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
571 return;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
572 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
573 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
574 assert(result.is_statically_bound(), "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
575 methodHandle m = result.resolved_method();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
576 oop vmtarget = m();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
577 int vmindex = methodOopDesc::nonvirtual_vtable_index;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
578 int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
579 sun_dyn_MemberName::set_vmtarget(mname(), vmtarget);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
580 sun_dyn_MemberName::set_vmindex(mname(), vmindex);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
581 sun_dyn_MemberName::set_modifiers(mname(), mods);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
582 DEBUG_ONLY(int junk; klassOop junk2);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
583 assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
584 "properly stored for later decoding");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
585 return;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
586 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
587 case IS_FIELD:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
588 {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
589 // This is taken from LinkResolver::resolve_field, sans access checks.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
590 fieldDescriptor fd; // find_field initializes fd if found
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
591 KlassHandle sel_klass(THREAD, instanceKlass::cast(defc())->find_field(name(), type(), &fd));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
592 // check if field exists; i.e., if a klass containing the field def has been selected
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
593 if (sel_klass.is_null()) return;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
594 oop vmtarget = sel_klass->as_klassOop();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
595 int vmindex = fd.offset();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
596 int mods = (fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
597 if (vmindex == VM_INDEX_UNINITIALIZED) break; // should not happen
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
598 sun_dyn_MemberName::set_vmtarget(mname(), vmtarget);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
599 sun_dyn_MemberName::set_vmindex(mname(), vmindex);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
600 sun_dyn_MemberName::set_modifiers(mname(), mods);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
601 return;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
602 }
1508
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
603 default:
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
604 THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format");
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
605 }
1508
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
606
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
607 // Second chance.
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
608 if (polymorphic_method_type.not_null()) {
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
609 // 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
610 Handle cur_class_loader;
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
611 const int nptypes = java_dyn_MethodType::ptype_count(polymorphic_method_type());
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
612 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
613 oop type_mirror;
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
614 if (i < nptypes) type_mirror = java_dyn_MethodType::ptype(polymorphic_method_type(), i);
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
615 else type_mirror = java_dyn_MethodType::rtype(polymorphic_method_type());
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
616 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
617 if (example_type == NULL) continue;
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
618 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
619 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
620 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
621 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
622 type,
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
623 KlassHandle(THREAD, example_type),
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
624 THREAD);
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
625 if (HAS_PENDING_EXCEPTION) {
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
626 CLEAR_PENDING_EXCEPTION;
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
627 m = NULL;
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
628 // 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
629 }
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
630 if (m != NULL) {
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
631 int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS);
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
632 sun_dyn_MemberName::set_vmtarget(mname(), m);
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
633 sun_dyn_MemberName::set_vmindex(mname(), m->vtable_index());
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
634 sun_dyn_MemberName::set_modifiers(mname(), mods);
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
635 return;
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
636 }
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
637 }
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
638 }
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
639 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
640
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
641 // Conversely, a member name which is only initialized from JVM internals
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
642 // may have null defc, name, and type fields.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
643 // Resolving it plants a vmtarget/vmindex in it,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
644 // which refers directly to JVM internals.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
645 void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
646 assert(sun_dyn_MemberName::is_instance(mname()), "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
647 oop vmtarget = sun_dyn_MemberName::vmtarget(mname());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
648 int vmindex = sun_dyn_MemberName::vmindex(mname());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
649 if (vmtarget == NULL || vmindex == VM_INDEX_UNINITIALIZED) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
650 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to expand");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
651 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
652
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
653 bool have_defc = (sun_dyn_MemberName::clazz(mname()) != NULL);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
654 bool have_name = (sun_dyn_MemberName::name(mname()) != NULL);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
655 bool have_type = (sun_dyn_MemberName::type(mname()) != NULL);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
656 int flags = sun_dyn_MemberName::flags(mname());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
657
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
658 if (suppress != 0) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
659 if (suppress & _suppress_defc) have_defc = true;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
660 if (suppress & _suppress_name) have_name = true;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
661 if (suppress & _suppress_type) have_type = true;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
662 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
663
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
664 if (have_defc && have_name && have_type) return; // nothing needed
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
665
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
666 switch (flags & ALL_KINDS) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
667 case IS_METHOD:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
668 case IS_CONSTRUCTOR:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
669 {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
670 klassOop receiver_limit = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
671 int decode_flags = 0;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
672 methodHandle m(THREAD, decode_vmtarget(vmtarget, vmindex, NULL,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
673 receiver_limit, decode_flags));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
674 if (m.is_null()) break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
675 if (!have_defc) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
676 klassOop defc = m->method_holder();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
677 if (receiver_limit != NULL && receiver_limit != defc
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
678 && Klass::cast(receiver_limit)->is_subtype_of(defc))
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
679 defc = receiver_limit;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
680 sun_dyn_MemberName::set_clazz(mname(), Klass::cast(defc)->java_mirror());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
681 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
682 if (!have_name) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
683 //not java_lang_String::create_from_symbol; let's intern member names
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
684 Handle name = StringTable::intern(m->name(), CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
685 sun_dyn_MemberName::set_name(mname(), name());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
686 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
687 if (!have_type) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
688 Handle type = java_lang_String::create_from_symbol(m->signature(), CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
689 sun_dyn_MemberName::set_type(mname(), type());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
690 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
691 return;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
692 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
693 case IS_FIELD:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
694 {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
695 // This is taken from LinkResolver::resolve_field, sans access checks.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
696 if (!vmtarget->is_klass()) break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
697 if (!Klass::cast((klassOop) vmtarget)->oop_is_instance()) break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
698 instanceKlassHandle defc(THREAD, (klassOop) vmtarget);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
699 bool is_static = ((flags & JVM_ACC_STATIC) != 0);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
700 fieldDescriptor fd; // find_field initializes fd if found
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
701 if (!defc->find_field_from_offset(vmindex, is_static, &fd))
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
702 break; // cannot expand
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
703 if (!have_defc) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
704 sun_dyn_MemberName::set_clazz(mname(), defc->java_mirror());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
705 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
706 if (!have_name) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
707 //not java_lang_String::create_from_symbol; let's intern member names
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
708 Handle name = StringTable::intern(fd.name(), CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
709 sun_dyn_MemberName::set_name(mname(), name());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
710 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
711 if (!have_type) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
712 Handle type = java_lang_String::create_from_symbol(fd.signature(), CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
713 sun_dyn_MemberName::set_type(mname(), type());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
714 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
715 return;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
716 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
717 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
718 THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
719 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
720
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
721 int MethodHandles::find_MemberNames(klassOop k,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
722 symbolOop name, symbolOop sig,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
723 int mflags, klassOop caller,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
724 int skip, objArrayOop results) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
725 DEBUG_ONLY(No_Safepoint_Verifier nsv);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
726 // this code contains no safepoints!
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
727
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
728 // %%% take caller into account!
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
729
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
730 if (k == NULL || !Klass::cast(k)->oop_is_instance()) return -1;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
731
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
732 int rfill = 0, rlimit = results->length(), rskip = skip;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
733 // overflow measurement:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
734 int overflow = 0, overflow_limit = MAX2(1000, rlimit);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
735
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
736 int match_flags = mflags;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
737 bool search_superc = ((match_flags & SEARCH_SUPERCLASSES) != 0);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
738 bool search_intfc = ((match_flags & SEARCH_INTERFACES) != 0);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
739 bool local_only = !(search_superc | search_intfc);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
740 bool classes_only = false;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
741
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
742 if (name != NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
743 if (name->utf8_length() == 0) return 0; // a match is not possible
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
744 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
745 if (sig != NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
746 if (sig->utf8_length() == 0) return 0; // a match is not possible
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
747 if (sig->byte_at(0) == '(')
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
748 match_flags &= ~(IS_FIELD | IS_TYPE);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
749 else
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
750 match_flags &= ~(IS_CONSTRUCTOR | IS_METHOD);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
751 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
752
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
753 if ((match_flags & IS_TYPE) != 0) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
754 // NYI, and Core Reflection works quite well for this query
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
755 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
756
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
757 if ((match_flags & IS_FIELD) != 0) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
758 for (FieldStream st(k, local_only, !search_intfc); !st.eos(); st.next()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
759 if (name != NULL && st.name() != name)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
760 continue;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
761 if (sig != NULL && st.signature() != sig)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
762 continue;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
763 // passed the filters
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
764 if (rskip > 0) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
765 --rskip;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
766 } else if (rfill < rlimit) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
767 oop result = results->obj_at(rfill++);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
768 if (!sun_dyn_MemberName::is_instance(result))
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
769 return -99; // caller bug!
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
770 MethodHandles::init_MemberName(result, st.klass()->as_klassOop(), st.access_flags(), st.offset());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
771 } else if (++overflow >= overflow_limit) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
772 match_flags = 0; break; // got tired of looking at overflow
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
773 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
774 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
775 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
776
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
777 if ((match_flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
778 // watch out for these guys:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
779 symbolOop init_name = vmSymbols::object_initializer_name();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
780 symbolOop clinit_name = vmSymbols::class_initializer_name();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
781 if (name == clinit_name) clinit_name = NULL; // hack for exposing <clinit>
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
782 bool negate_name_test = false;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
783 // fix name so that it captures the intention of IS_CONSTRUCTOR
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
784 if (!(match_flags & IS_METHOD)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
785 // constructors only
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
786 if (name == NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
787 name = init_name;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
788 } else if (name != init_name) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
789 return 0; // no constructors of this method name
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
790 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
791 } else if (!(match_flags & IS_CONSTRUCTOR)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
792 // methods only
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
793 if (name == NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
794 name = init_name;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
795 negate_name_test = true; // if we see the name, we *omit* the entry
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
796 } else if (name == init_name) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
797 return 0; // no methods of this constructor name
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
798 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
799 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
800 // caller will accept either sort; no need to adjust name
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
801 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
802 for (MethodStream st(k, local_only, !search_intfc); !st.eos(); st.next()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
803 methodOop m = st.method();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
804 symbolOop m_name = m->name();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
805 if (m_name == clinit_name)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
806 continue;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
807 if (name != NULL && ((m_name != name) ^ negate_name_test))
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
808 continue;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
809 if (sig != NULL && m->signature() != sig)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
810 continue;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
811 // passed the filters
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
812 if (rskip > 0) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
813 --rskip;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
814 } else if (rfill < rlimit) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
815 oop result = results->obj_at(rfill++);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
816 if (!sun_dyn_MemberName::is_instance(result))
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
817 return -99; // caller bug!
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
818 MethodHandles::init_MemberName(result, m, true);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
819 } else if (++overflow >= overflow_limit) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
820 match_flags = 0; break; // got tired of looking at overflow
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
821 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
822 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
823 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
824
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
825 // return number of elements we at leasted wanted to initialize
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
826 return rfill + overflow;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
827 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
828
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
829
1507
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
830 // 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
831 // Throw IAE if not
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
832 instanceKlassHandle MethodHandles::resolve_instance_klass(oop java_mirror_oop, TRAPS) {
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
833 instanceKlassHandle empty;
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
834 klassOop caller = NULL;
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
835 if (java_lang_Class::is_instance(java_mirror_oop)) {
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
836 caller = java_lang_Class::as_klassOop(java_mirror_oop);
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
837 }
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
838 if (caller == NULL || !Klass::cast(caller)->oop_is_instance()) {
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
839 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "not a class", empty);
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
840 }
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
841 return instanceKlassHandle(THREAD, caller);
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
842 }
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
843
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
844
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
845
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
846 // Decode the vmtarget field of a method handle.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
847 // Sanitize out methodOops, klassOops, and any other non-Java data.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
848 // This is for debugging and reflection.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
849 oop MethodHandles::encode_target(Handle mh, int format, TRAPS) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
850 assert(java_dyn_MethodHandle::is_instance(mh()), "must be a MH");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
851 if (format == ETF_HANDLE_OR_METHOD_NAME) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
852 oop target = java_dyn_MethodHandle::vmtarget(mh());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
853 if (target == NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
854 return NULL; // unformed MH
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
855 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
856 klassOop tklass = target->klass();
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1138
diff changeset
857 if (Klass::cast(tklass)->is_subclass_of(SystemDictionary::Object_klass())) {
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
858 return target; // target is another MH (or something else?)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
859 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
860 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
861 if (format == ETF_DIRECT_HANDLE) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
862 oop target = mh();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
863 for (;;) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
864 if (target->klass() == SystemDictionary::DirectMethodHandle_klass()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
865 return target;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
866 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
867 if (!java_dyn_MethodHandle::is_instance(target)){
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
868 return NULL; // unformed MH
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
869 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
870 target = java_dyn_MethodHandle::vmtarget(target);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
871 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
872 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
873 // cases of metadata in MH.vmtarget:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
874 // - AMH can have methodOop for static invoke with bound receiver
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
875 // - DMH can have methodOop for static invoke (on variable receiver)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
876 // - DMH can have klassOop for dispatched (non-static) invoke
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
877 klassOop receiver_limit = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
878 int decode_flags = 0;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
879 methodOop m = decode_MethodHandle(mh(), receiver_limit, decode_flags);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
880 if (m == NULL) return NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
881 switch (format) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
882 case ETF_REFLECT_METHOD:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
883 // same as jni_ToReflectedMethod:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
884 if (m->is_initializer()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
885 return Reflection::new_constructor(m, THREAD);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
886 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
887 return Reflection::new_method(m, UseNewReflection, false, THREAD);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
888 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
889
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
890 case ETF_HANDLE_OR_METHOD_NAME: // method, not handle
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
891 case ETF_METHOD_NAME:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
892 {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
893 if (SystemDictionary::MemberName_klass() == NULL) break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
894 instanceKlassHandle mname_klass(THREAD, SystemDictionary::MemberName_klass());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
895 mname_klass->initialize(CHECK_NULL);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
896 Handle mname = mname_klass->allocate_instance_handle(CHECK_NULL);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
897 sun_dyn_MemberName::set_vmindex(mname(), VM_INDEX_UNINITIALIZED);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
898 bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
899 init_MemberName(mname(), m, do_dispatch);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
900 expand_MemberName(mname, 0, CHECK_NULL);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
901 return mname();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
902 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
903 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
904
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
905 // Unknown format code.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
906 char msg[50];
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
907 jio_snprintf(msg, sizeof(msg), "unknown getTarget format=%d", format);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
908 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), msg);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
909 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
910
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
911 static const char* always_null_names[] = {
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
912 "java/lang/Void",
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
913 "java/lang/Null",
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
914 //"java/lang/Nothing",
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
915 "sun/dyn/empty/Empty",
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
916 NULL
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
917 };
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
918
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
919 static bool is_always_null_type(klassOop klass) {
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
920 if (!Klass::cast(klass)->oop_is_instance()) return false;
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
921 instanceKlass* ik = instanceKlass::cast(klass);
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
922 // Must be on the boot class path:
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
923 if (ik->class_loader() != NULL) return false;
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
924 // Check the name.
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
925 symbolOop name = ik->name();
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
926 for (int i = 0; ; i++) {
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
927 const char* test_name = always_null_names[i];
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
928 if (test_name == NULL) break;
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1059
diff changeset
929 if (name->equals(test_name))
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
930 return true;
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
931 }
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
932 return false;
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
933 }
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
934
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
935 bool MethodHandles::class_cast_needed(klassOop src, klassOop dst) {
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1138
diff changeset
936 if (src == dst || dst == SystemDictionary::Object_klass())
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
937 return false; // quickest checks
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
938 Klass* srck = Klass::cast(src);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
939 Klass* dstk = Klass::cast(dst);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
940 if (dstk->is_interface()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
941 // interface receivers can safely be viewed as untyped,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
942 // because interface calls always include a dynamic check
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1138
diff changeset
943 //dstk = Klass::cast(SystemDictionary::Object_klass());
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
944 return false;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
945 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
946 if (srck->is_interface()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
947 // interface arguments must be viewed as untyped
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1138
diff changeset
948 //srck = Klass::cast(SystemDictionary::Object_klass());
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
949 return true;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
950 }
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
951 if (is_always_null_type(src)) {
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
952 // some source types are known to be never instantiated;
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
953 // they represent references which are always null
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
954 // such null references never fail to convert safely
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
955 return false;
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
956 }
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
957 return !srck->is_subclass_of(dstk->as_klassOop());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
958 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
959
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
960 static oop object_java_mirror() {
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1138
diff changeset
961 return Klass::cast(SystemDictionary::Object_klass())->java_mirror();
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
962 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
963
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
964 bool MethodHandles::same_basic_type_for_arguments(BasicType src,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
965 BasicType dst,
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
966 bool raw,
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
967 bool for_return) {
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
968 if (for_return) {
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
969 // return values can always be forgotten:
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
970 if (dst == T_VOID) return true;
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
971 if (src == T_VOID) return raw && (dst == T_INT);
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
972 // 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
973 // 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
974 }
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
975 assert(src != T_VOID && dst != T_VOID, "should not be here");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
976 if (src == dst) return true;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
977 if (type2size[src] != type2size[dst]) return false;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
978 // allow reinterpretation casts for integral widening
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
979 if (is_subword_type(src)) { // subwords can fit in int or other subwords
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
980 if (dst == T_INT) // any subword fits in an int
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
981 return true;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
982 if (src == T_BOOLEAN) // boolean fits in any subword
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
983 return is_subword_type(dst);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
984 if (src == T_BYTE && dst == T_SHORT)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
985 return true; // remaining case: byte fits in short
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
986 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
987 // allow float/fixed reinterpretation casts
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
988 if (src == T_FLOAT) return dst == T_INT;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
989 if (src == T_INT) return dst == T_FLOAT;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
990 if (src == T_DOUBLE) return dst == T_LONG;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
991 if (src == T_LONG) return dst == T_DOUBLE;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
992 return false;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
993 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
994
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
995 const char* MethodHandles::check_method_receiver(methodOop m,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
996 klassOop passed_recv_type) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
997 assert(!m->is_static(), "caller resp.");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
998 if (passed_recv_type == NULL)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
999 return "receiver type is primitive";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1000 if (class_cast_needed(passed_recv_type, m->method_holder())) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1001 Klass* formal = Klass::cast(m->method_holder());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1002 return SharedRuntime::generate_class_cast_message("receiver type",
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1003 formal->external_name());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1004 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1005 return NULL; // checks passed
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1006 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1007
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1008 // Verify that m's signature can be called type-safely by a method handle
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1009 // of the given method type 'mtype'.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1010 // It takes a TRAPS argument because it must perform symbol lookups.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1011 void MethodHandles::verify_method_signature(methodHandle m,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1012 Handle mtype,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1013 int first_ptype_pos,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1014 KlassHandle insert_ptype,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1015 TRAPS) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1016 objArrayHandle ptypes(THREAD, java_dyn_MethodType::ptypes(mtype()));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1017 int pnum = first_ptype_pos;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1018 int pmax = ptypes->length();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1019 int mnum = 0; // method argument
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1020 const char* err = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1021 for (SignatureStream ss(m->signature()); !ss.is_done(); ss.next()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1022 oop ptype_oop = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1023 if (ss.at_return_type()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1024 if (pnum != pmax)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1025 { err = "too many arguments"; break; }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1026 ptype_oop = java_dyn_MethodType::rtype(mtype());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1027 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1028 if (pnum >= pmax)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1029 { err = "not enough arguments"; break; }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1030 if (pnum >= 0)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1031 ptype_oop = ptypes->obj_at(pnum);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1032 else if (insert_ptype.is_null())
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1033 ptype_oop = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1034 else
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1035 ptype_oop = insert_ptype->java_mirror();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1036 pnum += 1;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1037 mnum += 1;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1038 }
1508
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
1039 klassOop pklass = NULL;
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
1040 BasicType ptype = T_OBJECT;
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
1041 if (ptype_oop != NULL)
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
1042 ptype = java_lang_Class::as_BasicType(ptype_oop, &pklass);
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
1043 else
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
1044 // null does not match any non-reference; use Object to report the error
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
1045 pklass = SystemDictionary::Object_klass();
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1046 klassOop mklass = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1047 BasicType mtype = ss.type();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1048 if (mtype == T_ARRAY) mtype = T_OBJECT; // fold all refs to T_OBJECT
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1049 if (mtype == T_OBJECT) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1050 if (ptype_oop == NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1051 // null matches any reference
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1052 continue;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1053 }
1508
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
1054 KlassHandle pklass_handle(THREAD, pklass); pklass = NULL;
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1055 // If we fail to resolve types at this point, we will throw an error.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1056 symbolOop name_oop = ss.as_symbol(CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1057 symbolHandle name(THREAD, name_oop);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1058 instanceKlass* mk = instanceKlass::cast(m->method_holder());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1059 Handle loader(THREAD, mk->class_loader());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1060 Handle domain(THREAD, mk->protection_domain());
1508
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
1061 mklass = SystemDictionary::resolve_or_null(name, loader, domain, CHECK);
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
1062 pklass = pklass_handle();
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
1063 if (mklass == NULL && pklass != NULL &&
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
1064 Klass::cast(pklass)->name() == name() &&
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
1065 m->is_method_handle_invoke()) {
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
1066 // Assume a match. We can't really decode the signature of MH.invoke*.
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
1067 continue;
2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors
jrose
parents: 1507
diff changeset
1068 }
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1069 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1070 if (!ss.at_return_type()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1071 err = check_argument_type_change(ptype, pklass, mtype, mklass, mnum);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1072 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1073 err = check_return_type_change(mtype, mklass, ptype, pklass); // note reversal!
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1074 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1075 if (err != NULL) break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1076 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1077
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1078 if (err != NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1079 THROW_MSG(vmSymbols::java_lang_InternalError(), err);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1080 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1081 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1082
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1083 // Main routine for verifying the MethodHandle.type of a proposed
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1084 // direct or bound-direct method handle.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1085 void MethodHandles::verify_method_type(methodHandle m,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1086 Handle mtype,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1087 bool has_bound_recv,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1088 KlassHandle bound_recv_type,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1089 TRAPS) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1090 bool m_needs_receiver = !m->is_static();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1091
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1092 const char* err = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1093
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1094 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
1095 if (has_bound_recv) {
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1096 first_ptype_pos -= 1; // ptypes do not include the bound argument; start earlier in them
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1097 if (m_needs_receiver && bound_recv_type.is_null())
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1098 { err = "bound receiver is not an object"; goto die; }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1099 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1100
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1101 if (m_needs_receiver && err == NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1102 objArrayOop ptypes = java_dyn_MethodType::ptypes(mtype());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1103 if (ptypes->length() < first_ptype_pos)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1104 { err = "receiver argument is missing"; goto die; }
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1105 if (has_bound_recv)
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1106 err = check_method_receiver(m(), bound_recv_type->as_klassOop());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1107 else
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1108 err = check_method_receiver(m(), java_lang_Class::as_klassOop(ptypes->obj_at(first_ptype_pos-1)));
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1109 if (err != NULL) goto die;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1110 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1111
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1112 // Check the other arguments for mistypes.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1113 verify_method_signature(m, mtype, first_ptype_pos, bound_recv_type, CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1114 return;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1115
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1116 die:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1117 THROW_MSG(vmSymbols::java_lang_InternalError(), err);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1118 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1119
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1120 void MethodHandles::verify_vmslots(Handle mh, TRAPS) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1121 // Verify vmslots.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1122 int check_slots = argument_slot_count(java_dyn_MethodHandle::type(mh()));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1123 if (java_dyn_MethodHandle::vmslots(mh()) != check_slots) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1124 THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in BMH");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1125 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1126 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1127
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1128 void MethodHandles::verify_vmargslot(Handle mh, int argnum, int argslot, TRAPS) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1129 // Verify that argslot points at the given argnum.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1130 int check_slot = argument_slot(java_dyn_MethodHandle::type(mh()), argnum);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1131 if (argslot != check_slot || argslot < 0) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1132 const char* fmt = "for argnum of %d, vmargslot is %d, should be %d";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1133 size_t msglen = strlen(fmt) + 3*11 + 1;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1134 char* msg = NEW_RESOURCE_ARRAY(char, msglen);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1135 jio_snprintf(msg, msglen, fmt, argnum, argslot, check_slot);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1136 THROW_MSG(vmSymbols::java_lang_InternalError(), msg);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1137 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1138 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1139
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1140 // Verify the correspondence between two method types.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1141 // Apart from the advertised changes, caller method type X must
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1142 // be able to invoke the callee method Y type with no violations
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1143 // of type integrity.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1144 // Return NULL if all is well, else a short error message.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1145 const char* MethodHandles::check_method_type_change(oop src_mtype, int src_beg, int src_end,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1146 int insert_argnum, oop insert_type,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1147 int change_argnum, oop change_type,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1148 int delete_argnum,
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1149 oop dst_mtype, int dst_beg, int dst_end,
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1150 bool raw) {
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1151 objArrayOop src_ptypes = java_dyn_MethodType::ptypes(src_mtype);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1152 objArrayOop dst_ptypes = java_dyn_MethodType::ptypes(dst_mtype);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1153
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1154 int src_max = src_ptypes->length();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1155 int dst_max = dst_ptypes->length();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1156
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1157 if (src_end == -1) src_end = src_max;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1158 if (dst_end == -1) dst_end = dst_max;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1159
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1160 assert(0 <= src_beg && src_beg <= src_end && src_end <= src_max, "oob");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1161 assert(0 <= dst_beg && dst_beg <= dst_end && dst_end <= dst_max, "oob");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1162
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1163 // pending actions; set to -1 when done:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1164 int ins_idx = insert_argnum, chg_idx = change_argnum, del_idx = delete_argnum;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1165
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1166 const char* err = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1167
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1168 // Walk along each array of parameter types, including a virtual
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1169 // NULL end marker at the end of each.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1170 for (int src_idx = src_beg, dst_idx = dst_beg;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1171 (src_idx <= src_end && dst_idx <= dst_end);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1172 src_idx++, dst_idx++) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1173 oop src_type = (src_idx == src_end) ? oop(NULL) : src_ptypes->obj_at(src_idx);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1174 oop dst_type = (dst_idx == dst_end) ? oop(NULL) : dst_ptypes->obj_at(dst_idx);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1175 bool fix_null_src_type = false;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1176
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1177 // Perform requested edits.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1178 if (ins_idx == src_idx) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1179 // note that the inserted guy is never affected by a change or deletion
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1180 ins_idx = -1;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1181 src_type = insert_type;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1182 fix_null_src_type = true;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1183 --src_idx; // back up to process src type on next loop
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1184 src_idx = src_end;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1185 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1186 // note that the changed guy can be immediately deleted
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1187 if (chg_idx == src_idx) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1188 chg_idx = -1;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1189 assert(src_idx < src_end, "oob");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1190 src_type = change_type;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1191 fix_null_src_type = true;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1192 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1193 if (del_idx == src_idx) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1194 del_idx = -1;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1195 assert(src_idx < src_end, "oob");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1196 --dst_idx;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1197 continue; // rerun loop after skipping this position
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1198 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1199 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1200
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1201 if (src_type == NULL && fix_null_src_type)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1202 // explicit null in this case matches any dest reference
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1203 src_type = (java_lang_Class::is_primitive(dst_type) ? object_java_mirror() : dst_type);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1204
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1205 // Compare the two argument types.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1206 if (src_type != dst_type) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1207 if (src_type == NULL) return "not enough arguments";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1208 if (dst_type == NULL) return "too many arguments";
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1209 err = check_argument_type_change(src_type, dst_type, dst_idx, raw);
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1210 if (err != NULL) return err;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1211 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1212 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1213
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1214 // Now compare return types also.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1215 oop src_rtype = java_dyn_MethodType::rtype(src_mtype);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1216 oop dst_rtype = java_dyn_MethodType::rtype(dst_mtype);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1217 if (src_rtype != dst_rtype) {
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1218 err = check_return_type_change(dst_rtype, src_rtype, raw); // note reversal!
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1219 if (err != NULL) return err;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1220 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1221
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1222 assert(err == NULL, "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1223 return NULL; // all is well
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1224 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1225
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1226
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1227 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
1228 klassOop src_klass,
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1229 BasicType dst_type,
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1230 klassOop dst_klass,
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1231 int argnum,
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1232 bool raw) {
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1233 const char* err = NULL;
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1234 bool for_return = (argnum < 0);
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1235
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1236 // just in case:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1237 if (src_type == T_ARRAY) src_type = T_OBJECT;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1238 if (dst_type == T_ARRAY) dst_type = T_OBJECT;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1239
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1240 // 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
1241 if (!same_basic_type_for_arguments(src_type, dst_type, raw, for_return)) {
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1242 if (src_type == T_OBJECT) {
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1243 if (raw && dst_type == T_INT && is_always_null_type(src_klass))
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1244 return NULL; // OK to convert a null pointer to a garbage int
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1245 err = ((argnum >= 0)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1246 ? "type mismatch: passing a %s for method argument #%d, which expects primitive %s"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1247 : "type mismatch: returning a %s, but caller expects primitive %s");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1248 } else if (dst_type == T_OBJECT) {
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1249 err = ((argnum >= 0)
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1250 ? "type mismatch: passing a primitive %s for method argument #%d, which expects %s"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1251 : "type mismatch: returning a primitive %s, but caller expects %s");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1252 } else {
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1253 err = ((argnum >= 0)
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1254 ? "type mismatch: passing a %s for method argument #%d, which expects %s"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1255 : "type mismatch: returning a %s, but caller expects %s");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1256 }
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1257 } 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
1258 class_cast_needed(src_klass, dst_klass)) {
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1259 if (!class_cast_needed(dst_klass, src_klass)) {
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1260 if (raw)
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1261 return NULL; // reverse cast is OK; the MH target is trusted to enforce it
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1262 err = ((argnum >= 0)
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1263 ? "cast required: passing a %s for method argument #%d, which expects %s"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1264 : "cast required: returning a %s, but caller expects %s");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1265 } else {
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1266 err = ((argnum >= 0)
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1267 ? "reference mismatch: passing a %s for method argument #%d, which expects %s"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1268 : "reference mismatch: returning a %s, but caller expects %s");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1269 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1270 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1271 // passed the obstacle course
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1272 return NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1273 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1274
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1275 // format, format, format
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1276 const char* src_name = type2name(src_type);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1277 const char* dst_name = type2name(dst_type);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1278 if (src_type == T_OBJECT) src_name = Klass::cast(src_klass)->external_name();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1279 if (dst_type == T_OBJECT) dst_name = Klass::cast(dst_klass)->external_name();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1280 if (src_name == NULL) src_name = "unknown type";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1281 if (dst_name == NULL) dst_name = "unknown type";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1282
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1283 size_t msglen = strlen(err) + strlen(src_name) + strlen(dst_name) + (argnum < 10 ? 1 : 11);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1284 char* msg = NEW_RESOURCE_ARRAY(char, msglen + 1);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1285 if (argnum >= 0) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1286 assert(strstr(err, "%d") != NULL, "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1287 jio_snprintf(msg, msglen, err, src_name, argnum, dst_name);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1288 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1289 assert(strstr(err, "%d") == NULL, "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1290 jio_snprintf(msg, msglen, err, src_name, dst_name);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1291 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1292 return msg;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1293 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1294
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1295 // Compute the depth within the stack of the given argument, i.e.,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1296 // the combined size of arguments to the right of the given argument.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1297 // For the last argument (ptypes.length-1) this will be zero.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1298 // For the first argument (0) this will be the size of all
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1299 // arguments but that one. For the special number -1, this
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1300 // will be the size of all arguments, including the first.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1301 // If the argument is neither -1 nor a valid argument index,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1302 // then return a negative number. Otherwise, the result
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1303 // is in the range [0..vmslots] inclusive.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1304 int MethodHandles::argument_slot(oop method_type, int arg) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1305 objArrayOop ptypes = java_dyn_MethodType::ptypes(method_type);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1306 int argslot = 0;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1307 int len = ptypes->length();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1308 if (arg < -1 || arg >= len) return -99;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1309 for (int i = len-1; i > arg; i--) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1310 BasicType bt = java_lang_Class::as_BasicType(ptypes->obj_at(i));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1311 argslot += type2size[bt];
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1312 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1313 assert(argument_slot_to_argnum(method_type, argslot) == arg, "inverse works");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1314 return argslot;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1315 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1316
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1317 // Given a slot number, return the argument number.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1318 int MethodHandles::argument_slot_to_argnum(oop method_type, int query_argslot) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1319 objArrayOop ptypes = java_dyn_MethodType::ptypes(method_type);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1320 int argslot = 0;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1321 int len = ptypes->length();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1322 for (int i = len-1; i >= 0; i--) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1323 if (query_argslot == argslot) return i;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1324 BasicType bt = java_lang_Class::as_BasicType(ptypes->obj_at(i));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1325 argslot += type2size[bt];
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1326 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1327 // return pseudo-arg deepest in stack:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1328 if (query_argslot == argslot) return -1;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1329 return -99; // oob slot, or splitting a double-slot arg
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1330 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1331
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1332 methodHandle MethodHandles::dispatch_decoded_method(methodHandle m,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1333 KlassHandle receiver_limit,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1334 int decode_flags,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1335 KlassHandle receiver_klass,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1336 TRAPS) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1337 assert((decode_flags & ~_DMF_DIRECT_MASK) == 0, "must be direct method reference");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1338 assert((decode_flags & _dmf_has_receiver) != 0, "must have a receiver or first reference argument");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1339
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1340 if (!m->is_static() &&
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1341 (receiver_klass.is_null() || !receiver_klass->is_subtype_of(m->method_holder())))
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1342 // given type does not match class of method, or receiver is null!
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1343 // caller should have checked this, but let's be extra careful...
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1344 return methodHandle();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1345
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1346 if (receiver_limit.not_null() &&
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1347 (receiver_klass.not_null() && !receiver_klass->is_subtype_of(receiver_limit())))
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1348 // given type is not limited to the receiver type
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1349 // note that a null receiver can match any reference value, for a static method
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1350 return methodHandle();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1351
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1352 if (!(decode_flags & MethodHandles::_dmf_does_dispatch)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1353 // pre-dispatched or static method (null receiver is OK for static)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1354 return m;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1355
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1356 } else if (receiver_klass.is_null()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1357 // null receiver value; cannot dispatch
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1358 return methodHandle();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1359
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1360 } else if (!(decode_flags & MethodHandles::_dmf_from_interface)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1361 // perform virtual dispatch
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1362 int vtable_index = m->vtable_index();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1363 guarantee(vtable_index >= 0, "valid vtable index");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1364
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1365 // receiver_klass might be an arrayKlassOop but all vtables start at
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1366 // the same place. The cast is to avoid virtual call and assertion.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1367 // See also LinkResolver::runtime_resolve_virtual_method.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1368 instanceKlass* inst = (instanceKlass*)Klass::cast(receiver_klass());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1369 DEBUG_ONLY(inst->verify_vtable_index(vtable_index));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1370 methodOop m_oop = inst->method_at_vtable(vtable_index);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1371 return methodHandle(THREAD, m_oop);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1372
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1373 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1374 // perform interface dispatch
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1375 int itable_index = klassItable::compute_itable_index(m());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1376 guarantee(itable_index >= 0, "valid itable index");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1377 instanceKlass* inst = instanceKlass::cast(receiver_klass());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1378 methodOop m_oop = inst->method_at_itable(m->method_holder(), itable_index, THREAD);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1379 return methodHandle(THREAD, m_oop);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1380 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1381 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1382
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1383 void MethodHandles::verify_DirectMethodHandle(Handle mh, methodHandle m, TRAPS) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1384 // Verify type.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1385 Handle mtype(THREAD, java_dyn_MethodHandle::type(mh()));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1386 verify_method_type(m, mtype, false, KlassHandle(), CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1387
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1388 // Verify vmslots.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1389 if (java_dyn_MethodHandle::vmslots(mh()) != m->size_of_parameters()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1390 THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in DMH");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1391 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1392 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1393
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1394 void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_dispatch, TRAPS) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1395 // Check arguments.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1396 if (mh.is_null() || m.is_null() ||
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1397 (!do_dispatch && m->is_abstract())) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1398 THROW(vmSymbols::java_lang_InternalError());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1399 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1400
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1401 java_dyn_MethodHandle::init_vmslots(mh());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1402
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1403 if (VerifyMethodHandles) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1404 // The privileged code which invokes this routine should not make
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1405 // a mistake about types, but it's better to verify.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1406 verify_DirectMethodHandle(mh, m, CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1407 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1408
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1409 // Finally, after safety checks are done, link to the target method.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1410 // We will follow the same path as the latter part of
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1411 // InterpreterRuntime::resolve_invoke(), which first finds the method
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1412 // and then decides how to populate the constant pool cache entry
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1413 // that links the interpreter calls to the method. We need the same
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1414 // bits, and will use the same calling sequence code.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1415
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1416 int vmindex = methodOopDesc::garbage_vtable_index;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1417 oop vmtarget = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1418
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1419 instanceKlass::cast(m->method_holder())->link_class(CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1420
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1421 MethodHandleEntry* me = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1422 if (do_dispatch && Klass::cast(m->method_holder())->is_interface()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1423 // We are simulating an invokeinterface instruction.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1424 // (We might also be simulating an invokevirtual on a miranda method,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1425 // but it is safe to treat it as an invokeinterface.)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1426 assert(!m->can_be_statically_bound(), "no final methods on interfaces");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1427 vmindex = klassItable::compute_itable_index(m());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1428 assert(vmindex >= 0, "(>=0) == do_dispatch");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1429 // Set up same bits as ConstantPoolCacheEntry::set_interface_call().
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1430 vmtarget = m->method_holder(); // the interface
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1431 me = MethodHandles::entry(MethodHandles::_invokeinterface_mh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1432 } else if (!do_dispatch || m->can_be_statically_bound()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1433 // We are simulating an invokestatic or invokespecial instruction.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1434 // Set up the method pointer, just like ConstantPoolCacheEntry::set_method().
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1435 vmtarget = m();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1436 // this does not help dispatch, but it will make it possible to parse this MH:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1437 vmindex = methodOopDesc::nonvirtual_vtable_index;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1438 assert(vmindex < 0, "(>=0) == do_dispatch");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1439 if (!m->is_static()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1440 me = MethodHandles::entry(MethodHandles::_invokespecial_mh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1441 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1442 me = MethodHandles::entry(MethodHandles::_invokestatic_mh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1443 // Part of the semantics of a static call is an initialization barrier.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1444 // For a DMH, it is done now, when the handle is created.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1445 Klass* k = Klass::cast(m->method_holder());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1446 if (k->should_be_initialized()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1447 k->initialize(CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1448 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1449 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1450 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1451 // We are simulating an invokevirtual instruction.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1452 // Set up the vtable index, just like ConstantPoolCacheEntry::set_method().
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1453 // The key logic is LinkResolver::runtime_resolve_virtual_method.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1454 vmindex = m->vtable_index();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1455 vmtarget = m->method_holder();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1456 me = MethodHandles::entry(MethodHandles::_invokevirtual_mh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1457 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1458
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1459 if (me == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1460
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1461 sun_dyn_DirectMethodHandle::set_vmtarget(mh(), vmtarget);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1462 sun_dyn_DirectMethodHandle::set_vmindex(mh(), vmindex);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1463 DEBUG_ONLY(int flags; klassOop rlimit);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1464 assert(MethodHandles::decode_method(mh(), rlimit, flags) == m(),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1465 "properly stored for later decoding");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1466 DEBUG_ONLY(bool actual_do_dispatch = ((flags & _dmf_does_dispatch) != 0));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1467 assert(!(actual_do_dispatch && !do_dispatch),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1468 "do not perform dispatch if !do_dispatch specified");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1469 assert(actual_do_dispatch == (vmindex >= 0), "proper later decoding of do_dispatch");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1470 assert(decode_MethodHandle_stack_pushes(mh()) == 0, "DMH does not move stack");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1471
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1472 // Done!
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1473 java_dyn_MethodHandle::set_vmentry(mh(), me);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1474 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1475
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1476 void MethodHandles::verify_BoundMethodHandle_with_receiver(Handle mh,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1477 methodHandle m,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1478 TRAPS) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1479 // Verify type.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1480 oop receiver = sun_dyn_BoundMethodHandle::argument(mh());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1481 Handle mtype(THREAD, java_dyn_MethodHandle::type(mh()));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1482 KlassHandle bound_recv_type;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1483 if (receiver != NULL) bound_recv_type = KlassHandle(THREAD, receiver->klass());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1484 verify_method_type(m, mtype, true, bound_recv_type, CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1485
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1486 int receiver_pos = m->size_of_parameters() - 1;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1487
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1488 // Verify MH.vmargslot, which should point at the bound receiver.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1489 verify_vmargslot(mh, -1, sun_dyn_BoundMethodHandle::vmargslot(mh()), CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1490 //verify_vmslots(mh, CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1491
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1492 // Verify vmslots.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1493 if (java_dyn_MethodHandle::vmslots(mh()) != receiver_pos) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1494 THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in BMH (receiver)");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1495 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1496 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1497
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1498 // Initialize a BMH with a receiver bound directly to a methodOop.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1499 void MethodHandles::init_BoundMethodHandle_with_receiver(Handle mh,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1500 methodHandle original_m,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1501 KlassHandle receiver_limit,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1502 int decode_flags,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1503 TRAPS) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1504 // Check arguments.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1505 if (mh.is_null() || original_m.is_null()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1506 THROW(vmSymbols::java_lang_InternalError());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1507 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1508
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1509 KlassHandle receiver_klass;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1510 {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1511 oop receiver_oop = sun_dyn_BoundMethodHandle::argument(mh());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1512 if (receiver_oop != NULL)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1513 receiver_klass = KlassHandle(THREAD, receiver_oop->klass());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1514 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1515 methodHandle m = dispatch_decoded_method(original_m,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1516 receiver_limit, decode_flags,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1517 receiver_klass,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1518 CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1519 if (m.is_null()) { THROW(vmSymbols::java_lang_InternalError()); }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1520 if (m->is_abstract()) { THROW(vmSymbols::java_lang_AbstractMethodError()); }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1521
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1522 java_dyn_MethodHandle::init_vmslots(mh());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1523
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1524 if (VerifyMethodHandles) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1525 verify_BoundMethodHandle_with_receiver(mh, m, CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1526 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1527
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1528 sun_dyn_BoundMethodHandle::set_vmtarget(mh(), m());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1529
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1530 DEBUG_ONLY(int junk; klassOop junk2);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1531 assert(MethodHandles::decode_method(mh(), junk2, junk) == m(), "properly stored for later decoding");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1532 assert(decode_MethodHandle_stack_pushes(mh()) == 1, "BMH pushes one stack slot");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1533
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1534 // Done!
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1535 java_dyn_MethodHandle::set_vmentry(mh(), MethodHandles::entry(MethodHandles::_bound_ref_direct_mh));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1536 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1537
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1538 void MethodHandles::verify_BoundMethodHandle(Handle mh, Handle target, int argnum,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1539 bool direct_to_method, TRAPS) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1540 Handle ptype_handle(THREAD,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1541 java_dyn_MethodType::ptype(java_dyn_MethodHandle::type(target()), argnum));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1542 KlassHandle ptype_klass;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1543 BasicType ptype = java_lang_Class::as_BasicType(ptype_handle(), &ptype_klass);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1544 int slots_pushed = type2size[ptype];
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1545
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1546 oop argument = sun_dyn_BoundMethodHandle::argument(mh());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1547
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1548 const char* err = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1549
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1550 switch (ptype) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1551 case T_OBJECT:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1552 if (argument != NULL)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1553 // we must implicitly convert from the arg type to the outgoing ptype
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1554 err = check_argument_type_change(T_OBJECT, argument->klass(), ptype, ptype_klass(), argnum);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1555 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1556
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1557 case T_ARRAY: case T_VOID:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1558 assert(false, "array, void do not appear here");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1559 default:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1560 if (ptype != T_INT && !is_subword_type(ptype)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1561 err = "unexpected parameter type";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1562 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1563 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1564 // check subrange of Integer.value, if necessary
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1138
diff changeset
1565 if (argument == NULL || argument->klass() != SystemDictionary::Integer_klass()) {
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1566 err = "bound integer argument must be of type java.lang.Integer";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1567 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1568 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1569 if (ptype != T_INT) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1570 int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_INT);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1571 jint value = argument->int_field(value_offset);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1572 int vminfo = adapter_subword_vminfo(ptype);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1573 jint subword = truncate_subword_from_vminfo(value, vminfo);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1574 if (value != subword) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1575 err = "bound subword value does not fit into the subword type";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1576 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1577 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1578 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1579 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1580 case T_FLOAT:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1581 case T_DOUBLE:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1582 case T_LONG:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1583 {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1584 // we must implicitly convert from the unboxed arg type to the outgoing ptype
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1585 BasicType argbox = java_lang_boxing_object::basic_type(argument);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1586 if (argbox != ptype) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1587 err = check_argument_type_change(T_OBJECT, (argument == NULL
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1138
diff changeset
1588 ? SystemDictionary::Object_klass()
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1589 : argument->klass()),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1590 ptype, ptype_klass(), argnum);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1591 assert(err != NULL, "this must be an error");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1592 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1593 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1594 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1595 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1596
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1597 if (err == NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1598 DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh()));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1599 if (direct_to_method) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1600 assert(this_pushes == slots_pushed, "BMH pushes one or two stack slots");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1601 assert(slots_pushed <= MethodHandlePushLimit, "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1602 } else {
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1603 int target_pushes = decode_MethodHandle_stack_pushes(target());
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1604 assert(this_pushes == slots_pushed + target_pushes, "BMH stack motion must be correct");
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1605 // do not blow the stack; use a Java-based adapter if this limit is exceeded
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1059
diff changeset
1606 // FIXME
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1059
diff changeset
1607 // if (slots_pushed + target_pushes > MethodHandlePushLimit)
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1059
diff changeset
1608 // err = "too many bound parameters";
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1609 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1610 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1611
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1612 if (err == NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1613 // Verify the rest of the method type.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1614 err = check_method_type_insertion(java_dyn_MethodHandle::type(mh()),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1615 argnum, ptype_handle(),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1616 java_dyn_MethodHandle::type(target()));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1617 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1618
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1619 if (err != NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1620 THROW_MSG(vmSymbols::java_lang_InternalError(), err);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1621 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1622 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1623
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1624 void MethodHandles::init_BoundMethodHandle(Handle mh, Handle target, int argnum, TRAPS) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1625 // Check arguments.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1626 if (mh.is_null() || target.is_null() || !java_dyn_MethodHandle::is_instance(target())) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1627 THROW(vmSymbols::java_lang_InternalError());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1628 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1629
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1630 java_dyn_MethodHandle::init_vmslots(mh());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1631
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1632 if (VerifyMethodHandles) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1633 int insert_after = argnum - 1;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1634 verify_vmargslot(mh, insert_after, sun_dyn_BoundMethodHandle::vmargslot(mh()), CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1635 verify_vmslots(mh, CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1636 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1637
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1059
diff changeset
1638 // Get bound type and required slots.
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1059
diff changeset
1639 oop ptype_oop = java_dyn_MethodType::ptype(java_dyn_MethodHandle::type(target()), argnum);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1059
diff changeset
1640 BasicType ptype = java_lang_Class::as_BasicType(ptype_oop);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1059
diff changeset
1641 int slots_pushed = type2size[ptype];
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1059
diff changeset
1642
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1643 // If (a) the target is a direct non-dispatched method handle,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1644 // or (b) the target is a dispatched direct method handle and we
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1645 // are binding the receiver, cut out the middle-man.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1646 // Do this by decoding the DMH and using its methodOop directly as vmtarget.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1647 bool direct_to_method = false;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1648 if (OptimizeMethodHandles &&
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1649 target->klass() == SystemDictionary::DirectMethodHandle_klass() &&
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1650 (argnum == 0 || sun_dyn_DirectMethodHandle::vmindex(target()) < 0)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1651 int decode_flags = 0; klassOop receiver_limit_oop = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1652 methodHandle m(THREAD, decode_method(target(), receiver_limit_oop, decode_flags));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1653 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
1654 DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - slots_pushed); // pos. of 1st arg.
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1655 assert(sun_dyn_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1656 if (argnum == 0 && (decode_flags & _dmf_has_receiver) != 0) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1657 KlassHandle receiver_limit(THREAD, receiver_limit_oop);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1658 init_BoundMethodHandle_with_receiver(mh, m,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1659 receiver_limit, decode_flags,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1660 CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1661 return;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1662 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1663
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1664 // Even if it is not a bound receiver, we still might be able
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1665 // to bind another argument and still invoke the methodOop directly.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1666 if (!(decode_flags & _dmf_does_dispatch)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1667 direct_to_method = true;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1668 sun_dyn_BoundMethodHandle::set_vmtarget(mh(), m());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1669 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1670 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1671 if (!direct_to_method)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1672 sun_dyn_BoundMethodHandle::set_vmtarget(mh(), target());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1673
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1674 if (VerifyMethodHandles) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1675 verify_BoundMethodHandle(mh, target, argnum, direct_to_method, CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1676 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1677
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1678 // Next question: Is this a ref, int, or long bound value?
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1679 MethodHandleEntry* me = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1680 if (ptype == T_OBJECT) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1681 if (direct_to_method) me = MethodHandles::entry(_bound_ref_direct_mh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1682 else me = MethodHandles::entry(_bound_ref_mh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1683 } else if (slots_pushed == 2) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1684 if (direct_to_method) me = MethodHandles::entry(_bound_long_direct_mh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1685 else me = MethodHandles::entry(_bound_long_mh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1686 } else if (slots_pushed == 1) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1687 if (direct_to_method) me = MethodHandles::entry(_bound_int_direct_mh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1688 else me = MethodHandles::entry(_bound_int_mh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1689 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1690 assert(false, "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1691 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1692
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1693 // Done!
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1694 java_dyn_MethodHandle::set_vmentry(mh(), me);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1695 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1696
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1697 static void throw_InternalError_for_bad_conversion(int conversion, const char* err, TRAPS) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1698 char msg[200];
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1699 jio_snprintf(msg, sizeof(msg), "bad adapter (conversion=0x%08x): %s", conversion, err);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1700 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), msg);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1701 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1702
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1703 void MethodHandles::verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1704 jint conversion = sun_dyn_AdapterMethodHandle::conversion(mh());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1705 int argslot = sun_dyn_AdapterMethodHandle::vmargslot(mh());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1706
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1707 verify_vmargslot(mh, argnum, argslot, CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1708 verify_vmslots(mh, CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1709
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1710 jint conv_op = adapter_conversion_op(conversion);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1711 if (!conv_op_valid(conv_op)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1712 throw_InternalError_for_bad_conversion(conversion, "unknown conversion op", THREAD);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1713 return;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1714 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1715 EntryKind ek = adapter_entry_kind(conv_op);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1716
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1717 int stack_move = adapter_conversion_stack_move(conversion);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1718 BasicType src = adapter_conversion_src_type(conversion);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1719 BasicType dest = adapter_conversion_dest_type(conversion);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1720 int vminfo = adapter_conversion_vminfo(conversion); // should be zero
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1721
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1722 Handle argument(THREAD, sun_dyn_AdapterMethodHandle::argument(mh()));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1723 Handle target(THREAD, sun_dyn_AdapterMethodHandle::vmtarget(mh()));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1724 Handle src_mtype(THREAD, java_dyn_MethodHandle::type(mh()));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1725 Handle dst_mtype(THREAD, java_dyn_MethodHandle::type(target()));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1726
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1727 const char* err = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1728
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1729 if (err == NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1730 // Check that the correct argument is supplied, but only if it is required.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1731 switch (ek) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1732 case _adapter_check_cast: // target type of cast
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1733 case _adapter_ref_to_prim: // wrapper type from which to unbox
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1734 case _adapter_prim_to_ref: // wrapper type to box into
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1735 case _adapter_collect_args: // array type to collect into
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1736 case _adapter_spread_args: // array type to spread from
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1737 if (!java_lang_Class::is_instance(argument())
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1738 || java_lang_Class::is_primitive(argument()))
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1739 { err = "adapter requires argument of type java.lang.Class"; break; }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1740 if (ek == _adapter_collect_args ||
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1741 ek == _adapter_spread_args) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1742 // Make sure it is a suitable collection type. (Array, for now.)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1743 Klass* ak = Klass::cast(java_lang_Class::as_klassOop(argument()));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1744 if (!ak->oop_is_objArray()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1745 { err = "adapter requires argument of type java.lang.Class<Object[]>"; break; }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1746 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1747 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1748 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1749 case _adapter_flyby:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1750 case _adapter_ricochet:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1751 if (!java_dyn_MethodHandle::is_instance(argument()))
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1752 { err = "MethodHandle adapter argument required"; break; }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1753 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1754 default:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1755 if (argument.not_null())
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1756 { err = "adapter has spurious argument"; break; }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1757 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1758 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1759 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1760
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1761 if (err == NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1762 // Check that the src/dest types are supplied if needed.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1763 switch (ek) {
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1764 case _adapter_check_cast:
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1765 if (src != T_OBJECT || dest != T_OBJECT) {
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1766 err = "adapter requires object src/dest conversion subfields";
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1767 }
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1768 break;
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1769 case _adapter_prim_to_prim:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1770 if (!is_java_primitive(src) || !is_java_primitive(dest) || src == dest) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1771 err = "adapter requires primitive src/dest conversion subfields"; break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1772 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1773 if ( (src == T_FLOAT || src == T_DOUBLE) && !(dest == T_FLOAT || dest == T_DOUBLE) ||
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1774 !(src == T_FLOAT || src == T_DOUBLE) && (dest == T_FLOAT || dest == T_DOUBLE)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1775 err = "adapter cannot convert beween floating and fixed-point"; break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1776 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1777 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1778 case _adapter_ref_to_prim:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1779 if (src != T_OBJECT || !is_java_primitive(dest)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1780 || argument() != Klass::cast(SystemDictionary::box_klass(dest))->java_mirror()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1781 err = "adapter requires primitive dest conversion subfield"; break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1782 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1783 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1784 case _adapter_prim_to_ref:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1785 if (!is_java_primitive(src) || dest != T_OBJECT
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1786 || argument() != Klass::cast(SystemDictionary::box_klass(src))->java_mirror()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1787 err = "adapter requires primitive src conversion subfield"; break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1788 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1789 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1790 case _adapter_swap_args:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1791 case _adapter_rot_args:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1792 {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1793 if (!src || src != dest) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1794 err = "adapter requires src/dest conversion subfields for swap"; break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1795 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1796 int swap_size = type2size[src];
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1797 oop src_mtype = sun_dyn_AdapterMethodHandle::type(mh());
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1798 oop dest_mtype = sun_dyn_AdapterMethodHandle::type(target());
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1799 int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(target());
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1800 int src_slot = argslot;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1801 int dest_slot = vminfo;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1802 bool rotate_up = (src_slot > dest_slot); // upward rotation
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1803 int src_arg = argnum;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1804 int dest_arg = argument_slot_to_argnum(dest_mtype, dest_slot);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1805 verify_vmargslot(mh, dest_arg, dest_slot, CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1806 if (!(dest_slot >= src_slot + swap_size) &&
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1807 !(src_slot >= dest_slot + swap_size)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1808 err = "source, destination slots must be distinct";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1809 } else if (ek == _adapter_swap_args && !(src_slot > dest_slot)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1810 err = "source of swap must be deeper in stack";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1811 } else if (ek == _adapter_swap_args) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1812 err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, dest_arg),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1813 java_dyn_MethodType::ptype(dest_mtype, src_arg),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1814 dest_arg);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1815 } else if (ek == _adapter_rot_args) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1816 if (rotate_up) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1817 assert((src_slot > dest_slot) && (src_arg < dest_arg), "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1818 // rotate up: [dest_slot..src_slot-ss] --> [dest_slot+ss..src_slot]
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1819 // that is: [src_arg+1..dest_arg] --> [src_arg..dest_arg-1]
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1820 for (int i = src_arg+1; i <= dest_arg && err == NULL; i++) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1821 err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, i),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1822 java_dyn_MethodType::ptype(dest_mtype, i-1),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1823 i);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1824 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1825 } else { // rotate down
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1826 assert((src_slot < dest_slot) && (src_arg > dest_arg), "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1827 // rotate down: [src_slot+ss..dest_slot] --> [src_slot..dest_slot-ss]
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1828 // that is: [dest_arg..src_arg-1] --> [dst_arg+1..src_arg]
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1829 for (int i = dest_arg; i <= src_arg-1 && err == NULL; i++) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1830 err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, i),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1831 java_dyn_MethodType::ptype(dest_mtype, i+1),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1832 i);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1833 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1834 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1835 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1836 if (err == NULL)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1837 err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, src_arg),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1838 java_dyn_MethodType::ptype(dest_mtype, dest_arg),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1839 src_arg);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1840 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1841 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1842 case _adapter_collect_args:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1843 case _adapter_spread_args:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1844 {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1845 BasicType coll_type = (ek == _adapter_collect_args) ? dest : src;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1846 BasicType elem_type = (ek == _adapter_collect_args) ? src : dest;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1847 if (coll_type != T_OBJECT || elem_type != T_OBJECT) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1848 err = "adapter requires src/dest subfields"; break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1849 // later:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1850 // - consider making coll be a primitive array
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1851 // - consider making coll be a heterogeneous collection
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1852 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1853 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1854 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1855 default:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1856 if (src != 0 || dest != 0) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1857 err = "adapter has spurious src/dest conversion subfields"; break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1858 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1859 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1860 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1861 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1862
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1863 if (err == NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1864 // Check the stack_move subfield.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1865 // It must always report the net change in stack size, positive or negative.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1866 int slots_pushed = stack_move / stack_move_unit();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1867 switch (ek) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1868 case _adapter_prim_to_prim:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1869 case _adapter_ref_to_prim:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1870 case _adapter_prim_to_ref:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1871 if (slots_pushed != type2size[dest] - type2size[src]) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1872 err = "wrong stack motion for primitive conversion";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1873 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1874 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1875 case _adapter_dup_args:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1876 if (slots_pushed <= 0) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1877 err = "adapter requires conversion subfield slots_pushed > 0";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1878 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1879 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1880 case _adapter_drop_args:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1881 if (slots_pushed >= 0) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1882 err = "adapter requires conversion subfield slots_pushed < 0";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1883 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1884 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1885 case _adapter_collect_args:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1886 if (slots_pushed > 1) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1887 err = "adapter requires conversion subfield slots_pushed <= 1";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1888 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1889 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1890 case _adapter_spread_args:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1891 if (slots_pushed < -1) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1892 err = "adapter requires conversion subfield slots_pushed >= -1";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1893 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1894 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1895 default:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1896 if (stack_move != 0) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1897 err = "adapter has spurious stack_move conversion subfield";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1898 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1899 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1900 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1901 if (err == NULL && stack_move != slots_pushed * stack_move_unit()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1902 err = "stack_move conversion subfield must be multiple of stack_move_unit";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1903 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1904 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1905
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1906 if (err == NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1907 // Make sure this adapter does not push too deeply.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1908 int slots_pushed = stack_move / stack_move_unit();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1909 int this_vmslots = java_dyn_MethodHandle::vmslots(mh());
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1910 int target_vmslots = java_dyn_MethodHandle::vmslots(target());
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1911 if (slots_pushed != (target_vmslots - this_vmslots)) {
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1912 err = "stack_move inconsistent with previous and current MethodType vmslots";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1913 } else if (slots_pushed > 0) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1914 // verify stack_move against MethodHandlePushLimit
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1915 int target_pushes = decode_MethodHandle_stack_pushes(target());
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1916 // do not blow the stack; use a Java-based adapter if this limit is exceeded
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1917 if (slots_pushed + target_pushes > MethodHandlePushLimit) {
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1918 err = "adapter pushes too many parameters";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1919 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1920 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1921
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1922 // While we're at it, check that the stack motion decoder works:
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1923 DEBUG_ONLY(int target_pushes = decode_MethodHandle_stack_pushes(target()));
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1924 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
1925 assert(this_pushes == slots_pushed + target_pushes, "AMH stack motion must be correct");
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1926 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1927
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1928 if (err == NULL && vminfo != 0) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1929 switch (ek) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1930 case _adapter_swap_args:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1931 case _adapter_rot_args:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1932 break; // OK
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1933 default:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1934 err = "vminfo subfield is reserved to the JVM";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1935 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1936 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1937
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1938 // Do additional ad hoc checks.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1939 if (err == NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1940 switch (ek) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1941 case _adapter_retype_only:
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1942 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
1943 break;
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1944
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1945 case _adapter_retype_raw:
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
1946 err = check_method_type_passthrough(src_mtype(), dst_mtype(), true);
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1947 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1948
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1949 case _adapter_check_cast:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1950 {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1951 // The actual value being checked must be a reference:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1952 err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype(), argnum),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1953 object_java_mirror(), argnum);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1954 if (err != NULL) break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1955
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1956 // The output of the cast must fit with the destination argument:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1957 Handle cast_class = argument;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1958 err = check_method_type_conversion(src_mtype(),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1959 argnum, cast_class(),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1960 dst_mtype());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1961 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1962 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1963
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1964 // %%% TO DO: continue in remaining cases to verify src/dst_mtype if VerifyMethodHandles
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1965 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1966 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1967
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1968 if (err != NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1969 throw_InternalError_for_bad_conversion(conversion, err, THREAD);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1970 return;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1971 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1972
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1973 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1974
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1975 void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1976 oop argument = sun_dyn_AdapterMethodHandle::argument(mh());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1977 int argslot = sun_dyn_AdapterMethodHandle::vmargslot(mh());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1978 jint conversion = sun_dyn_AdapterMethodHandle::conversion(mh());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1979 jint conv_op = adapter_conversion_op(conversion);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1980
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1981 // adjust the adapter code to the internal EntryKind enumeration:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1982 EntryKind ek_orig = adapter_entry_kind(conv_op);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1983 EntryKind ek_opt = ek_orig; // may be optimized
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1984
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1985 // Finalize the vmtarget field (Java initialized it to null).
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1986 if (!java_dyn_MethodHandle::is_instance(target())) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1987 throw_InternalError_for_bad_conversion(conversion, "bad target", THREAD);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1988 return;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1989 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1990 sun_dyn_AdapterMethodHandle::set_vmtarget(mh(), target());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1991
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1992 if (VerifyMethodHandles) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1993 verify_AdapterMethodHandle(mh, argnum, CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1994 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1995
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1996 int stack_move = adapter_conversion_stack_move(conversion);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1997 BasicType src = adapter_conversion_src_type(conversion);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1998 BasicType dest = adapter_conversion_dest_type(conversion);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
1999 int vminfo = adapter_conversion_vminfo(conversion); // should be zero
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2000
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2001 const char* err = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2002
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2003 // Now it's time to finish the case analysis and pick a MethodHandleEntry.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2004 switch (ek_orig) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2005 case _adapter_retype_only:
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2006 case _adapter_retype_raw:
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2007 case _adapter_check_cast:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2008 case _adapter_dup_args:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2009 case _adapter_drop_args:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2010 // these work fine via general case code
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2011 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2012
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2013 case _adapter_prim_to_prim:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2014 {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2015 // Non-subword cases are {int,float,long,double} -> {int,float,long,double}.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2016 // And, the {float,double} -> {int,long} cases must be handled by Java.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2017 switch (type2size[src] *4+ type2size[dest]) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2018 case 1 *4+ 1:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2019 assert(src == T_INT || is_subword_type(src), "source is not float");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2020 // Subword-related cases are int -> {boolean,byte,char,short}.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2021 ek_opt = _adapter_opt_i2i;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2022 vminfo = adapter_subword_vminfo(dest);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2023 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2024 case 2 *4+ 1:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2025 if (src == T_LONG && (dest == T_INT || is_subword_type(dest))) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2026 ek_opt = _adapter_opt_l2i;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2027 vminfo = adapter_subword_vminfo(dest);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2028 } else if (src == T_DOUBLE && dest == T_FLOAT) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2029 ek_opt = _adapter_opt_d2f;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2030 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2031 assert(false, "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2032 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2033 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2034 case 1 *4+ 2:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2035 if (src == T_INT && dest == T_LONG) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2036 ek_opt = _adapter_opt_i2l;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2037 } else if (src == T_FLOAT && dest == T_DOUBLE) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2038 ek_opt = _adapter_opt_f2d;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2039 } else {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2040 assert(false, "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2041 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2042 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2043 default:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2044 assert(false, "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2045 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2046 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2047 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2048 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2049
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2050 case _adapter_ref_to_prim:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2051 {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2052 switch (type2size[dest]) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2053 case 1:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2054 ek_opt = _adapter_opt_unboxi;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2055 vminfo = adapter_subword_vminfo(dest);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2056 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2057 case 2:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2058 ek_opt = _adapter_opt_unboxl;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2059 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2060 default:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2061 assert(false, "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2062 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2063 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2064 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2065 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2066
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2067 case _adapter_prim_to_ref:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2068 goto throw_not_impl; // allocates, hence could block
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2069
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2070 case _adapter_swap_args:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2071 case _adapter_rot_args:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2072 {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2073 int swap_slots = type2size[src];
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2074 int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(mh());
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2075 int src_slot = argslot;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2076 int dest_slot = vminfo;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2077 int rotate = (ek_orig == _adapter_swap_args) ? 0 : (src_slot > dest_slot) ? 1 : -1;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2078 switch (swap_slots) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2079 case 1:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2080 ek_opt = (!rotate ? _adapter_opt_swap_1 :
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2081 rotate > 0 ? _adapter_opt_rot_1_up : _adapter_opt_rot_1_down);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2082 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2083 case 2:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2084 ek_opt = (!rotate ? _adapter_opt_swap_2 :
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2085 rotate > 0 ? _adapter_opt_rot_2_up : _adapter_opt_rot_2_down);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2086 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2087 default:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2088 assert(false, "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2089 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2090 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2091 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2092 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2093
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2094 case _adapter_collect_args:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2095 goto throw_not_impl; // allocates, hence could block
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2096
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2097 case _adapter_spread_args:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2098 {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2099 // vminfo will be the required length of the array
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2100 int slots_pushed = stack_move / stack_move_unit();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2101 int array_size = slots_pushed + 1;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2102 assert(array_size >= 0, "");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2103 vminfo = array_size;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2104 switch (array_size) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2105 case 0: ek_opt = _adapter_opt_spread_0; break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2106 case 1: ek_opt = _adapter_opt_spread_1; break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2107 default: ek_opt = _adapter_opt_spread_more; break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2108 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2109 if ((vminfo & CONV_VMINFO_MASK) != vminfo)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2110 goto throw_not_impl; // overflow
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2111 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2112 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2113
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2114 case _adapter_flyby:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2115 case _adapter_ricochet:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2116 goto throw_not_impl; // runs Java code, hence could block
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2117
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2118 default:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2119 // should have failed much earlier; must be a missing case here
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2120 assert(false, "incomplete switch");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2121 // and fall through:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2122
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2123 throw_not_impl:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2124 // FIXME: these adapters are NYI
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2125 err = "adapter not yet implemented in the JVM";
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2126 break;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2127 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2128
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2129 if (err != NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2130 throw_InternalError_for_bad_conversion(conversion, err, THREAD);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2131 return;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2132 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2133
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2134 // Rebuild the conversion value; maybe parts of it were changed.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2135 jint new_conversion = adapter_conversion(conv_op, src, dest, stack_move, vminfo);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2136
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2137 // Finalize the conversion field. (Note that it is final to Java code.)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2138 sun_dyn_AdapterMethodHandle::set_conversion(mh(), new_conversion);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2139
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2140 // Done!
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2141 java_dyn_MethodHandle::set_vmentry(mh(), entry(ek_opt));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2142
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2143 // There should be enough memory barriers on exit from native methods
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2144 // to ensure that the MH is fully initialized to all threads before
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2145 // Java code can publish it in global data structures.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2146 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2147
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2148 //
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2149 // Here are the native methods on sun.dyn.MethodHandleImpl.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2150 // They are the private interface between this JVM and the HotSpot-specific
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2151 // Java code that implements JSR 292 method handles.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2152 //
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2153 // Note: We use a JVM_ENTRY macro to define each of these, for this is the way
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2154 // that intrinsic (non-JNI) native methods are defined in HotSpot.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2155 //
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2156
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2157 // direct method handles for invokestatic or invokespecial
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2158 // void init(DirectMethodHandle self, MemberName ref, boolean doDispatch, Class<?> caller);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2159 JVM_ENTRY(void, MHI_init_DMH(JNIEnv *env, jobject igcls, jobject mh_jh,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2160 jobject target_jh, jboolean do_dispatch, jobject caller_jh)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2161 ResourceMark rm; // for error messages
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2162
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2163 // This is the guy we are initializing:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2164 if (mh_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2165 Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2166
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2167 // Early returns out of this method leave the DMH in an unfinished state.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2168 assert(java_dyn_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2169
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2170 // which method are we really talking about?
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2171 if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2172 oop target_oop = JNIHandles::resolve_non_null(target_jh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2173 if (sun_dyn_MemberName::is_instance(target_oop) &&
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2174 sun_dyn_MemberName::vmindex(target_oop) == VM_INDEX_UNINITIALIZED) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2175 Handle mname(THREAD, target_oop);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2176 MethodHandles::resolve_MemberName(mname, CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2177 target_oop = mname(); // in case of GC
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2178 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2179
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2180 int decode_flags = 0; klassOop receiver_limit = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2181 methodHandle m(THREAD,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2182 MethodHandles::decode_method(target_oop,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2183 receiver_limit, decode_flags));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2184 if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "no such method"); }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2185
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2186 // The trusted Java code that calls this method should already have performed
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2187 // access checks on behalf of the given caller. But, we can verify this.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2188 if (VerifyMethodHandles && caller_jh != NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2189 KlassHandle caller(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(caller_jh)));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2190 // If this were a bytecode, the first access check would be against
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2191 // the "reference class" mentioned in the CONSTANT_Methodref.
1507
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2192 // 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
2193 // 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
2194 // 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
2195 // happens, when we call resolve_MemberName.
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2196 //
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2197 // (A public class can inherit public members from private supers,
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2198 // 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
2199 // if the original symbolic reference was against the public class.)
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2200 //
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2201 // If there were a bytecode, the next step would be to lookup the method
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2202 // in the reference class, then then check the method's access bits.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2203 // Emulate LinkResolver::check_method_accessability.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2204 klassOop resolved_klass = m->method_holder();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2205 if (!Reflection::verify_field_access(caller->as_klassOop(),
1507
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2206 resolved_klass, resolved_klass,
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2207 m->access_flags(),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2208 true)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2209 // %%% following cutout belongs in Reflection::verify_field_access?
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2210 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
2211 resolved_klass, THREAD);
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2212 if (!same_pm) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2213 THROW_MSG(vmSymbols::java_lang_InternalError(), m->name_and_sig_as_C_string());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2214 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2215 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2216 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2217
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2218 MethodHandles::init_DirectMethodHandle(mh, m, (do_dispatch != JNI_FALSE), CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2219 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2220 JVM_END
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2221
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2222 // bound method handles
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2223 JVM_ENTRY(void, MHI_init_BMH(JNIEnv *env, jobject igcls, jobject mh_jh,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2224 jobject target_jh, int argnum)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2225 ResourceMark rm; // for error messages
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2226
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2227 // This is the guy we are initializing:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2228 if (mh_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2229 Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2230
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2231 // Early returns out of this method leave the BMH in an unfinished state.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2232 assert(java_dyn_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2233
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2234 if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2235 Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2236
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2237 if (!java_dyn_MethodHandle::is_instance(target())) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2238 // Target object is a reflective method. (%%% Do we need this alternate path?)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2239 Untested("init_BMH of non-MH");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2240 if (argnum != 0) { THROW(vmSymbols::java_lang_InternalError()); }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2241 int decode_flags = 0; klassOop receiver_limit_oop = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2242 methodHandle m(THREAD,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2243 MethodHandles::decode_method(target(),
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2244 receiver_limit_oop,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2245 decode_flags));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2246 KlassHandle receiver_limit(THREAD, receiver_limit_oop);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2247 MethodHandles::init_BoundMethodHandle_with_receiver(mh, m,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2248 receiver_limit,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2249 decode_flags,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2250 CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2251 return;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2252 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2253
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2254 // Build a BMH on top of a DMH or another BMH:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2255 MethodHandles::init_BoundMethodHandle(mh, target, argnum, CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2256 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2257 JVM_END
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2258
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2259 // adapter method handles
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2260 JVM_ENTRY(void, MHI_init_AMH(JNIEnv *env, jobject igcls, jobject mh_jh,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2261 jobject target_jh, int argnum)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2262 // This is the guy we are initializing:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2263 if (mh_jh == NULL || target_jh == NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2264 THROW(vmSymbols::java_lang_InternalError());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2265 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2266 Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2267 Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2268
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2269 // Early returns out of this method leave the AMH in an unfinished state.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2270 assert(java_dyn_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2271
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2272 MethodHandles::init_AdapterMethodHandle(mh, target, argnum, CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2273 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2274 JVM_END
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2275
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2276 // method type forms
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2277 JVM_ENTRY(void, MHI_init_MT(JNIEnv *env, jobject igcls, jobject erased_jh)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2278 if (erased_jh == NULL) return;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2279 if (TraceMethodHandles) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2280 tty->print("creating MethodType form ");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2281 if (WizardMode || Verbose) { // Warning: this calls Java code on the MH!
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2282 // call Object.toString()
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2283 symbolOop name = vmSymbols::toString_name(), sig = vmSymbols::void_string_signature();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2284 JavaCallArguments args(Handle(THREAD, JNIHandles::resolve_non_null(erased_jh)));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2285 JavaValue result(T_OBJECT);
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1138
diff changeset
2286 JavaCalls::call_virtual(&result, SystemDictionary::Object_klass(), name, sig,
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2287 &args, CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2288 Handle str(THREAD, (oop)result.get_jobject());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2289 java_lang_String::print(str, tty);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2290 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2291 tty->cr();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2292 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2293 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2294 JVM_END
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2295
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2296 // debugging and reflection
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2297 JVM_ENTRY(jobject, MHI_getTarget(JNIEnv *env, jobject igcls, jobject mh_jh, jint format)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2298 Handle mh(THREAD, JNIHandles::resolve(mh_jh));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2299 if (!java_dyn_MethodHandle::is_instance(mh())) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2300 THROW_NULL(vmSymbols::java_lang_IllegalArgumentException());
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2301 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2302 oop target = MethodHandles::encode_target(mh, format, CHECK_NULL);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2303 return JNIHandles::make_local(THREAD, target);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2304 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2305 JVM_END
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2306
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2307 JVM_ENTRY(jint, MHI_getConstant(JNIEnv *env, jobject igcls, jint which)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2308 switch (which) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2309 case MethodHandles::GC_JVM_PUSH_LIMIT:
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2310 guarantee(MethodHandlePushLimit >= 2 && MethodHandlePushLimit <= 0xFF,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2311 "MethodHandlePushLimit parameter must be in valid range");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2312 return MethodHandlePushLimit;
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2313 case MethodHandles::GC_JVM_STACK_MOVE_UNIT:
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2314 // return number of words per slot, signed according to stack direction
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2315 return MethodHandles::stack_move_unit();
1507
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2316 case MethodHandles::GC_CONV_OP_IMPLEMENTED_MASK:
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2317 return MethodHandles::adapter_conversion_ops_supported_mask();
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2318 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2319 return 0;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2320 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2321 JVM_END
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2322
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2323 #ifndef PRODUCT
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2324 #define EACH_NAMED_CON(template) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2325 template(MethodHandles,GC_JVM_PUSH_LIMIT) \
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2326 template(MethodHandles,GC_JVM_STACK_MOVE_UNIT) \
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2327 template(MethodHandles,ETF_HANDLE_OR_METHOD_NAME) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2328 template(MethodHandles,ETF_DIRECT_HANDLE) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2329 template(MethodHandles,ETF_METHOD_NAME) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2330 template(MethodHandles,ETF_REFLECT_METHOD) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2331 template(sun_dyn_MemberName,MN_IS_METHOD) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2332 template(sun_dyn_MemberName,MN_IS_CONSTRUCTOR) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2333 template(sun_dyn_MemberName,MN_IS_FIELD) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2334 template(sun_dyn_MemberName,MN_IS_TYPE) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2335 template(sun_dyn_MemberName,MN_SEARCH_SUPERCLASSES) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2336 template(sun_dyn_MemberName,MN_SEARCH_INTERFACES) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2337 template(sun_dyn_MemberName,VM_INDEX_UNINITIALIZED) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2338 template(sun_dyn_AdapterMethodHandle,OP_RETYPE_ONLY) \
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2339 template(sun_dyn_AdapterMethodHandle,OP_RETYPE_RAW) \
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2340 template(sun_dyn_AdapterMethodHandle,OP_CHECK_CAST) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2341 template(sun_dyn_AdapterMethodHandle,OP_PRIM_TO_PRIM) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2342 template(sun_dyn_AdapterMethodHandle,OP_REF_TO_PRIM) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2343 template(sun_dyn_AdapterMethodHandle,OP_PRIM_TO_REF) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2344 template(sun_dyn_AdapterMethodHandle,OP_SWAP_ARGS) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2345 template(sun_dyn_AdapterMethodHandle,OP_ROT_ARGS) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2346 template(sun_dyn_AdapterMethodHandle,OP_DUP_ARGS) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2347 template(sun_dyn_AdapterMethodHandle,OP_DROP_ARGS) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2348 template(sun_dyn_AdapterMethodHandle,OP_COLLECT_ARGS) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2349 template(sun_dyn_AdapterMethodHandle,OP_SPREAD_ARGS) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2350 template(sun_dyn_AdapterMethodHandle,OP_FLYBY) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2351 template(sun_dyn_AdapterMethodHandle,OP_RICOCHET) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2352 template(sun_dyn_AdapterMethodHandle,CONV_OP_LIMIT) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2353 template(sun_dyn_AdapterMethodHandle,CONV_OP_MASK) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2354 template(sun_dyn_AdapterMethodHandle,CONV_VMINFO_MASK) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2355 template(sun_dyn_AdapterMethodHandle,CONV_VMINFO_SHIFT) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2356 template(sun_dyn_AdapterMethodHandle,CONV_OP_SHIFT) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2357 template(sun_dyn_AdapterMethodHandle,CONV_DEST_TYPE_SHIFT) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2358 template(sun_dyn_AdapterMethodHandle,CONV_SRC_TYPE_SHIFT) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2359 template(sun_dyn_AdapterMethodHandle,CONV_STACK_MOVE_SHIFT) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2360 template(sun_dyn_AdapterMethodHandle,CONV_STACK_MOVE_MASK) \
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2361 /*end*/
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2362
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2363 #define ONE_PLUS(scope,value) 1+
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2364 static const int con_value_count = EACH_NAMED_CON(ONE_PLUS) 0;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2365 #define VALUE_COMMA(scope,value) scope::value,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2366 static const int con_values[con_value_count+1] = { EACH_NAMED_CON(VALUE_COMMA) 0 };
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2367 #define STRING_NULL(scope,value) #value "\0"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2368 static const char con_names[] = { EACH_NAMED_CON(STRING_NULL) };
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2369
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2370 #undef ONE_PLUS
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2371 #undef VALUE_COMMA
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2372 #undef STRING_NULL
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2373 #undef EACH_NAMED_CON
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2374 #endif
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2375
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2376 JVM_ENTRY(jint, MHI_getNamedCon(JNIEnv *env, jobject igcls, jint which, jobjectArray box_jh)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2377 #ifndef PRODUCT
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2378 if (which >= 0 && which < con_value_count) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2379 int con = con_values[which];
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2380 objArrayOop box = (objArrayOop) JNIHandles::resolve(box_jh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2381 if (box != NULL && box->klass() == Universe::objectArrayKlassObj() && box->length() > 0) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2382 const char* str = &con_names[0];
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2383 for (int i = 0; i < which; i++)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2384 str += strlen(str) + 1; // skip name and null
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2385 oop name = java_lang_String::create_oop_from_str(str, CHECK_0);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2386 box->obj_at_put(0, name);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2387 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2388 return con;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2389 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2390 #endif
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2391 return 0;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2392 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2393 JVM_END
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2394
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2395 // void init(MemberName self, AccessibleObject ref)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2396 JVM_ENTRY(void, MHI_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2397 if (mname_jh == NULL || target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2398 Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2399 oop target_oop = JNIHandles::resolve_non_null(target_jh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2400 MethodHandles::init_MemberName(mname(), target_oop);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2401 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2402 JVM_END
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2403
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2404 // void expand(MemberName self)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2405 JVM_ENTRY(void, MHI_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2406 if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2407 Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2408 MethodHandles::expand_MemberName(mname, 0, CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2409 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2410 JVM_END
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2411
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2412 // void resolve(MemberName self, Class<?> caller)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2413 JVM_ENTRY(void, MHI_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2414 if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2415 Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
1507
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2416
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2417 // 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
2418 // 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
2419 if (VerifyMethodHandles && caller_jh != NULL) {
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2420 klassOop reference_klass = java_lang_Class::as_klassOop(sun_dyn_MemberName::clazz(mname()));
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2421 if (reference_klass != NULL) {
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2422 // Emulate LinkResolver::check_klass_accessability.
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2423 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
2424 if (!Reflection::verify_class_access(caller,
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2425 reference_klass,
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2426 true)) {
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2427 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
2428 }
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2429 }
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2430 }
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2431
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2432 MethodHandles::resolve_MemberName(mname, CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2433 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2434 JVM_END
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2435
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2436 // static native int getMembers(Class<?> defc, String matchName, String matchSig,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2437 // int matchFlags, Class<?> caller, int skip, MemberName[] results);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2438 JVM_ENTRY(jint, MHI_getMembers(JNIEnv *env, jobject igcls,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2439 jclass clazz_jh, jstring name_jh, jstring sig_jh,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2440 int mflags, jclass caller_jh, jint skip, jobjectArray results_jh)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2441 if (clazz_jh == NULL || results_jh == NULL) return -1;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2442 klassOop k_oop = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz_jh));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2443
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2444 objArrayOop results = (objArrayOop) JNIHandles::resolve(results_jh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2445 if (results == NULL || !results->is_objArray()) return -1;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2446
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2447 symbolOop name = NULL, sig = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2448 if (name_jh != NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2449 name = java_lang_String::as_symbol_or_null(JNIHandles::resolve_non_null(name_jh));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2450 if (name == NULL) return 0; // a match is not possible
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2451 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2452 if (sig_jh != NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2453 sig = java_lang_String::as_symbol_or_null(JNIHandles::resolve_non_null(sig_jh));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2454 if (sig == NULL) return 0; // a match is not possible
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2455 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2456
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2457 klassOop caller = NULL;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2458 if (caller_jh != NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2459 oop caller_oop = JNIHandles::resolve_non_null(caller_jh);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2460 if (!java_lang_Class::is_instance(caller_oop)) return -1;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2461 caller = java_lang_Class::as_klassOop(caller_oop);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2462 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2463
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2464 if (name != NULL && sig != NULL && results != NULL) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2465 // try a direct resolve
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2466 // %%% TO DO
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2467 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2468
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2469 int res = MethodHandles::find_MemberNames(k_oop, name, sig, mflags,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2470 caller, skip, results);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2471 // TO DO: expand at least some of the MemberNames, to avoid massive callbacks
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2472 return res;
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2473 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2474 JVM_END
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2475
1507
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2476 JVM_ENTRY(void, MHI_registerBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh, jobject bsm_jh)) {
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2477 instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD);
1660
083fde3b838e 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 1552
diff changeset
2478 if (!AllowTransitionalJSR292) {
083fde3b838e 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 1552
diff changeset
2479 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
083fde3b838e 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 1552
diff changeset
2480 "registerBootstrapMethod is only supported in JSR 292 EDR");
083fde3b838e 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 1552
diff changeset
2481 }
1507
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2482 ik->link_class(CHECK);
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2483 if (!java_dyn_MethodHandle::is_instance(JNIHandles::resolve(bsm_jh))) {
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2484 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "method handle");
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2485 }
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2486 const char* err = NULL;
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2487 if (ik->is_initialized() || ik->is_in_error_state()) {
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2488 err = "too late: class is already initialized";
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2489 } else {
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2490 ObjectLocker ol(ik, THREAD); // note: this should be a recursive lock
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2491 if (ik->is_not_initialized() ||
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2492 (ik->is_being_initialized() && ik->is_reentrant_initialization(THREAD))) {
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2493 if (ik->bootstrap_method() != NULL) {
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2494 err = "class is already equipped with a bootstrap method";
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2495 } else {
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2496 ik->set_bootstrap_method(JNIHandles::resolve_non_null(bsm_jh));
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2497 err = NULL;
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2498 }
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2499 } else {
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2500 err = "class is already initialized";
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2501 if (ik->is_being_initialized())
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2502 err = "class is already being initialized in a different thread";
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2503 }
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2504 }
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2505 if (err != NULL) {
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2506 THROW_MSG(vmSymbols::java_lang_IllegalStateException(), err);
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2507 }
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2508 }
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2509 JVM_END
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2510
1507
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2511 JVM_ENTRY(jobject, MHI_getBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh)) {
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2512 instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD);
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2513 return JNIHandles::make_local(THREAD, ik->bootstrap_method());
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2514 }
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2515 JVM_END
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2516
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2517 JVM_ENTRY(void, MHI_setCallSiteTarget(JNIEnv *env, jobject igcls, jobject site_jh, jobject target_jh)) {
726
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2518 // No special action required, yet.
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2519 oop site_oop = JNIHandles::resolve(site_jh);
1507
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2520 if (!java_dyn_CallSite::is_instance(site_oop))
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2521 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "not a CallSite");
1059
389049f3f393 6858164: invokedynamic code needs some cleanup (post-6655638)
jrose
parents: 1039
diff changeset
2522 java_dyn_CallSite::set_target(site_oop, JNIHandles::resolve(target_jh));
726
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2523 }
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2524 JVM_END
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2525
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2526
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2527 /// JVM_RegisterMethodHandleMethods
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2528
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2529 #define ADR "J"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2530
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2531 #define LANG "Ljava/lang/"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2532 #define JDYN "Ljava/dyn/"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2533 #define IDYN "Lsun/dyn/"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2534
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2535 #define OBJ LANG"Object;"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2536 #define CLS LANG"Class;"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2537 #define STRG LANG"String;"
1059
389049f3f393 6858164: invokedynamic code needs some cleanup (post-6655638)
jrose
parents: 1039
diff changeset
2538 #define CST JDYN"CallSite;"
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2539 #define MT JDYN"MethodType;"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2540 #define MH JDYN"MethodHandle;"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2541 #define MHI IDYN"MethodHandleImpl;"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2542 #define MEM IDYN"MemberName;"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2543 #define AMH IDYN"AdapterMethodHandle;"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2544 #define BMH IDYN"BoundMethodHandle;"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2545 #define DMH IDYN"DirectMethodHandle;"
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2546
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2547 #define CC (char*) /*cast a literal from (const char*)*/
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2548 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2549
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2550 // These are the native methods on sun.dyn.MethodHandleNatives.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2551 static JNINativeMethod methods[] = {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2552 // void init(MemberName self, AccessibleObject ref)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2553 {CC"init", CC"("AMH""MH"I)V", FN_PTR(MHI_init_AMH)},
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2554 {CC"init", CC"("BMH""OBJ"I)V", FN_PTR(MHI_init_BMH)},
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2555 {CC"init", CC"("DMH""OBJ"Z"CLS")V", FN_PTR(MHI_init_DMH)},
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2556 {CC"init", CC"("MT")V", FN_PTR(MHI_init_MT)},
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2557 {CC"init", CC"("MEM""OBJ")V", FN_PTR(MHI_init_Mem)},
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2558 {CC"expand", CC"("MEM")V", FN_PTR(MHI_expand_Mem)},
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2559 {CC"resolve", CC"("MEM""CLS")V", FN_PTR(MHI_resolve_Mem)},
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2560 {CC"getTarget", CC"("MH"I)"OBJ, FN_PTR(MHI_getTarget)},
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2561 {CC"getConstant", CC"(I)I", FN_PTR(MHI_getConstant)},
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2562 // static native int getNamedCon(int which, Object[] name)
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2563 {CC"getNamedCon", CC"(I["OBJ")I", FN_PTR(MHI_getNamedCon)},
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2564 // static native int getMembers(Class<?> defc, String matchName, String matchSig,
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2565 // int matchFlags, Class<?> caller, int skip, MemberName[] results);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2566 {CC"getMembers", CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHI_getMembers)}
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2567 };
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2568
726
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2569 // More entry points specifically for EnableInvokeDynamic.
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2570 static JNINativeMethod methods2[] = {
1507
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2571 {CC"registerBootstrap", CC"("CLS MH")V", FN_PTR(MHI_registerBootstrap)},
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2572 {CC"getBootstrap", CC"("CLS")"MH, FN_PTR(MHI_getBootstrap)},
cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 1299
diff changeset
2573 {CC"setCallSiteTarget", CC"("CST MH")V", FN_PTR(MHI_setCallSiteTarget)}
726
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2574 };
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2575
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2576
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2577 // This one function is exported, used by NativeLookup.
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2578
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2579 JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2580 assert(MethodHandles::spot_check_entry_names(), "entry enum is OK");
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2581
726
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2582 // note: this explicit warning-producing stuff will be replaced by auto-detection of the JSR 292 classes
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2583
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2584 if (!EnableMethodHandles) {
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2585 warning("JSR 292 method handles are disabled in this JVM. Use -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles to enable.");
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2586 return; // bind nothing
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2587 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2588
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2589 bool enable_MH = true;
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2590
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2591 {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2592 ThreadToNativeFromVM ttnfv(thread);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2593
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2594 int status = env->RegisterNatives(MHN_class, methods, sizeof(methods)/sizeof(JNINativeMethod));
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2595 if (env->ExceptionOccurred()) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2596 MethodHandles::set_enabled(false);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2597 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2598 enable_MH = false;
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2599 env->ExceptionClear();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2600 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2601 }
726
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2602
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2603 if (enable_MH) {
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2604 KlassHandle MHI_klass = SystemDictionaryHandles::MethodHandleImpl_klass();
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2605 if (MHI_klass.not_null()) {
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2606 symbolHandle raiseException_name = oopFactory::new_symbol_handle("raiseException", CHECK);
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2607 symbolHandle raiseException_sig = oopFactory::new_symbol_handle("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK);
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2608 methodOop raiseException_method = instanceKlass::cast(MHI_klass->as_klassOop())
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2609 ->find_method(raiseException_name(), raiseException_sig());
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2610 if (raiseException_method != NULL && raiseException_method->is_static()) {
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2611 MethodHandles::set_raise_exception_method(raiseException_method);
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2612 } else {
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2613 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2614 enable_MH = false;
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2615 }
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2616 }
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2617 }
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2618
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2619 if (enable_MH) {
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2620 MethodHandles::set_enabled(true);
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2621 }
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2622
726
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2623 if (!EnableInvokeDynamic) {
1039
987e948ebbc8 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 726
diff changeset
2624 warning("JSR 292 invokedynamic is disabled in this JVM. Use -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic to enable.");
726
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2625 return; // bind nothing
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2626 }
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2627
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2628 {
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2629 ThreadToNativeFromVM ttnfv(thread);
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2630
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2631 int status = env->RegisterNatives(MHN_class, methods2, sizeof(methods2)/sizeof(JNINativeMethod));
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2632 if (env->ExceptionOccurred()) {
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2633 MethodHandles::set_enabled(false);
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2634 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2635 env->ExceptionClear();
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2636 } else {
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2637 MethodHandles::set_enabled(true);
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2638 }
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 710
diff changeset
2639 }
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2640 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
2641 JVM_END