1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <nativehelper/JniConstants.h>
18 #include <nativehelper/JNIHelp.h>
19
20 /** Signature for VarHandle access mode methods with a void return type. */
21 static const char* kVarHandleVoidSignature = "([Ljava/lang/Object;)V";
22
23 /** Signature for VarHandle access mode methods returning an object reference. */
24 static const char* kVarHandleBooleanSignature = "([Ljava/lang/Object;)Z";
25
26 /** Signature for VarHandle access mode methods returning a boolean value. */
27 static const char* kVarHandleObjectSignature = "([Ljava/lang/Object;)Ljava/lang/Object;";
28
29
ThrowUnsupportedOperationForAccessMode(JNIEnv * env,const char * accessMode)30 static void ThrowUnsupportedOperationForAccessMode(JNIEnv* env, const char* accessMode) {
31 // VarHandle access mode methods should be dispatched by the
32 // interpreter or inlined into compiled code. The JNI methods below
33 // are discoverable via reflection, but are not intended to be
34 // invoked this way.
35 jniThrowExceptionFmt(env,
36 "java/lang/UnsupportedOperationException",
37 "VarHandle.%s cannot be invoked reflectively.",
38 accessMode);
39 }
40
VarHandle_compareAndExchange(JNIEnv * env,jobject,jobjectArray)41 static void VarHandle_compareAndExchange(JNIEnv* env, jobject, jobjectArray) {
42 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
43 ThrowUnsupportedOperationForAccessMode(env, "compareAndExchange");
44 }
45
VarHandle_compareAndExchangeAcquire(JNIEnv * env,jobject,jobjectArray)46 static void VarHandle_compareAndExchangeAcquire(JNIEnv* env, jobject, jobjectArray) {
47 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
48 ThrowUnsupportedOperationForAccessMode(env, "compareAndExchangeAcquire");
49 }
50
VarHandle_compareAndExchangeRelease(JNIEnv * env,jobject,jobjectArray)51 static void VarHandle_compareAndExchangeRelease(JNIEnv* env, jobject, jobjectArray) {
52 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
53 ThrowUnsupportedOperationForAccessMode(env, "compareAndExchangeRelease");
54 }
55
VarHandle_compareAndSet(JNIEnv * env,jobject,jobjectArray)56 static void VarHandle_compareAndSet(JNIEnv* env, jobject, jobjectArray) {
57 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
58 ThrowUnsupportedOperationForAccessMode(env, "compareAndSet");
59 }
60
VarHandle_get(JNIEnv * env,jobject,jobjectArray)61 static void VarHandle_get(JNIEnv* env, jobject, jobjectArray) {
62 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
63 ThrowUnsupportedOperationForAccessMode(env, "get");
64 }
65
VarHandle_getAcquire(JNIEnv * env,jobject,jobjectArray)66 static void VarHandle_getAcquire(JNIEnv* env, jobject, jobjectArray) {
67 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
68 ThrowUnsupportedOperationForAccessMode(env, "getAcquire");
69 }
70
VarHandle_getAndAdd(JNIEnv * env,jobject,jobjectArray)71 static void VarHandle_getAndAdd(JNIEnv* env, jobject, jobjectArray) {
72 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
73 ThrowUnsupportedOperationForAccessMode(env, "getAndAdd");
74 }
75
VarHandle_getAndAddAcquire(JNIEnv * env,jobject,jobjectArray)76 static void VarHandle_getAndAddAcquire(JNIEnv* env, jobject, jobjectArray) {
77 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
78 ThrowUnsupportedOperationForAccessMode(env, "getAndAddAcquire");
79 }
80
VarHandle_getAndAddRelease(JNIEnv * env,jobject,jobjectArray)81 static void VarHandle_getAndAddRelease(JNIEnv* env, jobject, jobjectArray) {
82 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
83 ThrowUnsupportedOperationForAccessMode(env, "getAndAddRelease");
84 }
85
VarHandle_getAndBitwiseAnd(JNIEnv * env,jobject,jobjectArray)86 static void VarHandle_getAndBitwiseAnd(JNIEnv* env, jobject, jobjectArray) {
87 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
88 ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseAnd");
89 }
90
VarHandle_getAndBitwiseAndAcquire(JNIEnv * env,jobject,jobjectArray)91 static void VarHandle_getAndBitwiseAndAcquire(JNIEnv* env, jobject, jobjectArray) {
92 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
93 ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseAndAcquire");
94 }
95
VarHandle_getAndBitwiseAndRelease(JNIEnv * env,jobject,jobjectArray)96 static void VarHandle_getAndBitwiseAndRelease(JNIEnv* env, jobject, jobjectArray) {
97 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
98 ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseAndRelease");
99 }
100
VarHandle_getAndBitwiseOr(JNIEnv * env,jobject,jobjectArray)101 static void VarHandle_getAndBitwiseOr(JNIEnv* env, jobject, jobjectArray) {
102 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
103 ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseOr");
104 }
105
VarHandle_getAndBitwiseOrAcquire(JNIEnv * env,jobject,jobjectArray)106 static void VarHandle_getAndBitwiseOrAcquire(JNIEnv* env, jobject, jobjectArray) {
107 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
108 ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseOrAcquire");
109 }
110
VarHandle_getAndBitwiseOrRelease(JNIEnv * env,jobject,jobjectArray)111 static void VarHandle_getAndBitwiseOrRelease(JNIEnv* env, jobject, jobjectArray) {
112 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
113 ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseOrRelease");
114 }
115
VarHandle_getAndBitwiseXor(JNIEnv * env,jobject,jobjectArray)116 static void VarHandle_getAndBitwiseXor(JNIEnv* env, jobject, jobjectArray) {
117 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
118 ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseXor");
119 }
120
VarHandle_getAndBitwiseXorAcquire(JNIEnv * env,jobject,jobjectArray)121 static void VarHandle_getAndBitwiseXorAcquire(JNIEnv* env, jobject, jobjectArray) {
122 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
123 ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseXorAcquire");
124 }
125
VarHandle_getAndBitwiseXorRelease(JNIEnv * env,jobject,jobjectArray)126 static void VarHandle_getAndBitwiseXorRelease(JNIEnv* env, jobject, jobjectArray) {
127 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
128 ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseXorRelease");
129 }
130
VarHandle_getAndSet(JNIEnv * env,jobject,jobjectArray)131 static void VarHandle_getAndSet(JNIEnv* env, jobject, jobjectArray) {
132 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
133 ThrowUnsupportedOperationForAccessMode(env, "getAndSet");
134 }
135
VarHandle_getAndSetAcquire(JNIEnv * env,jobject,jobjectArray)136 static void VarHandle_getAndSetAcquire(JNIEnv* env, jobject, jobjectArray) {
137 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
138 ThrowUnsupportedOperationForAccessMode(env, "getAndSetAcquire");
139 }
140
VarHandle_getAndSetRelease(JNIEnv * env,jobject,jobjectArray)141 static void VarHandle_getAndSetRelease(JNIEnv* env, jobject, jobjectArray) {
142 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
143 ThrowUnsupportedOperationForAccessMode(env, "getAndSetRelease");
144 }
145
VarHandle_getOpaque(JNIEnv * env,jobject,jobjectArray)146 static void VarHandle_getOpaque(JNIEnv* env, jobject, jobjectArray) {
147 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
148 ThrowUnsupportedOperationForAccessMode(env, "getOpaque");
149 }
150
VarHandle_getVolatile(JNIEnv * env,jobject,jobjectArray)151 static void VarHandle_getVolatile(JNIEnv* env, jobject, jobjectArray) {
152 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
153 ThrowUnsupportedOperationForAccessMode(env, "getVolatile");
154 }
155
VarHandle_set(JNIEnv * env,jobject,jobjectArray)156 static void VarHandle_set(JNIEnv* env, jobject, jobjectArray) {
157 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
158 ThrowUnsupportedOperationForAccessMode(env, "set");
159 }
160
VarHandle_setOpaque(JNIEnv * env,jobject,jobjectArray)161 static void VarHandle_setOpaque(JNIEnv* env, jobject, jobjectArray) {
162 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
163 ThrowUnsupportedOperationForAccessMode(env, "setOpaque");
164 }
165
VarHandle_setRelease(JNIEnv * env,jobject,jobjectArray)166 static void VarHandle_setRelease(JNIEnv* env, jobject, jobjectArray) {
167 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
168 ThrowUnsupportedOperationForAccessMode(env, "setRelease");
169 }
170
VarHandle_setVolatile(JNIEnv * env,jobject,jobjectArray)171 static void VarHandle_setVolatile(JNIEnv* env, jobject, jobjectArray) {
172 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
173 ThrowUnsupportedOperationForAccessMode(env, "setVolatile");
174 }
175
VarHandle_weakCompareAndSet(JNIEnv * env,jobject,jobjectArray)176 static void VarHandle_weakCompareAndSet(JNIEnv* env, jobject, jobjectArray) {
177 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
178 ThrowUnsupportedOperationForAccessMode(env, "weakCompareAndSet");
179 }
180
VarHandle_weakCompareAndSetAcquire(JNIEnv * env,jobject,jobjectArray)181 static void VarHandle_weakCompareAndSetAcquire(JNIEnv* env, jobject, jobjectArray) {
182 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
183 ThrowUnsupportedOperationForAccessMode(env, "weakCompareAndSetAcquire");
184 }
185
VarHandle_weakCompareAndSetPlain(JNIEnv * env,jobject,jobjectArray)186 static void VarHandle_weakCompareAndSetPlain(JNIEnv* env, jobject, jobjectArray) {
187 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
188 ThrowUnsupportedOperationForAccessMode(env, "weakCompareAndSetPlain");
189 }
190
VarHandle_weakCompareAndSetRelease(JNIEnv * env,jobject,jobjectArray)191 static void VarHandle_weakCompareAndSetRelease(JNIEnv* env, jobject, jobjectArray) {
192 // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
193 ThrowUnsupportedOperationForAccessMode(env, "weakCompareAndSetRelease");
194 }
195
196 static JNINativeMethod gMethods[] = {
197 NATIVE_METHOD(VarHandle, compareAndExchange, kVarHandleObjectSignature),
198 NATIVE_METHOD(VarHandle, compareAndExchangeAcquire, kVarHandleObjectSignature),
199 NATIVE_METHOD(VarHandle, compareAndExchangeRelease, kVarHandleObjectSignature),
200 NATIVE_METHOD(VarHandle, compareAndSet, kVarHandleBooleanSignature),
201 NATIVE_METHOD(VarHandle, get, kVarHandleObjectSignature),
202 NATIVE_METHOD(VarHandle, getAcquire, kVarHandleObjectSignature),
203 NATIVE_METHOD(VarHandle, getAndAdd, kVarHandleObjectSignature),
204 NATIVE_METHOD(VarHandle, getAndAddAcquire, kVarHandleObjectSignature),
205 NATIVE_METHOD(VarHandle, getAndAddRelease, kVarHandleObjectSignature),
206 NATIVE_METHOD(VarHandle, getAndBitwiseAnd, kVarHandleObjectSignature),
207 NATIVE_METHOD(VarHandle, getAndBitwiseAndAcquire, kVarHandleObjectSignature),
208 NATIVE_METHOD(VarHandle, getAndBitwiseAndRelease, kVarHandleObjectSignature),
209 NATIVE_METHOD(VarHandle, getAndBitwiseOr, kVarHandleObjectSignature),
210 NATIVE_METHOD(VarHandle, getAndBitwiseOrAcquire, kVarHandleObjectSignature),
211 NATIVE_METHOD(VarHandle, getAndBitwiseOrRelease, kVarHandleObjectSignature),
212 NATIVE_METHOD(VarHandle, getAndBitwiseXor, kVarHandleObjectSignature),
213 NATIVE_METHOD(VarHandle, getAndBitwiseXorAcquire, kVarHandleObjectSignature),
214 NATIVE_METHOD(VarHandle, getAndBitwiseXorRelease, kVarHandleObjectSignature),
215 NATIVE_METHOD(VarHandle, getAndSet, kVarHandleObjectSignature),
216 NATIVE_METHOD(VarHandle, getAndSetAcquire, kVarHandleObjectSignature),
217 NATIVE_METHOD(VarHandle, getAndSetRelease, kVarHandleObjectSignature),
218 NATIVE_METHOD(VarHandle, getOpaque, kVarHandleObjectSignature),
219 NATIVE_METHOD(VarHandle, getVolatile, kVarHandleObjectSignature),
220 NATIVE_METHOD(VarHandle, set, kVarHandleVoidSignature),
221 NATIVE_METHOD(VarHandle, setOpaque, kVarHandleVoidSignature),
222 NATIVE_METHOD(VarHandle, setRelease, kVarHandleVoidSignature),
223 NATIVE_METHOD(VarHandle, setVolatile, kVarHandleVoidSignature),
224 NATIVE_METHOD(VarHandle, weakCompareAndSet, kVarHandleBooleanSignature),
225 NATIVE_METHOD(VarHandle, weakCompareAndSetAcquire, kVarHandleBooleanSignature),
226 NATIVE_METHOD(VarHandle, weakCompareAndSetPlain, kVarHandleBooleanSignature),
227 NATIVE_METHOD(VarHandle, weakCompareAndSetRelease, kVarHandleBooleanSignature),
228 };
229
register_java_lang_invoke_VarHandle(JNIEnv * env)230 void register_java_lang_invoke_VarHandle(JNIEnv* env) {
231 jniRegisterNativeMethods(env, "java/lang/invoke/VarHandle", gMethods, NELEM(gMethods));
232 }
233