1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.netty.util.internal;
18
19 import java.lang.invoke.MethodHandle;
20 import java.lang.invoke.MethodHandles;
21 import java.lang.invoke.MethodType;
22 import java.lang.invoke.VarHandle;
23 import java.nio.ByteOrder;
24
25 final class VarHandleFactory {
26
27 private VarHandleFactory() {
28 }
29
30 private static final MethodHandle FIND_VAR_HANDLE;
31 private static final MethodHandle PRIVATE_LOOKUP_IN;
32 private static final VarHandle LONG_LE_ARRAY_VIEW;
33 private static final VarHandle LONG_BE_ARRAY_VIEW;
34 private static final VarHandle INT_LE_ARRAY_VIEW;
35 private static final VarHandle INT_BE_ARRAY_VIEW;
36 private static final VarHandle SHORT_LE_ARRAY_VIEW;
37 private static final VarHandle SHORT_BE_ARRAY_VIEW;
38 private static final VarHandle LONG_LE_BYTE_BUFFER_VIEW;
39 private static final VarHandle LONG_BE_BYTE_BUFFER_VIEW;
40 private static final VarHandle INT_LE_BYTE_BUFFER_VIEW;
41 private static final VarHandle INT_BE_BYTE_BUFFER_VIEW;
42 private static final VarHandle SHORT_LE_BYTE_BUFFER_VIEW;
43 private static final VarHandle SHORT_BE_BYTE_BUFFER_VIEW;
44 private static final Throwable UNAVAILABILITY_CAUSE;
45
46 static {
47 MethodHandle findVarHandle = null;
48 MethodHandle privateLookupIn = null;
49 VarHandle longLeArrayViewHandle = null;
50 VarHandle longBeArrayViewHandle = null;
51 VarHandle intLeArrayViewHandle = null;
52 VarHandle intBeArrayViewHandle = null;
53 VarHandle shortLeArrayViewHandle = null;
54 VarHandle shortBeArrayViewHandle = null;
55 VarHandle longLeByteBufferViewHandle = null;
56 VarHandle longBeByteBufferViewHandle = null;
57 VarHandle intLeByteBufferViewHandle = null;
58 VarHandle intBeByteBufferViewHandle = null;
59 VarHandle shortLeByteBufferViewHandle = null;
60 VarHandle shortBeByteBufferViewHandle = null;
61 Throwable error = null;
62 try {
63 MethodHandles.Lookup lookup = MethodHandles.lookup();
64 findVarHandle = lookup.findVirtual(MethodHandles.Lookup.class, "findVarHandle",
65 MethodType.methodType(VarHandle.class, Class.class, String.class, Class.class));
66 privateLookupIn = lookup.findStatic(MethodHandles.class, "privateLookupIn",
67 MethodType.methodType(MethodHandles.Lookup.class, Class.class, MethodHandles.Lookup.class));
68 MethodHandle byteArrayViewHandle = lookup.findStatic(MethodHandles.class, "byteArrayViewVarHandle",
69 MethodType.methodType(VarHandle.class, Class.class, ByteOrder.class));
70 longLeArrayViewHandle = (VarHandle) byteArrayViewHandle.invokeExact(long[].class, ByteOrder.LITTLE_ENDIAN);
71 longBeArrayViewHandle = (VarHandle) byteArrayViewHandle.invokeExact(long[].class, ByteOrder.BIG_ENDIAN);
72 intLeArrayViewHandle = (VarHandle) byteArrayViewHandle.invokeExact(int[].class, ByteOrder.LITTLE_ENDIAN);
73 intBeArrayViewHandle = (VarHandle) byteArrayViewHandle.invokeExact(int[].class, ByteOrder.BIG_ENDIAN);
74 shortLeArrayViewHandle = (VarHandle) byteArrayViewHandle.invokeExact(
75 short[].class, ByteOrder.LITTLE_ENDIAN);
76 shortBeArrayViewHandle = (VarHandle) byteArrayViewHandle.invokeExact(short[].class, ByteOrder.BIG_ENDIAN);
77 MethodHandle byteBufferViewHandle = lookup.findStatic(MethodHandles.class, "byteBufferViewVarHandle",
78 MethodType.methodType(VarHandle.class, Class.class, ByteOrder.class));
79 longLeByteBufferViewHandle = (VarHandle) byteBufferViewHandle.invokeExact(
80 long[].class, ByteOrder.LITTLE_ENDIAN);
81 longBeByteBufferViewHandle = (VarHandle) byteBufferViewHandle.invokeExact(
82 long[].class, ByteOrder.BIG_ENDIAN);
83 intLeByteBufferViewHandle = (VarHandle) byteBufferViewHandle.invokeExact(
84 int[].class, ByteOrder.LITTLE_ENDIAN);
85 intBeByteBufferViewHandle = (VarHandle) byteBufferViewHandle.invokeExact(
86 int[].class, ByteOrder.BIG_ENDIAN);
87 shortLeByteBufferViewHandle = (VarHandle) byteBufferViewHandle.invokeExact(
88 short[].class, ByteOrder.LITTLE_ENDIAN);
89 shortBeByteBufferViewHandle = (VarHandle) byteBufferViewHandle.invokeExact(
90 short[].class, ByteOrder.BIG_ENDIAN);
91 error = null;
92 } catch (Throwable e) {
93 error = e;
94 findVarHandle = null;
95 privateLookupIn = null;
96 longLeArrayViewHandle = null;
97 longBeArrayViewHandle = null;
98 intLeArrayViewHandle = null;
99 intBeArrayViewHandle = null;
100 shortLeArrayViewHandle = null;
101 longLeByteBufferViewHandle = null;
102 longBeByteBufferViewHandle = null;
103 intLeByteBufferViewHandle = null;
104 intBeByteBufferViewHandle = null;
105 shortLeByteBufferViewHandle = null;
106 shortBeByteBufferViewHandle = null;
107 } finally {
108 FIND_VAR_HANDLE = findVarHandle;
109 PRIVATE_LOOKUP_IN = privateLookupIn;
110 LONG_LE_ARRAY_VIEW = longLeArrayViewHandle;
111 LONG_BE_ARRAY_VIEW = longBeArrayViewHandle;
112 INT_LE_ARRAY_VIEW = intLeArrayViewHandle;
113 INT_BE_ARRAY_VIEW = intBeArrayViewHandle;
114 SHORT_LE_ARRAY_VIEW = shortLeArrayViewHandle;
115 SHORT_BE_ARRAY_VIEW = shortBeArrayViewHandle;
116 LONG_LE_BYTE_BUFFER_VIEW = longLeByteBufferViewHandle;
117 LONG_BE_BYTE_BUFFER_VIEW = longBeByteBufferViewHandle;
118 INT_LE_BYTE_BUFFER_VIEW = intLeByteBufferViewHandle;
119 INT_BE_BYTE_BUFFER_VIEW = intBeByteBufferViewHandle;
120 SHORT_LE_BYTE_BUFFER_VIEW = shortLeByteBufferViewHandle;
121 SHORT_BE_BYTE_BUFFER_VIEW = shortBeByteBufferViewHandle;
122 UNAVAILABILITY_CAUSE = error;
123 }
124 }
125
126 public static boolean isSupported() {
127 return UNAVAILABILITY_CAUSE == null;
128 }
129
130 public static Throwable unavailableCause() {
131 return UNAVAILABILITY_CAUSE;
132 }
133
134 private static MethodHandles.Lookup privateLookup(MethodHandles.Lookup lookup, Class<?> targetClass) {
135 try {
136 return (MethodHandles.Lookup) PRIVATE_LOOKUP_IN.invokeExact(targetClass, lookup);
137 } catch (Throwable e) {
138 throw new RuntimeException(e);
139 }
140 }
141
142 public static VarHandle privateFindVarHandle(MethodHandles.Lookup lookup, Class<?> declaringClass,
143 String name, Class<?> type) {
144 try {
145 return (VarHandle) FIND_VAR_HANDLE.invokeExact(privateLookup(lookup, declaringClass),
146 declaringClass, name, type);
147 } catch (Throwable e) {
148 throw new RuntimeException(e);
149 }
150 }
151
152 public static VarHandle longLeArrayView() {
153 return LONG_LE_ARRAY_VIEW;
154 }
155
156 public static VarHandle longBeArrayView() {
157 return LONG_BE_ARRAY_VIEW;
158 }
159
160 public static VarHandle intLeArrayView() {
161 return INT_LE_ARRAY_VIEW;
162 }
163
164 public static VarHandle intBeArrayView() {
165 return INT_BE_ARRAY_VIEW;
166 }
167
168 public static VarHandle shortLeArrayView() {
169 return SHORT_LE_ARRAY_VIEW;
170 }
171
172 public static VarHandle shortBeArrayView() {
173 return SHORT_BE_ARRAY_VIEW;
174 }
175
176 public static VarHandle longLeByteBufferView() {
177 return LONG_LE_BYTE_BUFFER_VIEW;
178 }
179
180 public static VarHandle longBeByteBufferView() {
181 return LONG_BE_BYTE_BUFFER_VIEW;
182 }
183
184 public static VarHandle intLeByteBufferView() {
185 return INT_LE_BYTE_BUFFER_VIEW;
186 }
187
188 public static VarHandle intBeByteBufferView() {
189 return INT_BE_BYTE_BUFFER_VIEW;
190 }
191
192 public static VarHandle shortLeByteBufferView() {
193 return SHORT_LE_BYTE_BUFFER_VIEW;
194 }
195
196 public static VarHandle shortBeByteBufferView() {
197 return SHORT_BE_BYTE_BUFFER_VIEW;
198 }
199 }