blob: 0f474d3c9d35cb1da84fd2006a89fb898c40e473 [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));
Hans Boehmcc55e1d2017-07-27 15:28:07 -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 }
Hans Boehmd8434432014-07-11 09:56:07 -070083 bool success = obj->CasFieldStrongSequentiallyConsistentObject<false>(MemberOffset(offset),
Mathieu Chartier1a5337f2016-10-13 13:48:23 -070084 expectedValue,
85 newValue);
Ian Rogersef7d42f2014-01-06 12:55:46 -080086 return success ? JNI_TRUE : JNI_FALSE;
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070087}
88
Elliott Hughes0512f022012-03-15 22:10:52 -070089static jint Unsafe_getInt(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070090 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -070091 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070092 return obj->GetField32(MemberOffset(offset));
Ian Rogers5d76c432011-10-31 21:42:49 -070093}
94
Elliott Hughes0512f022012-03-15 22:10:52 -070095static jint Unsafe_getIntVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070096 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -070097 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070098 return obj->GetField32Volatile(MemberOffset(offset));
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070099}
100
Elliott Hughes0512f022012-03-15 22:10:52 -0700101static void Unsafe_putInt(JNIEnv* env, jobject, jobject javaObj, jlong offset, jint newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700102 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700103 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100104 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700105 obj->SetField32<false>(MemberOffset(offset), newValue);
Ian Rogers5d76c432011-10-31 21:42:49 -0700106}
107
Ian Rogersef7d42f2014-01-06 12:55:46 -0800108static void Unsafe_putIntVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset,
109 jint newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700110 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700111 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100112 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700113 obj->SetField32Volatile<false>(MemberOffset(offset), newValue);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700114}
115
Ian Rogersef7d42f2014-01-06 12:55:46 -0800116static void Unsafe_putOrderedInt(JNIEnv* env, jobject, jobject javaObj, jlong offset,
117 jint newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700118 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700119 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Hans Boehmcc55e1d2017-07-27 15:28:07 -0700120 // TODO: A release store is likely to be faster on future processors.
Orion Hodson27b96762018-03-13 16:06:57 +0000121 std::atomic_thread_fence(std::memory_order_release);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100122 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700123 obj->SetField32<false>(MemberOffset(offset), newValue);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700124}
125
Elliott Hughes0512f022012-03-15 22:10:52 -0700126static jlong Unsafe_getLong(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700127 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700128 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700129 return obj->GetField64(MemberOffset(offset));
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700130}
131
Elliott Hughes0512f022012-03-15 22:10:52 -0700132static jlong Unsafe_getLongVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700133 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700134 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700135 return obj->GetField64Volatile(MemberOffset(offset));
Ian Rogers5d76c432011-10-31 21:42:49 -0700136}
137
Elliott Hughes0512f022012-03-15 22:10:52 -0700138static void Unsafe_putLong(JNIEnv* env, jobject, jobject javaObj, jlong offset, jlong newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700139 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700140 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100141 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700142 obj->SetField64<false>(MemberOffset(offset), newValue);
Ian Rogers5d76c432011-10-31 21:42:49 -0700143}
144
Ian Rogersef7d42f2014-01-06 12:55:46 -0800145static void Unsafe_putLongVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset,
146 jlong newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700147 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700148 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100149 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700150 obj->SetField64Volatile<false>(MemberOffset(offset), newValue);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700151}
152
Ian Rogersef7d42f2014-01-06 12:55:46 -0800153static void Unsafe_putOrderedLong(JNIEnv* env, jobject, jobject javaObj, jlong offset,
154 jlong newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700155 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700156 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Orion Hodson27b96762018-03-13 16:06:57 +0000157 std::atomic_thread_fence(std::memory_order_release);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100158 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700159 obj->SetField64<false>(MemberOffset(offset), newValue);
Ian Rogers5d76c432011-10-31 21:42:49 -0700160}
161
Elliott Hughes0512f022012-03-15 22:10:52 -0700162static jobject Unsafe_getObjectVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700163 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700164 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
165 ObjPtr<mirror::Object> value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700166 return soa.AddLocalReference<jobject>(value);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700167}
168
Elliott Hughes0512f022012-03-15 22:10:52 -0700169static jobject Unsafe_getObject(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700170 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700171 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
172 ObjPtr<mirror::Object> value = obj->GetFieldObject<mirror::Object>(MemberOffset(offset));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700173 return soa.AddLocalReference<jobject>(value);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700174}
175
Ian Rogersef7d42f2014-01-06 12:55:46 -0800176static void Unsafe_putObject(JNIEnv* env, jobject, jobject javaObj, jlong offset,
177 jobject javaNewValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700178 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700179 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
180 ObjPtr<mirror::Object> newValue = soa.Decode<mirror::Object>(javaNewValue);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100181 // JNI must use non transactional mode.
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700182 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700183}
184
Ian Rogersef7d42f2014-01-06 12:55:46 -0800185static void Unsafe_putObjectVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset,
186 jobject javaNewValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700187 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700188 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
189 ObjPtr<mirror::Object> newValue = soa.Decode<mirror::Object>(javaNewValue);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100190 // JNI must use non transactional mode.
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700191 obj->SetFieldObjectVolatile<false>(MemberOffset(offset), newValue);
Ian Rogers5d76c432011-10-31 21:42:49 -0700192}
193
Ian Rogersef7d42f2014-01-06 12:55:46 -0800194static void Unsafe_putOrderedObject(JNIEnv* env, jobject, jobject javaObj, jlong offset,
195 jobject javaNewValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700196 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700197 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
198 ObjPtr<mirror::Object> newValue = soa.Decode<mirror::Object>(javaNewValue);
Orion Hodson27b96762018-03-13 16:06:57 +0000199 std::atomic_thread_fence(std::memory_order_release);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100200 // JNI must use non transactional mode.
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700201 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700202}
203
Igor Murashkin06537f72018-02-22 15:03:05 -0800204static jint Unsafe_getArrayBaseOffsetForComponentType(JNIEnv* env, jclass, jclass component_class) {
Hiroshi Yamauchi4d2efce2014-02-10 16:19:09 -0800205 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700206 ObjPtr<mirror::Class> component = soa.Decode<mirror::Class>(component_class);
Hiroshi Yamauchi4d2efce2014-02-10 16:19:09 -0800207 Primitive::Type primitive_type = component->GetPrimitiveType();
208 return mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value();
209}
210
Igor Murashkin06537f72018-02-22 15:03:05 -0800211static jint Unsafe_getArrayIndexScaleForComponentType(JNIEnv* env, jclass, jclass component_class) {
Hiroshi Yamauchi4d2efce2014-02-10 16:19:09 -0800212 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700213 ObjPtr<mirror::Class> component = soa.Decode<mirror::Class>(component_class);
Hiroshi Yamauchi4d2efce2014-02-10 16:19:09 -0800214 Primitive::Type primitive_type = component->GetPrimitiveType();
215 return Primitive::ComponentSize(primitive_type);
216}
217
Przemyslaw Szczepaniak6c0ea272015-09-23 08:48:00 +0100218static jint Unsafe_addressSize(JNIEnv* env ATTRIBUTE_UNUSED, jobject ob ATTRIBUTE_UNUSED) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100219 return sizeof(void*);
220}
221
Przemyslaw Szczepaniak6c0ea272015-09-23 08:48:00 +0100222static jint Unsafe_pageSize(JNIEnv* env ATTRIBUTE_UNUSED, jobject ob ATTRIBUTE_UNUSED) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100223 return sysconf(_SC_PAGESIZE);
224}
225
226static jlong Unsafe_allocateMemory(JNIEnv* env, jobject, jlong bytes) {
227 ScopedFastNativeObjectAccess soa(env);
228 // bytes is nonnegative and fits into size_t
229 if (bytes < 0 || bytes != (jlong)(size_t) bytes) {
Narayan Kamathd1ef4362015-11-12 11:49:06 +0000230 ThrowIllegalAccessException("wrong number of bytes");
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100231 return 0;
232 }
233 void* mem = malloc(bytes);
234 if (mem == nullptr) {
235 soa.Self()->ThrowOutOfMemoryError("native alloc");
236 return 0;
237 }
238 return (uintptr_t) mem;
239}
240
Przemyslaw Szczepaniak6c0ea272015-09-23 08:48:00 +0100241static void Unsafe_freeMemory(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) {
Narayan Kamatha0cf5a62015-09-07 11:41:37 +0100242 free(reinterpret_cast<void*>(static_cast<uintptr_t>(address)));
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100243}
244
Przemyslaw Szczepaniak6c0ea272015-09-23 08:48:00 +0100245static void Unsafe_setMemory(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jlong bytes, jbyte value) {
Narayan Kamatha0cf5a62015-09-07 11:41:37 +0100246 memset(reinterpret_cast<void*>(static_cast<uintptr_t>(address)), value, bytes);
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100247}
248
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000249static jbyte Unsafe_getByteJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100250 return *reinterpret_cast<jbyte*>(address);
251}
252
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000253static void Unsafe_putByteJB(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jbyte value) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100254 *reinterpret_cast<jbyte*>(address) = value;
255}
256
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000257static jshort Unsafe_getShortJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100258 return *reinterpret_cast<jshort*>(address);
259}
260
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000261static void Unsafe_putShortJS(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jshort value) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100262 *reinterpret_cast<jshort*>(address) = value;
263}
264
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000265static jchar Unsafe_getCharJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100266 return *reinterpret_cast<jchar*>(address);
267}
268
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000269static void Unsafe_putCharJC(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jchar value) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100270 *reinterpret_cast<jchar*>(address) = value;
271}
272
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000273static jint Unsafe_getIntJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100274 return *reinterpret_cast<jint*>(address);
275}
276
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000277static void Unsafe_putIntJI(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jint value) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100278 *reinterpret_cast<jint*>(address) = value;
279}
280
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000281static jlong Unsafe_getLongJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100282 return *reinterpret_cast<jlong*>(address);
283}
284
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000285static void Unsafe_putLongJJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jlong value) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100286 *reinterpret_cast<jlong*>(address) = value;
287}
288
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000289static jfloat Unsafe_getFloatJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100290 return *reinterpret_cast<jfloat*>(address);
291}
292
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000293static void Unsafe_putFloatJF(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jfloat value) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100294 *reinterpret_cast<jfloat*>(address) = value;
295}
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000296static jdouble Unsafe_getDoubleJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100297 return *reinterpret_cast<jdouble*>(address);
298}
299
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000300static void Unsafe_putDoubleJD(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jdouble value) {
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100301 *reinterpret_cast<jdouble*>(address) = value;
302}
303
Przemyslaw Szczepaniak6c0ea272015-09-23 08:48:00 +0100304static void Unsafe_copyMemory(JNIEnv *env, jobject unsafe ATTRIBUTE_UNUSED, jlong src,
305 jlong dst, jlong size) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700306 if (size == 0) {
307 return;
308 }
309 // size is nonnegative and fits into size_t
310 if (size < 0 || size != (jlong)(size_t) size) {
311 ScopedFastNativeObjectAccess soa(env);
312 ThrowIllegalAccessException("wrong number of bytes");
313 }
314 size_t sz = (size_t)size;
315 memcpy(reinterpret_cast<void *>(dst), reinterpret_cast<void *>(src), sz);
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100316}
317
318template<typename T>
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700319static void copyToArray(jlong srcAddr,
320 ObjPtr<mirror::PrimitiveArray<T>> array,
Przemyslaw Szczepaniak903ac272015-07-23 09:30:35 +0100321 size_t array_offset,
322 size_t size)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700323 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700324 const T* src = reinterpret_cast<T*>(srcAddr);
325 size_t sz = size / sizeof(T);
326 size_t of = array_offset / sizeof(T);
327 for (size_t i = 0; i < sz; ++i) {
328 array->Set(i + of, *(src + i));
329 }
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100330}
331
332template<typename T>
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700333static void copyFromArray(jlong dstAddr,
334 ObjPtr<mirror::PrimitiveArray<T>> array,
Przemyslaw Szczepaniak903ac272015-07-23 09:30:35 +0100335 size_t array_offset,
336 size_t size)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700337 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700338 T* dst = reinterpret_cast<T*>(dstAddr);
339 size_t sz = size / sizeof(T);
340 size_t of = array_offset / sizeof(T);
341 for (size_t i = 0; i < sz; ++i) {
342 *(dst + i) = array->Get(i + of);
343 }
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100344}
345
346static void Unsafe_copyMemoryToPrimitiveArray(JNIEnv *env,
Przemyslaw Szczepaniak6c0ea272015-09-23 08:48:00 +0100347 jobject unsafe ATTRIBUTE_UNUSED,
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100348 jlong srcAddr,
349 jobject dstObj,
350 jlong dstOffset,
351 jlong size) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700352 ScopedObjectAccess soa(env);
353 if (size == 0) {
354 return;
355 }
356 // size is nonnegative and fits into size_t
357 if (size < 0 || size != (jlong)(size_t) size) {
358 ThrowIllegalAccessException("wrong number of bytes");
359 }
360 size_t sz = (size_t)size;
361 size_t dst_offset = (size_t)dstOffset;
362 ObjPtr<mirror::Object> dst = soa.Decode<mirror::Object>(dstObj);
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700363 ObjPtr<mirror::Class> component_type = dst->GetClass()->GetComponentType();
Mathieu Chartier0795f232016-09-27 18:43:30 -0700364 if (component_type->IsPrimitiveByte() || component_type->IsPrimitiveBoolean()) {
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700365 copyToArray(srcAddr, MakeObjPtr(dst->AsByteSizedArray()), dst_offset, sz);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700366 } else if (component_type->IsPrimitiveShort() || component_type->IsPrimitiveChar()) {
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700367 copyToArray(srcAddr, MakeObjPtr(dst->AsShortSizedArray()), dst_offset, sz);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700368 } else if (component_type->IsPrimitiveInt() || component_type->IsPrimitiveFloat()) {
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700369 copyToArray(srcAddr, MakeObjPtr(dst->AsIntArray()), dst_offset, sz);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700370 } else if (component_type->IsPrimitiveLong() || component_type->IsPrimitiveDouble()) {
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700371 copyToArray(srcAddr, MakeObjPtr(dst->AsLongArray()), dst_offset, sz);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700372 } else {
373 ThrowIllegalAccessException("not a primitive array");
374 }
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100375}
376
377static void Unsafe_copyMemoryFromPrimitiveArray(JNIEnv *env,
Przemyslaw Szczepaniak6c0ea272015-09-23 08:48:00 +0100378 jobject unsafe ATTRIBUTE_UNUSED,
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100379 jobject srcObj,
380 jlong srcOffset,
381 jlong dstAddr,
382 jlong size) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700383 ScopedObjectAccess soa(env);
384 if (size == 0) {
385 return;
386 }
387 // size is nonnegative and fits into size_t
388 if (size < 0 || size != (jlong)(size_t) size) {
389 ThrowIllegalAccessException("wrong number of bytes");
390 }
391 size_t sz = (size_t)size;
392 size_t src_offset = (size_t)srcOffset;
393 ObjPtr<mirror::Object> src = soa.Decode<mirror::Object>(srcObj);
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700394 ObjPtr<mirror::Class> component_type = src->GetClass()->GetComponentType();
Mathieu Chartier0795f232016-09-27 18:43:30 -0700395 if (component_type->IsPrimitiveByte() || component_type->IsPrimitiveBoolean()) {
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700396 copyFromArray(dstAddr, MakeObjPtr(src->AsByteSizedArray()), src_offset, sz);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700397 } else if (component_type->IsPrimitiveShort() || component_type->IsPrimitiveChar()) {
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700398 copyFromArray(dstAddr, MakeObjPtr(src->AsShortSizedArray()), src_offset, sz);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700399 } else if (component_type->IsPrimitiveInt() || component_type->IsPrimitiveFloat()) {
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700400 copyFromArray(dstAddr, MakeObjPtr(src->AsIntArray()), src_offset, sz);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700401 } else if (component_type->IsPrimitiveLong() || component_type->IsPrimitiveDouble()) {
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700402 copyFromArray(dstAddr, MakeObjPtr(src->AsLongArray()), src_offset, sz);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700403 } else {
404 ThrowIllegalAccessException("not a primitive array");
405 }
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100406}
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100407static jboolean Unsafe_getBoolean(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700408 ScopedFastNativeObjectAccess soa(env);
409 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
410 return obj->GetFieldBoolean(MemberOffset(offset));
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100411}
412
413static void Unsafe_putBoolean(JNIEnv* env, jobject, jobject javaObj, jlong offset, jboolean newValue) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700414 ScopedFastNativeObjectAccess soa(env);
415 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
416 // JNI must use non transactional mode (SetField8 is non-transactional).
417 obj->SetFieldBoolean<false>(MemberOffset(offset), newValue);
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100418}
419
420static jbyte Unsafe_getByte(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700421 ScopedFastNativeObjectAccess soa(env);
422 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
423 return obj->GetFieldByte(MemberOffset(offset));
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100424}
425
426static void Unsafe_putByte(JNIEnv* env, jobject, jobject javaObj, jlong offset, jbyte newValue) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700427 ScopedFastNativeObjectAccess soa(env);
428 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
429 // JNI must use non transactional mode.
430 obj->SetFieldByte<false>(MemberOffset(offset), newValue);
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100431}
432
433static jchar Unsafe_getChar(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700434 ScopedFastNativeObjectAccess soa(env);
435 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
436 return obj->GetFieldChar(MemberOffset(offset));
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100437}
438
439static void Unsafe_putChar(JNIEnv* env, jobject, jobject javaObj, jlong offset, jchar newValue) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700440 ScopedFastNativeObjectAccess soa(env);
441 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
442 // JNI must use non transactional mode.
443 obj->SetFieldChar<false>(MemberOffset(offset), newValue);
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100444}
445
446static jshort Unsafe_getShort(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700447 ScopedFastNativeObjectAccess soa(env);
448 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
449 return obj->GetFieldShort(MemberOffset(offset));
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100450}
451
452static void Unsafe_putShort(JNIEnv* env, jobject, jobject javaObj, jlong offset, jshort newValue) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700453 ScopedFastNativeObjectAccess soa(env);
454 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
455 // JNI must use non transactional mode.
456 obj->SetFieldShort<false>(MemberOffset(offset), newValue);
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100457}
458
459static jfloat Unsafe_getFloat(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
460 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700461 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Przemyslaw Szczepaniak5c404222015-08-04 13:19:12 +0100462 union {int32_t val; jfloat converted;} conv;
463 conv.val = obj->GetField32(MemberOffset(offset));
464 return conv.converted;
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100465}
466
467static void Unsafe_putFloat(JNIEnv* env, jobject, jobject javaObj, jlong offset, jfloat newValue) {
468 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700469 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Przemyslaw Szczepaniak5c404222015-08-04 13:19:12 +0100470 union {int32_t converted; jfloat val;} conv;
471 conv.val = newValue;
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100472 // JNI must use non transactional mode.
Przemyslaw Szczepaniak5c404222015-08-04 13:19:12 +0100473 obj->SetField32<false>(MemberOffset(offset), conv.converted);
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100474}
475
476static jdouble Unsafe_getDouble(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
477 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700478 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Przemyslaw Szczepaniak5c404222015-08-04 13:19:12 +0100479 union {int64_t val; jdouble converted;} conv;
480 conv.val = obj->GetField64(MemberOffset(offset));
481 return conv.converted;
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100482}
483
484static void Unsafe_putDouble(JNIEnv* env, jobject, jobject javaObj, jlong offset, jdouble newValue) {
485 ScopedFastNativeObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700486 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj);
Przemyslaw Szczepaniak5c404222015-08-04 13:19:12 +0100487 union {int64_t converted; jdouble val;} conv;
488 conv.val = newValue;
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100489 // JNI must use non transactional mode.
Przemyslaw Szczepaniak5c404222015-08-04 13:19:12 +0100490 obj->SetField64<false>(MemberOffset(offset), conv.converted);
Piotr Jastrzebski8e73ea42015-05-07 09:41:00 +0100491}
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700492
Igor Murashkin629afab2016-02-19 14:56:43 -0800493static void Unsafe_loadFence(JNIEnv*, jobject) {
494 std::atomic_thread_fence(std::memory_order_acquire);
495}
496
497static void Unsafe_storeFence(JNIEnv*, jobject) {
498 std::atomic_thread_fence(std::memory_order_release);
499}
500
501static void Unsafe_fullFence(JNIEnv*, jobject) {
502 std::atomic_thread_fence(std::memory_order_seq_cst);
503}
504
Elliott Hughes0512f022012-03-15 22:10:52 -0700505static JNINativeMethod gMethods[] = {
Igor Murashkin3b6f4402017-02-16 16:13:17 -0800506 FAST_NATIVE_METHOD(Unsafe, compareAndSwapInt, "(Ljava/lang/Object;JII)Z"),
507 FAST_NATIVE_METHOD(Unsafe, compareAndSwapLong, "(Ljava/lang/Object;JJJ)Z"),
508 FAST_NATIVE_METHOD(Unsafe, compareAndSwapObject, "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z"),
509 FAST_NATIVE_METHOD(Unsafe, getIntVolatile, "(Ljava/lang/Object;J)I"),
510 FAST_NATIVE_METHOD(Unsafe, putIntVolatile, "(Ljava/lang/Object;JI)V"),
511 FAST_NATIVE_METHOD(Unsafe, getLongVolatile, "(Ljava/lang/Object;J)J"),
512 FAST_NATIVE_METHOD(Unsafe, putLongVolatile, "(Ljava/lang/Object;JJ)V"),
513 FAST_NATIVE_METHOD(Unsafe, getObjectVolatile, "(Ljava/lang/Object;J)Ljava/lang/Object;"),
514 FAST_NATIVE_METHOD(Unsafe, putObjectVolatile, "(Ljava/lang/Object;JLjava/lang/Object;)V"),
515 FAST_NATIVE_METHOD(Unsafe, getInt, "(Ljava/lang/Object;J)I"),
516 FAST_NATIVE_METHOD(Unsafe, putInt, "(Ljava/lang/Object;JI)V"),
517 FAST_NATIVE_METHOD(Unsafe, putOrderedInt, "(Ljava/lang/Object;JI)V"),
518 FAST_NATIVE_METHOD(Unsafe, getLong, "(Ljava/lang/Object;J)J"),
519 FAST_NATIVE_METHOD(Unsafe, putLong, "(Ljava/lang/Object;JJ)V"),
520 FAST_NATIVE_METHOD(Unsafe, putOrderedLong, "(Ljava/lang/Object;JJ)V"),
521 FAST_NATIVE_METHOD(Unsafe, getObject, "(Ljava/lang/Object;J)Ljava/lang/Object;"),
522 FAST_NATIVE_METHOD(Unsafe, putObject, "(Ljava/lang/Object;JLjava/lang/Object;)V"),
523 FAST_NATIVE_METHOD(Unsafe, putOrderedObject, "(Ljava/lang/Object;JLjava/lang/Object;)V"),
524 FAST_NATIVE_METHOD(Unsafe, getArrayBaseOffsetForComponentType, "(Ljava/lang/Class;)I"),
525 FAST_NATIVE_METHOD(Unsafe, getArrayIndexScaleForComponentType, "(Ljava/lang/Class;)I"),
526 FAST_NATIVE_METHOD(Unsafe, addressSize, "()I"),
527 FAST_NATIVE_METHOD(Unsafe, pageSize, "()I"),
528 FAST_NATIVE_METHOD(Unsafe, allocateMemory, "(J)J"),
529 FAST_NATIVE_METHOD(Unsafe, freeMemory, "(J)V"),
530 FAST_NATIVE_METHOD(Unsafe, setMemory, "(JJB)V"),
531 FAST_NATIVE_METHOD(Unsafe, copyMemory, "(JJJ)V"),
532 FAST_NATIVE_METHOD(Unsafe, copyMemoryToPrimitiveArray, "(JLjava/lang/Object;JJ)V"),
533 FAST_NATIVE_METHOD(Unsafe, copyMemoryFromPrimitiveArray, "(Ljava/lang/Object;JJJ)V"),
534 FAST_NATIVE_METHOD(Unsafe, getBoolean, "(Ljava/lang/Object;J)Z"),
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000535
Igor Murashkin3b6f4402017-02-16 16:13:17 -0800536 FAST_NATIVE_METHOD(Unsafe, getByte, "(Ljava/lang/Object;J)B"),
537 FAST_NATIVE_METHOD(Unsafe, getChar, "(Ljava/lang/Object;J)C"),
538 FAST_NATIVE_METHOD(Unsafe, getShort, "(Ljava/lang/Object;J)S"),
539 FAST_NATIVE_METHOD(Unsafe, getFloat, "(Ljava/lang/Object;J)F"),
540 FAST_NATIVE_METHOD(Unsafe, getDouble, "(Ljava/lang/Object;J)D"),
541 FAST_NATIVE_METHOD(Unsafe, putBoolean, "(Ljava/lang/Object;JZ)V"),
542 FAST_NATIVE_METHOD(Unsafe, putByte, "(Ljava/lang/Object;JB)V"),
543 FAST_NATIVE_METHOD(Unsafe, putChar, "(Ljava/lang/Object;JC)V"),
544 FAST_NATIVE_METHOD(Unsafe, putShort, "(Ljava/lang/Object;JS)V"),
545 FAST_NATIVE_METHOD(Unsafe, putFloat, "(Ljava/lang/Object;JF)V"),
546 FAST_NATIVE_METHOD(Unsafe, putDouble, "(Ljava/lang/Object;JD)V"),
Narayan Kamath0dd8c392016-02-01 13:22:18 +0000547
548 // Each of the getFoo variants are overloaded with a call that operates
549 // directively on a native pointer.
Igor Murashkin3b6f4402017-02-16 16:13:17 -0800550 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, getByte, "(J)B", getByteJ),
551 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, getChar, "(J)C", getCharJ),
552 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, getShort, "(J)S", getShortJ),
553 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, getInt, "(J)I", getIntJ),
554 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, getLong, "(J)J", getLongJ),
555 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, getFloat, "(J)F", getFloatJ),
556 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, getDouble, "(J)D", getDoubleJ),
557 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, putByte, "(JB)V", putByteJB),
558 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, putChar, "(JC)V", putCharJC),
559 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, putShort, "(JS)V", putShortJS),
560 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, putInt, "(JI)V", putIntJI),
561 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, putLong, "(JJ)V", putLongJJ),
562 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, putFloat, "(JF)V", putFloatJF),
563 OVERLOADED_FAST_NATIVE_METHOD(Unsafe, putDouble, "(JD)V", putDoubleJD),
Igor Murashkin629afab2016-02-19 14:56:43 -0800564
565 // CAS
Igor Murashkin3b6f4402017-02-16 16:13:17 -0800566 FAST_NATIVE_METHOD(Unsafe, loadFence, "()V"),
567 FAST_NATIVE_METHOD(Unsafe, storeFence, "()V"),
568 FAST_NATIVE_METHOD(Unsafe, fullFence, "()V"),
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700569};
570
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700571void register_sun_misc_Unsafe(JNIEnv* env) {
Elliott Hugheseac76672012-05-24 21:56:51 -0700572 REGISTER_NATIVE_METHODS("sun/misc/Unsafe");
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700573}
574
575} // namespace art