blob: d613f73a8a8d3bdcc3432b1fd398bc27860a5552 [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
Ian Rogers1d54e732013-05-02 21:10:01 -070017#include "gc/accounting/card_table-inl.h"
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070018#include "jni_internal.h"
Hiroshi Yamauchi4d2efce2014-02-10 16:19:09 -080019#include "mirror/array.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080020#include "mirror/object.h"
21#include "mirror/object-inl.h"
Ian Rogers1eb512d2013-10-18 15:42:20 -070022#include "scoped_fast_native_object_access.h"
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070023
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070024namespace art {
25
Ian Rogersef7d42f2014-01-06 12:55:46 -080026static jboolean Unsafe_compareAndSwapInt(JNIEnv* env, jobject, jobject javaObj, jlong offset,
27 jint expectedValue, jint newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070028 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080029 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010030 // JNI must use non transactional mode.
Hans Boehmd8434432014-07-11 09:56:07 -070031 bool success = obj->CasFieldStrongSequentiallyConsistent32<false>(MemberOffset(offset),
32 expectedValue, newValue);
Ian Rogers9adbff52013-01-23 18:19:03 -080033 return success ? JNI_TRUE : JNI_FALSE;
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070034}
35
Ian Rogersef7d42f2014-01-06 12:55:46 -080036static jboolean Unsafe_compareAndSwapLong(JNIEnv* env, jobject, jobject javaObj, jlong offset,
37 jlong expectedValue, jlong newValue) {
38 ScopedFastNativeObjectAccess soa(env);
39 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010040 // JNI must use non transactional mode.
Hans Boehmd8434432014-07-11 09:56:07 -070041 bool success = obj->CasFieldStrongSequentiallyConsistent64<false>(MemberOffset(offset),
42 expectedValue, newValue);
Ian Rogersef7d42f2014-01-06 12:55:46 -080043 return success ? JNI_TRUE : JNI_FALSE;
44}
45
46static jboolean Unsafe_compareAndSwapObject(JNIEnv* env, jobject, jobject javaObj, jlong offset,
47 jobject javaExpectedValue, jobject javaNewValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070048 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080049 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
50 mirror::Object* expectedValue = soa.Decode<mirror::Object*>(javaExpectedValue);
51 mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010052 // JNI must use non transactional mode.
Hans Boehmd8434432014-07-11 09:56:07 -070053 bool success = obj->CasFieldStrongSequentiallyConsistentObject<false>(MemberOffset(offset),
54 expectedValue, newValue);
Ian Rogersef7d42f2014-01-06 12:55:46 -080055 return success ? JNI_TRUE : JNI_FALSE;
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070056}
57
Elliott Hughes0512f022012-03-15 22:10:52 -070058static jint Unsafe_getInt(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070059 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080060 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070061 return obj->GetField32(MemberOffset(offset));
Ian Rogers5d76c432011-10-31 21:42:49 -070062}
63
Elliott Hughes0512f022012-03-15 22:10:52 -070064static jint Unsafe_getIntVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070065 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080066 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070067 return obj->GetField32Volatile(MemberOffset(offset));
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070068}
69
Elliott Hughes0512f022012-03-15 22:10:52 -070070static void Unsafe_putInt(JNIEnv* env, jobject, jobject javaObj, jlong offset, jint newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070071 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080072 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010073 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070074 obj->SetField32<false>(MemberOffset(offset), newValue);
Ian Rogers5d76c432011-10-31 21:42:49 -070075}
76
Ian Rogersef7d42f2014-01-06 12:55:46 -080077static void Unsafe_putIntVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset,
78 jint newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070079 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080080 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010081 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070082 obj->SetField32Volatile<false>(MemberOffset(offset), newValue);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070083}
84
Ian Rogersef7d42f2014-01-06 12:55:46 -080085static void Unsafe_putOrderedInt(JNIEnv* env, jobject, jobject javaObj, jlong offset,
86 jint newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070087 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080088 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Hans Boehm30359612014-05-21 17:46:23 -070089 QuasiAtomic::ThreadFenceRelease();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010090 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070091 obj->SetField32<false>(MemberOffset(offset), newValue);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070092}
93
Elliott Hughes0512f022012-03-15 22:10:52 -070094static jlong Unsafe_getLong(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070095 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080096 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070097 return obj->GetField64(MemberOffset(offset));
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070098}
99
Elliott Hughes0512f022012-03-15 22:10:52 -0700100static jlong Unsafe_getLongVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700101 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800102 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700103 return obj->GetField64Volatile(MemberOffset(offset));
Ian Rogers5d76c432011-10-31 21:42:49 -0700104}
105
Elliott Hughes0512f022012-03-15 22:10:52 -0700106static void Unsafe_putLong(JNIEnv* env, jobject, jobject javaObj, jlong offset, jlong newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700107 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800108 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100109 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700110 obj->SetField64<false>(MemberOffset(offset), newValue);
Ian Rogers5d76c432011-10-31 21:42:49 -0700111}
112
Ian Rogersef7d42f2014-01-06 12:55:46 -0800113static void Unsafe_putLongVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset,
114 jlong newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700115 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800116 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100117 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700118 obj->SetField64Volatile<false>(MemberOffset(offset), newValue);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700119}
120
Ian Rogersef7d42f2014-01-06 12:55:46 -0800121static void Unsafe_putOrderedLong(JNIEnv* env, jobject, jobject javaObj, jlong offset,
122 jlong newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700123 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800124 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Hans Boehm30359612014-05-21 17:46:23 -0700125 QuasiAtomic::ThreadFenceRelease();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100126 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700127 obj->SetField64<false>(MemberOffset(offset), newValue);
Ian Rogers5d76c432011-10-31 21:42:49 -0700128}
129
Elliott Hughes0512f022012-03-15 22:10:52 -0700130static jobject Unsafe_getObjectVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700131 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800132 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700133 mirror::Object* value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700134 return soa.AddLocalReference<jobject>(value);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700135}
136
Elliott Hughes0512f022012-03-15 22:10:52 -0700137static jobject Unsafe_getObject(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700138 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800139 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700140 mirror::Object* value = obj->GetFieldObject<mirror::Object>(MemberOffset(offset));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700141 return soa.AddLocalReference<jobject>(value);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700142}
143
Ian Rogersef7d42f2014-01-06 12:55:46 -0800144static void Unsafe_putObject(JNIEnv* env, jobject, jobject javaObj, jlong offset,
145 jobject javaNewValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700146 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800147 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
148 mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100149 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700150 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700151}
152
Ian Rogersef7d42f2014-01-06 12:55:46 -0800153static void Unsafe_putObjectVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset,
154 jobject javaNewValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700155 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800156 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
157 mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100158 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700159 obj->SetFieldObjectVolatile<false>(MemberOffset(offset), newValue);
Ian Rogers5d76c432011-10-31 21:42:49 -0700160}
161
Ian Rogersef7d42f2014-01-06 12:55:46 -0800162static void Unsafe_putOrderedObject(JNIEnv* env, jobject, jobject javaObj, jlong offset,
163 jobject javaNewValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700164 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800165 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
166 mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue);
Hans Boehm30359612014-05-21 17:46:23 -0700167 QuasiAtomic::ThreadFenceRelease();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100168 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700169 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700170}
171
Hiroshi Yamauchi4d2efce2014-02-10 16:19:09 -0800172static jint Unsafe_getArrayBaseOffsetForComponentType(JNIEnv* env, jclass, jobject component_class) {
173 ScopedFastNativeObjectAccess soa(env);
174 mirror::Class* component = soa.Decode<mirror::Class*>(component_class);
175 Primitive::Type primitive_type = component->GetPrimitiveType();
176 return mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value();
177}
178
179static jint Unsafe_getArrayIndexScaleForComponentType(JNIEnv* env, jclass, jobject component_class) {
180 ScopedFastNativeObjectAccess soa(env);
181 mirror::Class* component = soa.Decode<mirror::Class*>(component_class);
182 Primitive::Type primitive_type = component->GetPrimitiveType();
183 return Primitive::ComponentSize(primitive_type);
184}
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100185static jint Unsafe_addressSize(JNIEnv* env, jobject) {
186 return sizeof(void*);
187}
188
189static jint Unsafe_pageSize(JNIEnv* env, jobject) {
190 return sysconf(_SC_PAGESIZE);
191}
192
193static jlong Unsafe_allocateMemory(JNIEnv* env, jobject, jlong bytes) {
194 ScopedFastNativeObjectAccess soa(env);
195 // bytes is nonnegative and fits into size_t
196 if (bytes < 0 || bytes != (jlong)(size_t) bytes) {
197 ThrowIllegalAccessException(nullptr, "wrong number of bytes");
198 return 0;
199 }
200 void* mem = malloc(bytes);
201 if (mem == nullptr) {
202 soa.Self()->ThrowOutOfMemoryError("native alloc");
203 return 0;
204 }
205 return (uintptr_t) mem;
206}
207
208static void Unsafe_freeMemory(JNIEnv* env, jobject, jlong address) {
209 free((void*)(uintptr_t)address);
210}
211
212static void Unsafe_setMemory(JNIEnv* env, jobject, jlong address, jlong bytes, jbyte value) {
213 memset((void*)(uintptr_t)address, value, bytes);
214}
215
216static jbyte Unsafe_getByte$(JNIEnv* env, jobject, jlong address) {
217 return *reinterpret_cast<jbyte*>(address);
218}
219
220static void Unsafe_putByte$(JNIEnv* env, jobject, jlong address, jbyte value) {
221 *reinterpret_cast<jbyte*>(address) = value;
222}
223
224static jshort Unsafe_getShort$(JNIEnv* env, jobject, jlong address) {
225 return *reinterpret_cast<jshort*>(address);
226}
227
228static void Unsafe_putShort$(JNIEnv* env, jobject, jlong address, jshort value) {
229 *reinterpret_cast<jshort*>(address) = value;
230}
231
232static jchar Unsafe_getChar$(JNIEnv* env, jobject, jlong address) {
233 return *reinterpret_cast<jchar*>(address);
234}
235
236static void Unsafe_putChar$(JNIEnv* env, jobject, jlong address, jchar value) {
237 *reinterpret_cast<jchar*>(address) = value;
238}
239
240static jint Unsafe_getInt$(JNIEnv* env, jobject, jlong address) {
241 return *reinterpret_cast<jint*>(address);
242}
243
244static void Unsafe_putInt$(JNIEnv* env, jobject, jlong address, jint value) {
245 *reinterpret_cast<jint*>(address) = value;
246}
247
248static jlong Unsafe_getLong$(JNIEnv* env, jobject, jlong address) {
249 return *reinterpret_cast<jlong*>(address);
250}
251
252static void Unsafe_putLong$(JNIEnv* env, jobject, jlong address, jlong value) {
253 *reinterpret_cast<jlong*>(address) = value;
254}
255
256static jfloat Unsafe_getFloat$(JNIEnv* env, jobject, jlong address) {
257 return *reinterpret_cast<jfloat*>(address);
258}
259
260static void Unsafe_putFloat$(JNIEnv* env, jobject, jlong address, jfloat value) {
261 *reinterpret_cast<jfloat*>(address) = value;
262}
263static jdouble Unsafe_getDouble$(JNIEnv* env, jobject, jlong address) {
264 return *reinterpret_cast<jdouble*>(address);
265}
266
267static void Unsafe_putDouble$(JNIEnv* env, jobject, jlong address, jdouble value) {
268 *reinterpret_cast<jdouble*>(address) = value;
269}
270
271static jlong Unsafe_getAddress(JNIEnv* env, jobject, jlong address) {
272 void* p = (void*)(uintptr_t)address;
273 return (uintptr_t)(*(void**)p);
274}
275
276static void Unsafe_copyMemory(JNIEnv *env, jobject unsafe, jlong src, jlong dst, jlong size) {
277 if (size == 0) {
278 return;
279 }
280 // size is nonnegative and fits into size_t
281 if (size < 0 || size != (jlong)(size_t) size) {
282 ScopedFastNativeObjectAccess soa(env);
283 ThrowIllegalAccessException(nullptr, "wrong number of bytes");
284 }
285 size_t sz = (size_t)size;
286 memcpy(reinterpret_cast<void *>(dst), reinterpret_cast<void *>(src), sz);
287}
288
289template<typename T>
290static void copyToArray(jlong srcAddr, mirror::PrimitiveArray<T>* array, size_t size)
291 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
292 const T* src = reinterpret_cast<T*>(srcAddr);
293 size_t sz = size / sizeof(T);
294 for (size_t i = 0; i < sz; ++i) {
295 array->Set(i, *(src + i));
296 }
297}
298
299template<typename T>
300static void copyFromArray(jlong dstAddr, mirror::PrimitiveArray<T>* array, size_t size)
301 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_){
302 T* dst = reinterpret_cast<T*>(dstAddr);
303 size_t sz = size / sizeof(T);
304 for (size_t i = 0; i < sz; ++i) {
305 *(dst + i) = array->Get(i);
306 }
307}
308
309static void Unsafe_copyMemoryToPrimitiveArray(JNIEnv *env,
310 jobject unsafe,
311 jlong srcAddr,
312 jobject dstObj,
313 jlong dstOffset,
314 jlong size) {
315 ScopedObjectAccess soa(env);
316 if (size == 0) {
317 return;
318 }
319 // size is nonnegative and fits into size_t
320 if (size < 0 || size != (jlong)(size_t) size) {
321 ThrowIllegalAccessException(nullptr, "wrong number of bytes");
322 }
323 size_t sz = (size_t)size;
324 mirror::Object* dst = soa.Decode<mirror::Object*>(dstObj);
325 mirror::Class* component_type = dst->GetClass()->GetComponentType();
326 if (component_type->IsPrimitiveByte() || component_type->IsPrimitiveBoolean()) {
327 copyToArray(srcAddr, dst->AsByteSizedArray(), sz);
328 } else if (component_type->IsPrimitiveShort() || component_type->IsPrimitiveChar()) {
329 copyToArray(srcAddr, dst->AsShortSizedArray(), sz);
330 } else if (component_type->IsPrimitiveInt() || component_type->IsPrimitiveFloat()) {
331 copyToArray(srcAddr, dst->AsIntArray(), sz);
332 } else if (component_type->IsPrimitiveLong() || component_type->IsPrimitiveDouble()) {
333 copyToArray(srcAddr, dst->AsLongArray(), sz);
334 } else {
335 ThrowIllegalAccessException(nullptr, "not a primitive array");
336 }
337}
338
339static void Unsafe_copyMemoryFromPrimitiveArray(JNIEnv *env,
340 jobject unsafe,
341 jobject srcObj,
342 jlong srcOffset,
343 jlong dstAddr,
344 jlong size) {
345 ScopedObjectAccess soa(env);
346 if (size == 0) {
347 return;
348 }
349 // size is nonnegative and fits into size_t
350 if (size < 0 || size != (jlong)(size_t) size) {
351 ThrowIllegalAccessException(nullptr, "wrong number of bytes");
352 }
353 size_t sz = (size_t)size;
354 mirror::Object* src = soa.Decode<mirror::Object*>(srcObj);
355 mirror::Class* component_type = src->GetClass()->GetComponentType();
356 if (component_type->IsPrimitiveByte() || component_type->IsPrimitiveBoolean()) {
357 copyFromArray(dstAddr, src->AsByteSizedArray(), sz);
358 } else if (component_type->IsPrimitiveShort() || component_type->IsPrimitiveChar()) {
359 copyFromArray(dstAddr, src->AsShortSizedArray(), sz);
360 } else if (component_type->IsPrimitiveInt() || component_type->IsPrimitiveFloat()) {
361 copyFromArray(dstAddr, src->AsIntArray(), sz);
362 } else if (component_type->IsPrimitiveLong() || component_type->IsPrimitiveDouble()) {
363 copyFromArray(dstAddr, src->AsLongArray(), sz);
364 } else {
365 ThrowIllegalAccessException(nullptr, "not a primitive array");
366 }
367}
Hiroshi Yamauchi4d2efce2014-02-10 16:19:09 -0800368
Elliott Hughes0512f022012-03-15 22:10:52 -0700369static JNINativeMethod gMethods[] = {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700370 NATIVE_METHOD(Unsafe, compareAndSwapInt, "!(Ljava/lang/Object;JII)Z"),
371 NATIVE_METHOD(Unsafe, compareAndSwapLong, "!(Ljava/lang/Object;JJJ)Z"),
372 NATIVE_METHOD(Unsafe, compareAndSwapObject, "!(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z"),
373 NATIVE_METHOD(Unsafe, getIntVolatile, "!(Ljava/lang/Object;J)I"),
374 NATIVE_METHOD(Unsafe, putIntVolatile, "!(Ljava/lang/Object;JI)V"),
375 NATIVE_METHOD(Unsafe, getLongVolatile, "!(Ljava/lang/Object;J)J"),
376 NATIVE_METHOD(Unsafe, putLongVolatile, "!(Ljava/lang/Object;JJ)V"),
377 NATIVE_METHOD(Unsafe, getObjectVolatile, "!(Ljava/lang/Object;J)Ljava/lang/Object;"),
378 NATIVE_METHOD(Unsafe, putObjectVolatile, "!(Ljava/lang/Object;JLjava/lang/Object;)V"),
379 NATIVE_METHOD(Unsafe, getInt, "!(Ljava/lang/Object;J)I"),
380 NATIVE_METHOD(Unsafe, putInt, "!(Ljava/lang/Object;JI)V"),
381 NATIVE_METHOD(Unsafe, putOrderedInt, "!(Ljava/lang/Object;JI)V"),
382 NATIVE_METHOD(Unsafe, getLong, "!(Ljava/lang/Object;J)J"),
383 NATIVE_METHOD(Unsafe, putLong, "!(Ljava/lang/Object;JJ)V"),
384 NATIVE_METHOD(Unsafe, putOrderedLong, "!(Ljava/lang/Object;JJ)V"),
385 NATIVE_METHOD(Unsafe, getObject, "!(Ljava/lang/Object;J)Ljava/lang/Object;"),
386 NATIVE_METHOD(Unsafe, putObject, "!(Ljava/lang/Object;JLjava/lang/Object;)V"),
387 NATIVE_METHOD(Unsafe, putOrderedObject, "!(Ljava/lang/Object;JLjava/lang/Object;)V"),
Hiroshi Yamauchi4d2efce2014-02-10 16:19:09 -0800388 NATIVE_METHOD(Unsafe, getArrayBaseOffsetForComponentType, "!(Ljava/lang/Class;)I"),
389 NATIVE_METHOD(Unsafe, getArrayIndexScaleForComponentType, "!(Ljava/lang/Class;)I"),
Piotr Jastrzebskid7fcf6e2015-05-05 12:54:00 +0100390 NATIVE_METHOD(Unsafe, addressSize, "!()I"),
391 NATIVE_METHOD(Unsafe, pageSize, "!()I"),
392 NATIVE_METHOD(Unsafe, allocateMemory, "!(J)J"),
393 NATIVE_METHOD(Unsafe, freeMemory, "!(J)V"),
394 NATIVE_METHOD(Unsafe, setMemory, "!(JJB)V"),
395 NATIVE_METHOD(Unsafe, getByte$, "!(J)B"),
396 NATIVE_METHOD(Unsafe, putByte$, "!(JB)V"),
397 NATIVE_METHOD(Unsafe, getShort$, "!(J)S"),
398 NATIVE_METHOD(Unsafe, putShort$, "!(JS)V"),
399 NATIVE_METHOD(Unsafe, getChar$, "!(J)C"),
400 NATIVE_METHOD(Unsafe, putChar$, "!(JC)V"),
401 NATIVE_METHOD(Unsafe, getInt$, "!(J)I"),
402 NATIVE_METHOD(Unsafe, putInt$, "!(JI)V"),
403 NATIVE_METHOD(Unsafe, getLong$, "!(J)J"),
404 NATIVE_METHOD(Unsafe, putLong$, "!(JJ)V"),
405 NATIVE_METHOD(Unsafe, getFloat$, "!(J)F"),
406 NATIVE_METHOD(Unsafe, putFloat$, "!(JF)V"),
407 NATIVE_METHOD(Unsafe, getDouble$, "!(J)D"),
408 NATIVE_METHOD(Unsafe, putDouble$, "!(JD)V"),
409 NATIVE_METHOD(Unsafe, getAddress, "!(J)J"),
410 NATIVE_METHOD(Unsafe, copyMemory, "!(JJJ)V"),
411 NATIVE_METHOD(Unsafe, copyMemoryToPrimitiveArray, "!(JLjava/lang/Object;JJ)V"),
412 NATIVE_METHOD(Unsafe, copyMemoryFromPrimitiveArray, "!(Ljava/lang/Object;JJJ)V"),
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700413};
414
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700415void register_sun_misc_Unsafe(JNIEnv* env) {
Elliott Hugheseac76672012-05-24 21:56:51 -0700416 REGISTER_NATIVE_METHODS("sun/misc/Unsafe");
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700417}
418
419} // namespace art