blob: e021b77dae3a3ee10b62395995a12ba0ca543d20 [file] [log] [blame]
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -07001/*
2 * Copyright (C) 2008 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
Andreas Gampe277ccbd2014-11-03 21:36:10 -080017#include "sun_misc_Unsafe.h"
Andreas Gampea14100c2017-04-24 15:09:56 -070018
Andreas Gampea14100c2017-04-24 15:09:56 -070019#include <unistd.h>
20
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070021#include <cstdlib>
22#include <cstring>
23#include <atomic>
24
Andreas Gampea14100c2017-04-24 15:09:56 -070025#include "nativehelper/jni_macros.h"
26
David Sehrc431b9d2018-03-02 12:01:51 -080027#include "base/quasi_atomic.h"
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +010028#include "common_throws.h"
Ian Rogers1d54e732013-05-02 21:10:01 -070029#include "gc/accounting/card_table-inl.h"
Vladimir Markoa3ad0cd2018-05-04 10:06:38 +010030#include "jni/jni_internal.h"
Hiroshi Yamauchi4d2efce2014-02-10 16:19:09 -080031#include "mirror/array.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070032#include "mirror/class-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080033#include "mirror/object-inl.h"
Andreas Gampe87583b32017-05-25 11:22:18 -070034#include "native_util.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070035#include "scoped_fast_native_object_access-inl.h"
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070036
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070037namespace art {
38
Ian Rogersef7d42f2014-01-06 12:55:46 -080039static jboolean Unsafe_compareAndSwapInt(JNIEnv* env, jobject, jobject javaObj, jlong offset,
40 jint expectedValue, jint newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070041 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -070042 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010043 // JNI must use non transactional mode.
Mathieu Chartier42c2e502018-06-19 12:30:56 -070044 bool success = obj->CasField32<false>(MemberOffset(offset),
45 expectedValue,
46 newValue,
47 CASMode::kStrong,
48 std::memory_order_seq_cst);
Ian Rogers9adbff52013-01-23 18:19:03 -080049 return success ? JNI_TRUE : JNI_FALSE;
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070050}
51
Ian Rogersef7d42f2014-01-06 12:55:46 -080052static jboolean Unsafe_compareAndSwapLong(JNIEnv* env, jobject, jobject javaObj, jlong offset,
53 jlong expectedValue, jlong newValue) {
54 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -070055 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010056 // JNI must use non transactional mode.
Hans Boehmd8434432014-07-11 09:56:07 -070057 bool success = obj->CasFieldStrongSequentiallyConsistent64<false>(MemberOffset(offset),
Mathieu Chartier0795f232016-09-27 18:43:30 -070058 expectedValue,
59 newValue);
Ian Rogersef7d42f2014-01-06 12:55:46 -080060 return success ? JNI_TRUE : JNI_FALSE;
61}
62
63static jboolean Unsafe_compareAndSwapObject(JNIEnv* env, jobject, jobject javaObj, jlong offset,
64 jobject javaExpectedValue, jobject javaNewValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070065 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -070066 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
67 ObjPtr<mirror::Object> expectedValue = soa.Decode<mirror::Object>(javaExpectedValue);
68 ObjPtr<mirror::Object> newValue = soa.Decode<mirror::Object>(javaNewValue);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010069 // JNI must use non transactional mode.
Hiroshi Yamauchicc78f3f2015-12-11 15:51:04 -080070 if (kUseReadBarrier) {
71 // Need to make sure the reference stored in the field is a to-space one before attempting the
72 // CAS or the CAS could fail incorrectly.
Hans Boehmcc55e1d2017-07-27 15:28:07 -070073 // Note that the read barrier load does NOT need to be volatile.
Hiroshi Yamauchicc78f3f2015-12-11 15:51:04 -080074 mirror::HeapReference<mirror::Object>* field_addr =
75 reinterpret_cast<mirror::HeapReference<mirror::Object>*>(
Mathieu Chartier1cc62e42016-10-03 18:01:28 -070076 reinterpret_cast<uint8_t*>(obj.Ptr()) + static_cast<size_t>(offset));
Andreas Gampe98ea9d92018-10-19 14:06:15 -070077 ReadBarrier::Barrier<mirror::Object, /* kIsVolatile= */ false, kWithReadBarrier,
78 /* kAlwaysUpdateField= */ true>(
Mathieu Chartier1cc62e42016-10-03 18:01:28 -070079 obj.Ptr(),
Hiroshi Yamauchicc78f3f2015-12-11 15:51:04 -080080 MemberOffset(offset),
81 field_addr);
82 }
Mathieu Chartiera9746b92018-06-22 10:25:40 -070083 bool success = obj->CasFieldObject<false>(MemberOffset(offset),
84 expectedValue,
85 newValue,
86 CASMode::kStrong,
87 std::memory_order_seq_cst);
Ian Rogersef7d42f2014-01-06 12:55:46 -080088 return success ? JNI_TRUE : JNI_FALSE;
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070089}
90
Elliott Hughes0512f022012-03-15 22:10:52 -070091static jint Unsafe_getInt(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070092 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -070093 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070094 return obj->GetField32(MemberOffset(offset));
Ian Rogers5d76c432011-10-31 21:42:49 -070095}
96
Elliott Hughes0512f022012-03-15 22:10:52 -070097static jint Unsafe_getIntVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070098 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -070099 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700100 return obj->GetField32Volatile(MemberOffset(offset));
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700101}
102
Elliott Hughes0512f022012-03-15 22:10:52 -0700103static void Unsafe_putInt(JNIEnv* env, jobject, jobject javaObj, jlong offset, jint newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700104 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700105 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100106 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700107 obj->SetField32<false>(MemberOffset(offset), newValue);
Ian Rogers5d76c432011-10-31 21:42:49 -0700108}
109
Ian Rogersef7d42f2014-01-06 12:55:46 -0800110static void Unsafe_putIntVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset,
111 jint newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700112 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700113 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100114 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700115 obj->SetField32Volatile<false>(MemberOffset(offset), newValue);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700116}
117
Ian Rogersef7d42f2014-01-06 12:55:46 -0800118static void Unsafe_putOrderedInt(JNIEnv* env, jobject, jobject javaObj, jlong offset,
119 jint newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700120 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700121 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Hans Boehmcc55e1d2017-07-27 15:28:07 -0700122 // TODO: A release store is likely to be faster on future processors.
Orion Hodson27b96762018-03-13 16:06:57 +0000123 std::atomic_thread_fence(std::memory_order_release);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100124 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700125 obj->SetField32<false>(MemberOffset(offset), newValue);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700126}
127
Elliott Hughes0512f022012-03-15 22:10:52 -0700128static jlong Unsafe_getLong(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700129 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700130 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700131 return obj->GetField64(MemberOffset(offset));
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700132}
133
Elliott Hughes0512f022012-03-15 22:10:52 -0700134static jlong Unsafe_getLongVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700135 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700136 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700137 return obj->GetField64Volatile(MemberOffset(offset));
Ian Rogers5d76c432011-10-31 21:42:49 -0700138}
139
Elliott Hughes0512f022012-03-15 22:10:52 -0700140static void Unsafe_putLong(JNIEnv* env, jobject, jobject javaObj, jlong offset, jlong newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700141 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700142 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100143 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700144 obj->SetField64<false>(MemberOffset(offset), newValue);
Ian Rogers5d76c432011-10-31 21:42:49 -0700145}
146
Ian Rogersef7d42f2014-01-06 12:55:46 -0800147static void Unsafe_putLongVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset,
148 jlong newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700149 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700150 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100151 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700152 obj->SetField64Volatile<false>(MemberOffset(offset), newValue);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700153}
154
Ian Rogersef7d42f2014-01-06 12:55:46 -0800155static void Unsafe_putOrderedLong(JNIEnv* env, jobject, jobject javaObj, jlong offset,
156 jlong newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700157 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700158 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Orion Hodson27b96762018-03-13 16:06:57 +0000159 std::atomic_thread_fence(std::memory_order_release);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100160 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700161 obj->SetField64<false>(MemberOffset(offset), newValue);
Ian Rogers5d76c432011-10-31 21:42:49 -0700162}
163
Elliott Hughes0512f022012-03-15 22:10:52 -0700164static jobject Unsafe_getObjectVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700165 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700166 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
167 ObjPtr<mirror::Object> value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700168 return soa.AddLocalReference<jobject>(value);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700169}
170
Elliott Hughes0512f022012-03-15 22:10:52 -0700171static jobject Unsafe_getObject(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700172 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700173 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
174 ObjPtr<mirror::Object> value = obj->GetFieldObject<mirror::Object>(MemberOffset(offset));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700175 return soa.AddLocalReference<jobject>(value);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700176}
177
Ian Rogersef7d42f2014-01-06 12:55:46 -0800178static void Unsafe_putObject(JNIEnv* env, jobject, jobject javaObj, jlong offset,
179 jobject javaNewValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700180 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700181 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
182 ObjPtr<mirror::Object> newValue = soa.Decode<mirror::Object>(javaNewValue);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100183 // JNI must use non transactional mode.
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700184 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700185}
186
Ian Rogersef7d42f2014-01-06 12:55:46 -0800187static void Unsafe_putObjectVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset,
188 jobject javaNewValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700189 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700190 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
191 ObjPtr<mirror::Object> newValue = soa.Decode<mirror::Object>(javaNewValue);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100192 // JNI must use non transactional mode.
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700193 obj->SetFieldObjectVolatile<false>(MemberOffset(offset), newValue);
Ian Rogers5d76c432011-10-31 21:42:49 -0700194}
195
Ian Rogersef7d42f2014-01-06 12:55:46 -0800196static void Unsafe_putOrderedObject(JNIEnv* env, jobject, jobject javaObj, jlong offset,
197 jobject javaNewValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700198 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700199 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
200 ObjPtr<mirror::Object> newValue = soa.Decode<mirror::Object>(javaNewValue);
Orion Hodson27b96762018-03-13 16:06:57 +0000201 std::atomic_thread_fence(std::memory_order_release);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100202 // JNI must use non transactional mode.
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700203 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700204}
205
Igor Murashkin06537f72018-02-22 15:03:05 -0800206static jint Unsafe_getArrayBaseOffsetForComponentType(JNIEnv* env, jclass, jclass component_class) {
Hiroshi Yamauchi4d2efce2014-02-10 16:19:09 -0800207 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700208 ObjPtr<mirror::Class> component = soa.Decode<mirror::Class>(component_class);
Hiroshi Yamauchi4d2efce2014-02-10 16:19:09 -0800209 Primitive::Type primitive_type = component->GetPrimitiveType();
210 return mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value();
211}
212
Igor Murashkin06537f72018-02-22 15:03:05 -0800213static jint Unsafe_getArrayIndexScaleForComponentType(JNIEnv* env, jclass, jclass component_class) {
Hiroshi Yamauchi4d2efce2014-02-10 16:19:09 -0800214 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700215 ObjPtr<mirror::Class> component = soa.Decode<mirror::Class>(component_class);
Hiroshi Yamauchi4d2efce2014-02-10 16:19:09 -0800216 Primitive::Type primitive_type = component->GetPrimitiveType();
217 return Primitive::ComponentSize(primitive_type);
218}
219
Przemyslaw Szczepaniak6c0ea272015-09-23 08:48:00 +0100220static jint Unsafe_addressSize(JNIEnv* env ATTRIBUTE_UNUSED, jobject ob ATTRIBUTE_UNUSED) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100221 return sizeof(void*);
222}
223
Przemyslaw Szczepaniak6c0ea272015-09-23 08:48:00 +0100224static jint Unsafe_pageSize(JNIEnv* env ATTRIBUTE_UNUSED, jobject ob ATTRIBUTE_UNUSED) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100225 return sysconf(_SC_PAGESIZE);
226}
227
228static jlong Unsafe_allocateMemory(JNIEnv* env, jobject, jlong bytes) {
229 ScopedFastNativeObjectAccess soa(env);
230 // bytes is nonnegative and fits into size_t
231 if (bytes < 0 || bytes != (jlong)(size_t) bytes) {
Narayan Kamathd1ef4362015-11-12 11:49:06 +0000232 ThrowIllegalAccessException("wrong number of bytes");
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100233 return 0;
234 }
235 void* mem = malloc(bytes);
236 if (mem == nullptr) {
237 soa.Self()->ThrowOutOfMemoryError("native alloc");
238 return 0;
239 }
240 return (uintptr_t) mem;
241}
242
Przemyslaw Szczepaniak6c0ea272015-09-23 08:48:00 +0100243static void Unsafe_freeMemory(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) {
Narayan Kamatha0cf5a62015-09-07 11:41:37 +0100244 free(reinterpret_cast<void*>(static_cast<uintptr_t>(address)));
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100245}
246
Przemyslaw Szczepaniak6c0ea272015-09-23 08:48:00 +0100247static void Unsafe_setMemory(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jlong bytes, jbyte value) {
Narayan Kamatha0cf5a62015-09-07 11:41:37 +0100248 memset(reinterpret_cast<void*>(static_cast<uintptr_t>(address)), value, bytes);
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100249}
250
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000251static jbyte Unsafe_getByteJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100252 return *reinterpret_cast<jbyte*>(address);
253}
254
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000255static void Unsafe_putByteJB(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jbyte value) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100256 *reinterpret_cast<jbyte*>(address) = value;
257}
258
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000259static jshort Unsafe_getShortJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100260 return *reinterpret_cast<jshort*>(address);
261}
262
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000263static void Unsafe_putShortJS(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jshort value) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100264 *reinterpret_cast<jshort*>(address) = value;
265}
266
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000267static jchar Unsafe_getCharJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100268 return *reinterpret_cast<jchar*>(address);
269}
270
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000271static void Unsafe_putCharJC(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jchar value) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100272 *reinterpret_cast<jchar*>(address) = value;
273}
274
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000275static jint Unsafe_getIntJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100276 return *reinterpret_cast<jint*>(address);
277}
278
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000279static void Unsafe_putIntJI(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jint value) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100280 *reinterpret_cast<jint*>(address) = value;
281}
282
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000283static jlong Unsafe_getLongJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100284 return *reinterpret_cast<jlong*>(address);
285}
286
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000287static void Unsafe_putLongJJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jlong value) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100288 *reinterpret_cast<jlong*>(address) = value;
289}
290
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000291static jfloat Unsafe_getFloatJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100292 return *reinterpret_cast<jfloat*>(address);
293}
294
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000295static void Unsafe_putFloatJF(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jfloat value) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100296 *reinterpret_cast<jfloat*>(address) = value;
297}
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000298static jdouble Unsafe_getDoubleJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100299 return *reinterpret_cast<jdouble*>(address);
300}
301
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000302static void Unsafe_putDoubleJD(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jdouble value) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100303 *reinterpret_cast<jdouble*>(address) = value;
304}
305
Przemyslaw Szczepaniak6c0ea272015-09-23 08:48:00 +0100306static void Unsafe_copyMemory(JNIEnv *env, jobject unsafe ATTRIBUTE_UNUSED, jlong src,
307 jlong dst, jlong size) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700308 if (size == 0) {
309 return;
310 }
311 // size is nonnegative and fits into size_t
312 if (size < 0 || size != (jlong)(size_t) size) {
313 ScopedFastNativeObjectAccess soa(env);
314 ThrowIllegalAccessException("wrong number of bytes");
315 }
316 size_t sz = (size_t)size;
317 memcpy(reinterpret_cast<void *>(dst), reinterpret_cast<void *>(src), sz);
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100318}
319
320template<typename T>
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700321static void copyToArray(jlong srcAddr,
322 ObjPtr<mirror::PrimitiveArray<T>> array,
Przemyslaw Szczepaniak903ac272015-07-23 09:30:35 +0100323 size_t array_offset,
324 size_t size)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700325 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700326 const T* src = reinterpret_cast<T*>(srcAddr);
327 size_t sz = size / sizeof(T);
328 size_t of = array_offset / sizeof(T);
329 for (size_t i = 0; i < sz; ++i) {
330 array->Set(i + of, *(src + i));
331 }
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100332}
333
334template<typename T>
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700335static void copyFromArray(jlong dstAddr,
336 ObjPtr<mirror::PrimitiveArray<T>> array,
Przemyslaw Szczepaniak903ac272015-07-23 09:30:35 +0100337 size_t array_offset,
338 size_t size)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700339 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700340 T* dst = reinterpret_cast<T*>(dstAddr);
341 size_t sz = size / sizeof(T);
342 size_t of = array_offset / sizeof(T);
343 for (size_t i = 0; i < sz; ++i) {
344 *(dst + i) = array->Get(i + of);
345 }
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100346}
347
348static void Unsafe_copyMemoryToPrimitiveArray(JNIEnv *env,
Przemyslaw Szczepaniak6c0ea272015-09-23 08:48:00 +0100349 jobject unsafe ATTRIBUTE_UNUSED,
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100350 jlong srcAddr,
351 jobject dstObj,
352 jlong dstOffset,
353 jlong size) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700354 ScopedObjectAccess soa(env);
355 if (size == 0) {
356 return;
357 }
358 // size is nonnegative and fits into size_t
359 if (size < 0 || size != (jlong)(size_t) size) {
360 ThrowIllegalAccessException("wrong number of bytes");
361 }
362 size_t sz = (size_t)size;
363 size_t dst_offset = (size_t)dstOffset;
364 ObjPtr<mirror::Object> dst = soa.Decode<mirror::Object>(dstObj);
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700365 ObjPtr<mirror::Class> component_type = dst->GetClass()->GetComponentType();
Mathieu Chartier0795f232016-09-27 18:43:30 -0700366 if (component_type->IsPrimitiveByte() || component_type->IsPrimitiveBoolean()) {
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700367 copyToArray(srcAddr, MakeObjPtr(dst->AsByteSizedArray()), dst_offset, sz);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700368 } else if (component_type->IsPrimitiveShort() || component_type->IsPrimitiveChar()) {
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700369 copyToArray(srcAddr, MakeObjPtr(dst->AsShortSizedArray()), dst_offset, sz);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700370 } else if (component_type->IsPrimitiveInt() || component_type->IsPrimitiveFloat()) {
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700371 copyToArray(srcAddr, MakeObjPtr(dst->AsIntArray()), dst_offset, sz);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700372 } else if (component_type->IsPrimitiveLong() || component_type->IsPrimitiveDouble()) {
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700373 copyToArray(srcAddr, MakeObjPtr(dst->AsLongArray()), dst_offset, sz);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700374 } else {
375 ThrowIllegalAccessException("not a primitive array");
376 }
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100377}
378
379static void Unsafe_copyMemoryFromPrimitiveArray(JNIEnv *env,
Przemyslaw Szczepaniak6c0ea272015-09-23 08:48:00 +0100380 jobject unsafe ATTRIBUTE_UNUSED,
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100381 jobject srcObj,
382 jlong srcOffset,
383 jlong dstAddr,
384 jlong size) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700385 ScopedObjectAccess soa(env);
386 if (size == 0) {
387 return;
388 }
389 // size is nonnegative and fits into size_t
390 if (size < 0 || size != (jlong)(size_t) size) {
391 ThrowIllegalAccessException("wrong number of bytes");
392 }
393 size_t sz = (size_t)size;
394 size_t src_offset = (size_t)srcOffset;
395 ObjPtr<mirror::Object> src = soa.Decode<mirror::Object>(srcObj);
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700396 ObjPtr<mirror::Class> component_type = src->GetClass()->GetComponentType();
Mathieu Chartier0795f232016-09-27 18:43:30 -0700397 if (component_type->IsPrimitiveByte() || component_type->IsPrimitiveBoolean()) {
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700398 copyFromArray(dstAddr, MakeObjPtr(src->AsByteSizedArray()), src_offset, sz);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700399 } else if (component_type->IsPrimitiveShort() || component_type->IsPrimitiveChar()) {
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700400 copyFromArray(dstAddr, MakeObjPtr(src->AsShortSizedArray()), src_offset, sz);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700401 } else if (component_type->IsPrimitiveInt() || component_type->IsPrimitiveFloat()) {
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700402 copyFromArray(dstAddr, MakeObjPtr(src->AsIntArray()), src_offset, sz);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700403 } else if (component_type->IsPrimitiveLong() || component_type->IsPrimitiveDouble()) {
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700404 copyFromArray(dstAddr, MakeObjPtr(src->AsLongArray()), src_offset, sz);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700405 } else {
406 ThrowIllegalAccessException("not a primitive array");
407 }
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100408}
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100409static jboolean Unsafe_getBoolean(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700410 ScopedFastNativeObjectAccess soa(env);
411 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
412 return obj->GetFieldBoolean(MemberOffset(offset));
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100413}
414
415static void Unsafe_putBoolean(JNIEnv* env, jobject, jobject javaObj, jlong offset, jboolean newValue) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700416 ScopedFastNativeObjectAccess soa(env);
417 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
418 // JNI must use non transactional mode (SetField8 is non-transactional).
419 obj->SetFieldBoolean<false>(MemberOffset(offset), newValue);
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100420}
421
422static jbyte Unsafe_getByte(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700423 ScopedFastNativeObjectAccess soa(env);
424 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
425 return obj->GetFieldByte(MemberOffset(offset));
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100426}
427
428static void Unsafe_putByte(JNIEnv* env, jobject, jobject javaObj, jlong offset, jbyte newValue) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700429 ScopedFastNativeObjectAccess soa(env);
430 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
431 // JNI must use non transactional mode.
432 obj->SetFieldByte<false>(MemberOffset(offset), newValue);
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100433}
434
435static jchar Unsafe_getChar(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700436 ScopedFastNativeObjectAccess soa(env);
437 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
438 return obj->GetFieldChar(MemberOffset(offset));
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100439}
440
441static void Unsafe_putChar(JNIEnv* env, jobject, jobject javaObj, jlong offset, jchar newValue) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700442 ScopedFastNativeObjectAccess soa(env);
443 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
444 // JNI must use non transactional mode.
445 obj->SetFieldChar<false>(MemberOffset(offset), newValue);
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100446}
447
448static jshort Unsafe_getShort(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700449 ScopedFastNativeObjectAccess soa(env);
450 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
451 return obj->GetFieldShort(MemberOffset(offset));
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100452}
453
454static void Unsafe_putShort(JNIEnv* env, jobject, jobject javaObj, jlong offset, jshort newValue) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700455 ScopedFastNativeObjectAccess soa(env);
456 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
457 // JNI must use non transactional mode.
458 obj->SetFieldShort<false>(MemberOffset(offset), newValue);
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100459}
460
461static jfloat Unsafe_getFloat(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
462 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700463 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Przemyslaw Szczepaniak5c404222015-08-04 13:19:12 +0100464 union {int32_t val; jfloat converted;} conv;
465 conv.val = obj->GetField32(MemberOffset(offset));
466 return conv.converted;
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100467}
468
469static void Unsafe_putFloat(JNIEnv* env, jobject, jobject javaObj, jlong offset, jfloat newValue) {
470 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700471 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Przemyslaw Szczepaniak5c404222015-08-04 13:19:12 +0100472 union {int32_t converted; jfloat val;} conv;
473 conv.val = newValue;
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100474 // JNI must use non transactional mode.
Przemyslaw Szczepaniak5c404222015-08-04 13:19:12 +0100475 obj->SetField32<false>(MemberOffset(offset), conv.converted);
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100476}
477
478static jdouble Unsafe_getDouble(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
479 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700480 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Przemyslaw Szczepaniak5c404222015-08-04 13:19:12 +0100481 union {int64_t val; jdouble converted;} conv;
482 conv.val = obj->GetField64(MemberOffset(offset));
483 return conv.converted;
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100484}
485
486static void Unsafe_putDouble(JNIEnv* env, jobject, jobject javaObj, jlong offset, jdouble newValue) {
487 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700488 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Przemyslaw Szczepaniak5c404222015-08-04 13:19:12 +0100489 union {int64_t converted; jdouble val;} conv;
490 conv.val = newValue;
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100491 // JNI must use non transactional mode.
Przemyslaw Szczepaniak5c404222015-08-04 13:19:12 +0100492 obj->SetField64<false>(MemberOffset(offset), conv.converted);
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100493}
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700494
Igor Murashkin629afab2016-02-19 14:56:43 -0800495static void Unsafe_loadFence(JNIEnv*, jobject) {
496 std::atomic_thread_fence(std::memory_order_acquire);
497}
498
499static void Unsafe_storeFence(JNIEnv*, jobject) {
500 std::atomic_thread_fence(std::memory_order_release);
501}
502
503static void Unsafe_fullFence(JNIEnv*, jobject) {
504 std::atomic_thread_fence(std::memory_order_seq_cst);
505}
506
Elliott Hughes0512f022012-03-15 22:10:52 -0700507static JNINativeMethod gMethods[] = {
Igor Murashkin3b6f4402017-02-16 16:13:17 -0800508 FAST_NATIVE_METHOD(Unsafe, compareAndSwapInt, "(Ljava/lang/Object;JII)Z"),
509 FAST_NATIVE_METHOD(Unsafe, compareAndSwapLong, "(Ljava/lang/Object;JJJ)Z"),
510 FAST_NATIVE_METHOD(Unsafe, compareAndSwapObject, "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z"),
511 FAST_NATIVE_METHOD(Unsafe, getIntVolatile, "(Ljava/lang/Object;J)I"),
512 FAST_NATIVE_METHOD(Unsafe, putIntVolatile, "(Ljava/lang/Object;JI)V"),
513 FAST_NATIVE_METHOD(Unsafe, getLongVolatile, "(Ljava/lang/Object;J)J"),
514 FAST_NATIVE_METHOD(Unsafe, putLongVolatile, "(Ljava/lang/Object;JJ)V"),
515 FAST_NATIVE_METHOD(Unsafe, getObjectVolatile, "(Ljava/lang/Object;J)Ljava/lang/Object;"),
516 FAST_NATIVE_METHOD(Unsafe, putObjectVolatile, "(Ljava/lang/Object;JLjava/lang/Object;)V"),
517 FAST_NATIVE_METHOD(Unsafe, getInt, "(Ljava/lang/Object;J)I"),
518 FAST_NATIVE_METHOD(Unsafe, putInt, "(Ljava/lang/Object;JI)V"),
519 FAST_NATIVE_METHOD(Unsafe, putOrderedInt, "(Ljava/lang/Object;JI)V"),
520 FAST_NATIVE_METHOD(Unsafe, getLong, "(Ljava/lang/Object;J)J"),
521 FAST_NATIVE_METHOD(Unsafe, putLong, "(Ljava/lang/Object;JJ)V"),
522 FAST_NATIVE_METHOD(Unsafe, putOrderedLong, "(Ljava/lang/Object;JJ)V"),
523 FAST_NATIVE_METHOD(Unsafe, getObject, "(Ljava/lang/Object;J)Ljava/lang/Object;"),
524 FAST_NATIVE_METHOD(Unsafe, putObject, "(Ljava/lang/Object;JLjava/lang/Object;)V"),
525 FAST_NATIVE_METHOD(Unsafe, putOrderedObject, "(Ljava/lang/Object;JLjava/lang/Object;)V"),
526 FAST_NATIVE_METHOD(Unsafe, getArrayBaseOffsetForComponentType, "(Ljava/lang/Class;)I"),
527 FAST_NATIVE_METHOD(Unsafe, getArrayIndexScaleForComponentType, "(Ljava/lang/Class;)I"),
528 FAST_NATIVE_METHOD(Unsafe, addressSize, "()I"),
529 FAST_NATIVE_METHOD(Unsafe, pageSize, "()I"),
530 FAST_NATIVE_METHOD(Unsafe, allocateMemory, "(J)J"),
531 FAST_NATIVE_METHOD(Unsafe, freeMemory, "(J)V"),
532 FAST_NATIVE_METHOD(Unsafe, setMemory, "(JJB)V"),
533 FAST_NATIVE_METHOD(Unsafe, copyMemory, "(JJJ)V"),
534 FAST_NATIVE_METHOD(Unsafe, copyMemoryToPrimitiveArray, "(JLjava/lang/Object;JJ)V"),
535 FAST_NATIVE_METHOD(Unsafe, copyMemoryFromPrimitiveArray, "(Ljava/lang/Object;JJJ)V"),
536 FAST_NATIVE_METHOD(Unsafe, getBoolean, "(Ljava/lang/Object;J)Z"),
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000537
Igor Murashkin3b6f4402017-02-16 16:13:17 -0800538 FAST_NATIVE_METHOD(Unsafe, getByte, "(Ljava/lang/Object;J)B"),
539 FAST_NATIVE_METHOD(Unsafe, getChar, "(Ljava/lang/Object;J)C"),
540 FAST_NATIVE_METHOD(Unsafe, getShort, "(Ljava/lang/Object;J)S"),
541 FAST_NATIVE_METHOD(Unsafe, getFloat, "(Ljava/lang/Object;J)F"),
542 FAST_NATIVE_METHOD(Unsafe, getDouble, "(Ljava/lang/Object;J)D"),
543 FAST_NATIVE_METHOD(Unsafe, putBoolean, "(Ljava/lang/Object;JZ)V"),
544 FAST_NATIVE_METHOD(Unsafe, putByte, "(Ljava/lang/Object;JB)V"),
545 FAST_NATIVE_METHOD(Unsafe, putChar, "(Ljava/lang/Object;JC)V"),
546 FAST_NATIVE_METHOD(Unsafe, putShort, "(Ljava/lang/Object;JS)V"),
547 FAST_NATIVE_METHOD(Unsafe, putFloat, "(Ljava/lang/Object;JF)V"),
548 FAST_NATIVE_METHOD(Unsafe, putDouble, "(Ljava/lang/Object;JD)V"),
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000549
550 // Each of the getFoo variants are overloaded with a call that operates
551 // directively on a native pointer.
Igor Murashkin3b6f4402017-02-16 16:13:17 -0800552 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, getByte, "(J)B", getByteJ),
553 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, getChar, "(J)C", getCharJ),
554 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, getShort, "(J)S", getShortJ),
555 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, getInt, "(J)I", getIntJ),
556 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, getLong, "(J)J", getLongJ),
557 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, getFloat, "(J)F", getFloatJ),
558 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, getDouble, "(J)D", getDoubleJ),
559 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, putByte, "(JB)V", putByteJB),
560 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, putChar, "(JC)V", putCharJC),
561 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, putShort, "(JS)V", putShortJS),
562 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, putInt, "(JI)V", putIntJI),
563 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, putLong, "(JJ)V", putLongJJ),
564 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, putFloat, "(JF)V", putFloatJF),
565 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, putDouble, "(JD)V", putDoubleJD),
Igor Murashkin629afab2016-02-19 14:56:43 -0800566
567 // CAS
Igor Murashkin3b6f4402017-02-16 16:13:17 -0800568 FAST_NATIVE_METHOD(Unsafe, loadFence, "()V"),
569 FAST_NATIVE_METHOD(Unsafe, storeFence, "()V"),
570 FAST_NATIVE_METHOD(Unsafe, fullFence, "()V"),
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700571};
572
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700573void register_sun_misc_Unsafe(JNIEnv* env) {
Elliott Hugheseac76672012-05-24 21:56:51 -0700574 REGISTER_NATIVE_METHODS("sun/misc/Unsafe");
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700575}
576
577} // namespace art