History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/lang/invoke/Invokers.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/lang/invoke/Invokers.java+158−0
@@ -0,0 +1,158 @@
1+/*
2+ * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package java.lang.invoke;
27+
28+import sun.invoke.empty.Empty;
29+import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
30+
31+/**
32+ * Construction and caching of often-used invokers.
33+ * @author jrose
34+ */
35+class Invokers {
36+ // exact type (sans leading taget MH) for the outgoing call
37+ private final MethodType targetType;
38+
39+ // exact invoker for the outgoing call
40+ private /*lazy*/ MethodHandle exactInvoker;
41+
42+ // erased (partially untyped but with primitives) invoker for the outgoing call
43+ private /*lazy*/ MethodHandle erasedInvoker;
44+ /*lazy*/ MethodHandle erasedInvokerWithDrops; // for InvokeGeneric
45+
46+ // general invoker for the outgoing call
47+ private /*lazy*/ MethodHandle generalInvoker;
48+
49+ // general invoker for the outgoing call, uses varargs
50+ private /*lazy*/ MethodHandle varargsInvoker;
51+
52+ // general invoker for the outgoing call; accepts a trailing Object[]
53+ private final /*lazy*/ MethodHandle[] spreadInvokers;
54+
55+ // invoker for an unbound callsite
56+ private /*lazy*/ MethodHandle uninitializedCallSite;
57+
58+ /** Compute and cache information common to all collecting adapters
59+ * that implement members of the erasure-family of the given erased type.
60+ */
61+ /*non-public*/ Invokers(MethodType targetType) {
62+ this.targetType = targetType;
63+ this.spreadInvokers = new MethodHandle[targetType.parameterCount()+1];
64+ }
65+
66+ /*non-public*/ static MethodType invokerType(MethodType targetType) {
67+ return targetType.insertParameterTypes(0, MethodHandle.class);
68+ }
69+
70+ /*non-public*/ MethodHandle exactInvoker() {
71+ MethodHandle invoker = exactInvoker;
72+ if (invoker != null) return invoker;
73+ invoker = lookupInvoker("invokeExact");
74+ exactInvoker = invoker;
75+ return invoker;
76+ }
77+
78+ /*non-public*/ MethodHandle generalInvoker() {
79+ MethodHandle invoker = generalInvoker;
80+ if (invoker != null) return invoker;
81+ invoker = lookupInvoker("invoke");
82+ generalInvoker = invoker;
83+ return invoker;
84+ }
85+
86+ private MethodHandle lookupInvoker(String name) {
87+ MethodHandle invoker;
88+ try {
89+ invoker = IMPL_LOOKUP.findVirtual(MethodHandle.class, name, targetType);
90+ } catch (ReflectiveOperationException ex) {
91+ throw new InternalError("JVM cannot find invoker for "+targetType);
92+ }
93+ assert(invokerType(targetType) == invoker.type());
94+ assert(!invoker.isVarargsCollector());
95+ return invoker;
96+ }
97+
98+ /*non-public*/ MethodHandle erasedInvoker() {
99+ MethodHandle xinvoker = exactInvoker();
100+ MethodHandle invoker = erasedInvoker;
101+ if (invoker != null) return invoker;
102+ MethodType erasedType = targetType.erase();
103+ invoker = xinvoker.asType(invokerType(erasedType));
104+ erasedInvoker = invoker;
105+ return invoker;
106+ }
107+
108+ /*non-public*/ MethodHandle spreadInvoker(int leadingArgCount) {
109+ MethodHandle vaInvoker = spreadInvokers[leadingArgCount];
110+ if (vaInvoker != null) return vaInvoker;
111+ MethodHandle gInvoker = generalInvoker();
112+ int spreadArgCount = targetType.parameterCount() - leadingArgCount;
113+ vaInvoker = gInvoker.asSpreader(Object[].class, spreadArgCount);
114+ spreadInvokers[leadingArgCount] = vaInvoker;
115+ return vaInvoker;
116+ }
117+
118+ /*non-public*/ MethodHandle varargsInvoker() {
119+ MethodHandle vaInvoker = varargsInvoker;
120+ if (vaInvoker != null) return vaInvoker;
121+ vaInvoker = spreadInvoker(0).asType(invokerType(MethodType.genericMethodType(0, true)));
122+ varargsInvoker = vaInvoker;
123+ return vaInvoker;
124+ }
125+
126+ private static MethodHandle THROW_UCS = null;
127+
128+ /*non-public*/ MethodHandle uninitializedCallSite() {
129+ MethodHandle invoker = uninitializedCallSite;
130+ if (invoker != null) return invoker;
131+ if (targetType.parameterCount() > 0) {
132+ MethodType type0 = targetType.dropParameterTypes(0, targetType.parameterCount());
133+ Invokers invokers0 = type0.invokers();
134+ invoker = MethodHandles.dropArguments(invokers0.uninitializedCallSite(),
135+ 0, targetType.parameterList());
136+ assert(invoker.type().equals(targetType));
137+ uninitializedCallSite = invoker;
138+ return invoker;
139+ }
140+ if (THROW_UCS == null) {
141+ try {
142+ THROW_UCS = IMPL_LOOKUP
143+ .findStatic(CallSite.class, "uninitializedCallSite",
144+ MethodType.methodType(Empty.class));
145+ } catch (ReflectiveOperationException ex) {
146+ throw new RuntimeException(ex);
147+ }
148+ }
149+ invoker = AdapterMethodHandle.makeRetypeRaw(targetType, THROW_UCS);
150+ assert(invoker.type().equals(targetType));
151+ uninitializedCallSite = invoker;
152+ return invoker;
153+ }
154+
155+ public String toString() {
156+ return "Invokers"+targetType;
157+ }
158+}