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
26package java.lang.invoke;
27
28import sun.invoke.empty.Empty;
29import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
30
31/**
32 * Construction and caching of often-used invokers.
33 * @author jrose
34 */
35class 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}