1/* 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 17#include "sun_misc_Unsafe.h" 18#include "common_throws.h" 19#include "gc/accounting/card_table-inl.h" 20#include "jni_internal.h" 21#include "mirror/array.h" 22#include "mirror/class-inl.h" 23#include "mirror/object-inl.h" 24#include "scoped_fast_native_object_access.h" 25 26#include <unistd.h> 27#include <stdlib.h> 28#include <string.h> 29#include <atomic> 30 31namespace art { 32 33static jboolean Unsafe_compareAndSwapInt(JNIEnv* env, jobject, jobject javaObj, jlong offset, 34 jint expectedValue, jint newValue) { 35 ScopedFastNativeObjectAccess soa(env); 36 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 37 // JNI must use non transactional mode. 38 bool success = obj->CasFieldStrongSequentiallyConsistent32<false>(MemberOffset(offset), 39 expectedValue, newValue); 40 return success ? JNI_TRUE : JNI_FALSE; 41} 42 43static jboolean Unsafe_compareAndSwapLong(JNIEnv* env, jobject, jobject javaObj, jlong offset, 44 jlong expectedValue, jlong newValue) { 45 ScopedFastNativeObjectAccess soa(env); 46 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 47 // JNI must use non transactional mode. 48 bool success = obj->CasFieldStrongSequentiallyConsistent64<false>(MemberOffset(offset), 49 expectedValue, newValue); 50 return success ? JNI_TRUE : JNI_FALSE; 51} 52 53static jboolean Unsafe_compareAndSwapObject(JNIEnv* env, jobject, jobject javaObj, jlong offset, 54 jobject javaExpectedValue, jobject javaNewValue) { 55 ScopedFastNativeObjectAccess soa(env); 56 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 57 mirror::Object* expectedValue = soa.Decode<mirror::Object*>(javaExpectedValue); 58 mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue); 59 // JNI must use non transactional mode. 60 if (kUseReadBarrier) { 61 // Need to make sure the reference stored in the field is a to-space one before attempting the 62 // CAS or the CAS could fail incorrectly. 63 mirror::HeapReference<mirror::Object>* field_addr = 64 reinterpret_cast<mirror::HeapReference<mirror::Object>*>( 65 reinterpret_cast<uint8_t*>(obj) + static_cast<size_t>(offset)); 66 ReadBarrier::Barrier<mirror::Object, kWithReadBarrier, /*kAlwaysUpdateField*/true>( 67 obj, 68 MemberOffset(offset), 69 field_addr); 70 } 71 bool success = obj->CasFieldStrongSequentiallyConsistentObject<false>(MemberOffset(offset), 72 expectedValue, newValue); 73 return success ? JNI_TRUE : JNI_FALSE; 74} 75 76static jint Unsafe_getInt(JNIEnv* env, jobject, jobject javaObj, jlong offset) { 77 ScopedFastNativeObjectAccess soa(env); 78 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 79 return obj->GetField32(MemberOffset(offset)); 80} 81 82static jint Unsafe_getIntVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) { 83 ScopedFastNativeObjectAccess soa(env); 84 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 85 return obj->GetField32Volatile(MemberOffset(offset)); 86} 87 88static void Unsafe_putInt(JNIEnv* env, jobject, jobject javaObj, jlong offset, jint newValue) { 89 ScopedFastNativeObjectAccess soa(env); 90 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 91 // JNI must use non transactional mode. 92 obj->SetField32<false>(MemberOffset(offset), newValue); 93} 94 95static void Unsafe_putIntVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset, 96 jint newValue) { 97 ScopedFastNativeObjectAccess soa(env); 98 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 99 // JNI must use non transactional mode. 100 obj->SetField32Volatile<false>(MemberOffset(offset), newValue); 101} 102 103static void Unsafe_putOrderedInt(JNIEnv* env, jobject, jobject javaObj, jlong offset, 104 jint newValue) { 105 ScopedFastNativeObjectAccess soa(env); 106 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 107 QuasiAtomic::ThreadFenceRelease(); 108 // JNI must use non transactional mode. 109 obj->SetField32<false>(MemberOffset(offset), newValue); 110} 111 112static jlong Unsafe_getLong(JNIEnv* env, jobject, jobject javaObj, jlong offset) { 113 ScopedFastNativeObjectAccess soa(env); 114 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 115 return obj->GetField64(MemberOffset(offset)); 116} 117 118static jlong Unsafe_getLongVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) { 119 ScopedFastNativeObjectAccess soa(env); 120 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 121 return obj->GetField64Volatile(MemberOffset(offset)); 122} 123 124static void Unsafe_putLong(JNIEnv* env, jobject, jobject javaObj, jlong offset, jlong newValue) { 125 ScopedFastNativeObjectAccess soa(env); 126 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 127 // JNI must use non transactional mode. 128 obj->SetField64<false>(MemberOffset(offset), newValue); 129} 130 131static void Unsafe_putLongVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset, 132 jlong newValue) { 133 ScopedFastNativeObjectAccess soa(env); 134 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 135 // JNI must use non transactional mode. 136 obj->SetField64Volatile<false>(MemberOffset(offset), newValue); 137} 138 139static void Unsafe_putOrderedLong(JNIEnv* env, jobject, jobject javaObj, jlong offset, 140 jlong newValue) { 141 ScopedFastNativeObjectAccess soa(env); 142 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 143 QuasiAtomic::ThreadFenceRelease(); 144 // JNI must use non transactional mode. 145 obj->SetField64<false>(MemberOffset(offset), newValue); 146} 147 148static jobject Unsafe_getObjectVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) { 149 ScopedFastNativeObjectAccess soa(env); 150 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 151 mirror::Object* value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset)); 152 return soa.AddLocalReference<jobject>(value); 153} 154 155static jobject Unsafe_getObject(JNIEnv* env, jobject, jobject javaObj, jlong offset) { 156 ScopedFastNativeObjectAccess soa(env); 157 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 158 mirror::Object* value = obj->GetFieldObject<mirror::Object>(MemberOffset(offset)); 159 return soa.AddLocalReference<jobject>(value); 160} 161 162static void Unsafe_putObject(JNIEnv* env, jobject, jobject javaObj, jlong offset, 163 jobject javaNewValue) { 164 ScopedFastNativeObjectAccess soa(env); 165 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 166 mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue); 167 // JNI must use non transactional mode. 168 obj->SetFieldObject<false>(MemberOffset(offset), newValue); 169} 170 171static void Unsafe_putObjectVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset, 172 jobject javaNewValue) { 173 ScopedFastNativeObjectAccess soa(env); 174 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 175 mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue); 176 // JNI must use non transactional mode. 177 obj->SetFieldObjectVolatile<false>(MemberOffset(offset), newValue); 178} 179 180static void Unsafe_putOrderedObject(JNIEnv* env, jobject, jobject javaObj, jlong offset, 181 jobject javaNewValue) { 182 ScopedFastNativeObjectAccess soa(env); 183 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 184 mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue); 185 QuasiAtomic::ThreadFenceRelease(); 186 // JNI must use non transactional mode. 187 obj->SetFieldObject<false>(MemberOffset(offset), newValue); 188} 189 190static jint Unsafe_getArrayBaseOffsetForComponentType(JNIEnv* env, jclass, jobject component_class) { 191 ScopedFastNativeObjectAccess soa(env); 192 mirror::Class* component = soa.Decode<mirror::Class*>(component_class); 193 Primitive::Type primitive_type = component->GetPrimitiveType(); 194 return mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value(); 195} 196 197static jint Unsafe_getArrayIndexScaleForComponentType(JNIEnv* env, jclass, jobject component_class) { 198 ScopedFastNativeObjectAccess soa(env); 199 mirror::Class* component = soa.Decode<mirror::Class*>(component_class); 200 Primitive::Type primitive_type = component->GetPrimitiveType(); 201 return Primitive::ComponentSize(primitive_type); 202} 203 204static jint Unsafe_addressSize(JNIEnv* env ATTRIBUTE_UNUSED, jobject ob ATTRIBUTE_UNUSED) { 205 return sizeof(void*); 206} 207 208static jint Unsafe_pageSize(JNIEnv* env ATTRIBUTE_UNUSED, jobject ob ATTRIBUTE_UNUSED) { 209 return sysconf(_SC_PAGESIZE); 210} 211 212static jlong Unsafe_allocateMemory(JNIEnv* env, jobject, jlong bytes) { 213 ScopedFastNativeObjectAccess soa(env); 214 // bytes is nonnegative and fits into size_t 215 if (bytes < 0 || bytes != (jlong)(size_t) bytes) { 216 ThrowIllegalAccessException("wrong number of bytes"); 217 return 0; 218 } 219 void* mem = malloc(bytes); 220 if (mem == nullptr) { 221 soa.Self()->ThrowOutOfMemoryError("native alloc"); 222 return 0; 223 } 224 return (uintptr_t) mem; 225} 226 227static void Unsafe_freeMemory(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) { 228 free(reinterpret_cast<void*>(static_cast<uintptr_t>(address))); 229} 230 231static void Unsafe_setMemory(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jlong bytes, jbyte value) { 232 memset(reinterpret_cast<void*>(static_cast<uintptr_t>(address)), value, bytes); 233} 234 235static jbyte Unsafe_getByteJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) { 236 return *reinterpret_cast<jbyte*>(address); 237} 238 239static void Unsafe_putByteJB(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jbyte value) { 240 *reinterpret_cast<jbyte*>(address) = value; 241} 242 243static jshort Unsafe_getShortJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) { 244 return *reinterpret_cast<jshort*>(address); 245} 246 247static void Unsafe_putShortJS(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jshort value) { 248 *reinterpret_cast<jshort*>(address) = value; 249} 250 251static jchar Unsafe_getCharJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) { 252 return *reinterpret_cast<jchar*>(address); 253} 254 255static void Unsafe_putCharJC(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jchar value) { 256 *reinterpret_cast<jchar*>(address) = value; 257} 258 259static jint Unsafe_getIntJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) { 260 return *reinterpret_cast<jint*>(address); 261} 262 263static void Unsafe_putIntJI(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jint value) { 264 *reinterpret_cast<jint*>(address) = value; 265} 266 267static jlong Unsafe_getLongJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) { 268 return *reinterpret_cast<jlong*>(address); 269} 270 271static void Unsafe_putLongJJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jlong value) { 272 *reinterpret_cast<jlong*>(address) = value; 273} 274 275static jfloat Unsafe_getFloatJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) { 276 return *reinterpret_cast<jfloat*>(address); 277} 278 279static void Unsafe_putFloatJF(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jfloat value) { 280 *reinterpret_cast<jfloat*>(address) = value; 281} 282static jdouble Unsafe_getDoubleJ(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address) { 283 return *reinterpret_cast<jdouble*>(address); 284} 285 286static void Unsafe_putDoubleJD(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong address, jdouble value) { 287 *reinterpret_cast<jdouble*>(address) = value; 288} 289 290static void Unsafe_copyMemory(JNIEnv *env, jobject unsafe ATTRIBUTE_UNUSED, jlong src, 291 jlong dst, jlong size) { 292 if (size == 0) { 293 return; 294 } 295 // size is nonnegative and fits into size_t 296 if (size < 0 || size != (jlong)(size_t) size) { 297 ScopedFastNativeObjectAccess soa(env); 298 ThrowIllegalAccessException("wrong number of bytes"); 299 } 300 size_t sz = (size_t)size; 301 memcpy(reinterpret_cast<void *>(dst), reinterpret_cast<void *>(src), sz); 302} 303 304template<typename T> 305static void copyToArray(jlong srcAddr, mirror::PrimitiveArray<T>* array, 306 size_t array_offset, 307 size_t size) 308 SHARED_REQUIRES(Locks::mutator_lock_) { 309 const T* src = reinterpret_cast<T*>(srcAddr); 310 size_t sz = size / sizeof(T); 311 size_t of = array_offset / sizeof(T); 312 for (size_t i = 0; i < sz; ++i) { 313 array->Set(i + of, *(src + i)); 314 } 315} 316 317template<typename T> 318static void copyFromArray(jlong dstAddr, mirror::PrimitiveArray<T>* array, 319 size_t array_offset, 320 size_t size) 321 SHARED_REQUIRES(Locks::mutator_lock_) { 322 T* dst = reinterpret_cast<T*>(dstAddr); 323 size_t sz = size / sizeof(T); 324 size_t of = array_offset / sizeof(T); 325 for (size_t i = 0; i < sz; ++i) { 326 *(dst + i) = array->Get(i + of); 327 } 328} 329 330static void Unsafe_copyMemoryToPrimitiveArray(JNIEnv *env, 331 jobject unsafe ATTRIBUTE_UNUSED, 332 jlong srcAddr, 333 jobject dstObj, 334 jlong dstOffset, 335 jlong size) { 336 ScopedObjectAccess soa(env); 337 if (size == 0) { 338 return; 339 } 340 // size is nonnegative and fits into size_t 341 if (size < 0 || size != (jlong)(size_t) size) { 342 ThrowIllegalAccessException("wrong number of bytes"); 343 } 344 size_t sz = (size_t)size; 345 size_t dst_offset = (size_t)dstOffset; 346 mirror::Object* dst = soa.Decode<mirror::Object*>(dstObj); 347 mirror::Class* component_type = dst->GetClass()->GetComponentType(); 348 if (component_type->IsPrimitiveByte() || component_type->IsPrimitiveBoolean()) { 349 copyToArray(srcAddr, dst->AsByteSizedArray(), dst_offset, sz); 350 } else if (component_type->IsPrimitiveShort() || component_type->IsPrimitiveChar()) { 351 copyToArray(srcAddr, dst->AsShortSizedArray(), dst_offset, sz); 352 } else if (component_type->IsPrimitiveInt() || component_type->IsPrimitiveFloat()) { 353 copyToArray(srcAddr, dst->AsIntArray(), dst_offset, sz); 354 } else if (component_type->IsPrimitiveLong() || component_type->IsPrimitiveDouble()) { 355 copyToArray(srcAddr, dst->AsLongArray(), dst_offset, sz); 356 } else { 357 ThrowIllegalAccessException("not a primitive array"); 358 } 359} 360 361static void Unsafe_copyMemoryFromPrimitiveArray(JNIEnv *env, 362 jobject unsafe ATTRIBUTE_UNUSED, 363 jobject srcObj, 364 jlong srcOffset, 365 jlong dstAddr, 366 jlong size) { 367 ScopedObjectAccess soa(env); 368 if (size == 0) { 369 return; 370 } 371 // size is nonnegative and fits into size_t 372 if (size < 0 || size != (jlong)(size_t) size) { 373 ThrowIllegalAccessException("wrong number of bytes"); 374 } 375 size_t sz = (size_t)size; 376 size_t src_offset = (size_t)srcOffset; 377 mirror::Object* src = soa.Decode<mirror::Object*>(srcObj); 378 mirror::Class* component_type = src->GetClass()->GetComponentType(); 379 if (component_type->IsPrimitiveByte() || component_type->IsPrimitiveBoolean()) { 380 copyFromArray(dstAddr, src->AsByteSizedArray(), src_offset, sz); 381 } else if (component_type->IsPrimitiveShort() || component_type->IsPrimitiveChar()) { 382 copyFromArray(dstAddr, src->AsShortSizedArray(), src_offset, sz); 383 } else if (component_type->IsPrimitiveInt() || component_type->IsPrimitiveFloat()) { 384 copyFromArray(dstAddr, src->AsIntArray(), src_offset, sz); 385 } else if (component_type->IsPrimitiveLong() || component_type->IsPrimitiveDouble()) { 386 copyFromArray(dstAddr, src->AsLongArray(), src_offset, sz); 387 } else { 388 ThrowIllegalAccessException("not a primitive array"); 389 } 390} 391static jboolean Unsafe_getBoolean(JNIEnv* env, jobject, jobject javaObj, jlong offset) { 392 ScopedFastNativeObjectAccess soa(env); 393 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 394 return obj->GetFieldBoolean(MemberOffset(offset)); 395} 396 397static void Unsafe_putBoolean(JNIEnv* env, jobject, jobject javaObj, jlong offset, jboolean newValue) { 398 ScopedFastNativeObjectAccess soa(env); 399 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 400 // JNI must use non transactional mode (SetField8 is non-transactional). 401 obj->SetFieldBoolean<false>(MemberOffset(offset), newValue); 402} 403 404static jbyte Unsafe_getByte(JNIEnv* env, jobject, jobject javaObj, jlong offset) { 405 ScopedFastNativeObjectAccess soa(env); 406 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 407 return obj->GetFieldByte(MemberOffset(offset)); 408} 409 410static void Unsafe_putByte(JNIEnv* env, jobject, jobject javaObj, jlong offset, jbyte newValue) { 411 ScopedFastNativeObjectAccess soa(env); 412 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 413 // JNI must use non transactional mode. 414 obj->SetFieldByte<false>(MemberOffset(offset), newValue); 415} 416 417static jchar Unsafe_getChar(JNIEnv* env, jobject, jobject javaObj, jlong offset) { 418 ScopedFastNativeObjectAccess soa(env); 419 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 420 return obj->GetFieldChar(MemberOffset(offset)); 421} 422 423static void Unsafe_putChar(JNIEnv* env, jobject, jobject javaObj, jlong offset, jchar newValue) { 424 ScopedFastNativeObjectAccess soa(env); 425 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 426 // JNI must use non transactional mode. 427 obj->SetFieldChar<false>(MemberOffset(offset), newValue); 428} 429 430static jshort Unsafe_getShort(JNIEnv* env, jobject, jobject javaObj, jlong offset) { 431 ScopedFastNativeObjectAccess soa(env); 432 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 433 return obj->GetFieldShort(MemberOffset(offset)); 434} 435 436static void Unsafe_putShort(JNIEnv* env, jobject, jobject javaObj, jlong offset, jshort newValue) { 437 ScopedFastNativeObjectAccess soa(env); 438 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 439 // JNI must use non transactional mode. 440 obj->SetFieldShort<false>(MemberOffset(offset), newValue); 441} 442 443static jfloat Unsafe_getFloat(JNIEnv* env, jobject, jobject javaObj, jlong offset) { 444 ScopedFastNativeObjectAccess soa(env); 445 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 446 union {int32_t val; jfloat converted;} conv; 447 conv.val = obj->GetField32(MemberOffset(offset)); 448 return conv.converted; 449} 450 451static void Unsafe_putFloat(JNIEnv* env, jobject, jobject javaObj, jlong offset, jfloat newValue) { 452 ScopedFastNativeObjectAccess soa(env); 453 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 454 union {int32_t converted; jfloat val;} conv; 455 conv.val = newValue; 456 // JNI must use non transactional mode. 457 obj->SetField32<false>(MemberOffset(offset), conv.converted); 458} 459 460static jdouble Unsafe_getDouble(JNIEnv* env, jobject, jobject javaObj, jlong offset) { 461 ScopedFastNativeObjectAccess soa(env); 462 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 463 union {int64_t val; jdouble converted;} conv; 464 conv.val = obj->GetField64(MemberOffset(offset)); 465 return conv.converted; 466} 467 468static void Unsafe_putDouble(JNIEnv* env, jobject, jobject javaObj, jlong offset, jdouble newValue) { 469 ScopedFastNativeObjectAccess soa(env); 470 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); 471 union {int64_t converted; jdouble val;} conv; 472 conv.val = newValue; 473 // JNI must use non transactional mode. 474 obj->SetField64<false>(MemberOffset(offset), conv.converted); 475} 476 477static void Unsafe_loadFence(JNIEnv*, jobject) { 478 std::atomic_thread_fence(std::memory_order_acquire); 479} 480 481static void Unsafe_storeFence(JNIEnv*, jobject) { 482 std::atomic_thread_fence(std::memory_order_release); 483} 484 485static void Unsafe_fullFence(JNIEnv*, jobject) { 486 std::atomic_thread_fence(std::memory_order_seq_cst); 487} 488 489static JNINativeMethod gMethods[] = { 490 NATIVE_METHOD(Unsafe, compareAndSwapInt, "!(Ljava/lang/Object;JII)Z"), 491 NATIVE_METHOD(Unsafe, compareAndSwapLong, "!(Ljava/lang/Object;JJJ)Z"), 492 NATIVE_METHOD(Unsafe, compareAndSwapObject, "!(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z"), 493 NATIVE_METHOD(Unsafe, getIntVolatile, "!(Ljava/lang/Object;J)I"), 494 NATIVE_METHOD(Unsafe, putIntVolatile, "!(Ljava/lang/Object;JI)V"), 495 NATIVE_METHOD(Unsafe, getLongVolatile, "!(Ljava/lang/Object;J)J"), 496 NATIVE_METHOD(Unsafe, putLongVolatile, "!(Ljava/lang/Object;JJ)V"), 497 NATIVE_METHOD(Unsafe, getObjectVolatile, "!(Ljava/lang/Object;J)Ljava/lang/Object;"), 498 NATIVE_METHOD(Unsafe, putObjectVolatile, "!(Ljava/lang/Object;JLjava/lang/Object;)V"), 499 NATIVE_METHOD(Unsafe, getInt, "!(Ljava/lang/Object;J)I"), 500 NATIVE_METHOD(Unsafe, putInt, "!(Ljava/lang/Object;JI)V"), 501 NATIVE_METHOD(Unsafe, putOrderedInt, "!(Ljava/lang/Object;JI)V"), 502 NATIVE_METHOD(Unsafe, getLong, "!(Ljava/lang/Object;J)J"), 503 NATIVE_METHOD(Unsafe, putLong, "!(Ljava/lang/Object;JJ)V"), 504 NATIVE_METHOD(Unsafe, putOrderedLong, "!(Ljava/lang/Object;JJ)V"), 505 NATIVE_METHOD(Unsafe, getObject, "!(Ljava/lang/Object;J)Ljava/lang/Object;"), 506 NATIVE_METHOD(Unsafe, putObject, "!(Ljava/lang/Object;JLjava/lang/Object;)V"), 507 NATIVE_METHOD(Unsafe, putOrderedObject, "!(Ljava/lang/Object;JLjava/lang/Object;)V"), 508 NATIVE_METHOD(Unsafe, getArrayBaseOffsetForComponentType, "!(Ljava/lang/Class;)I"), 509 NATIVE_METHOD(Unsafe, getArrayIndexScaleForComponentType, "!(Ljava/lang/Class;)I"), 510 NATIVE_METHOD(Unsafe, addressSize, "!()I"), 511 NATIVE_METHOD(Unsafe, pageSize, "!()I"), 512 NATIVE_METHOD(Unsafe, allocateMemory, "!(J)J"), 513 NATIVE_METHOD(Unsafe, freeMemory, "!(J)V"), 514 NATIVE_METHOD(Unsafe, setMemory, "!(JJB)V"), 515 NATIVE_METHOD(Unsafe, copyMemory, "!(JJJ)V"), 516 NATIVE_METHOD(Unsafe, copyMemoryToPrimitiveArray, "!(JLjava/lang/Object;JJ)V"), 517 NATIVE_METHOD(Unsafe, copyMemoryFromPrimitiveArray, "!(Ljava/lang/Object;JJJ)V"), 518 NATIVE_METHOD(Unsafe, getBoolean, "!(Ljava/lang/Object;J)Z"), 519 520 NATIVE_METHOD(Unsafe, getByte, "!(Ljava/lang/Object;J)B"), 521 NATIVE_METHOD(Unsafe, getChar, "!(Ljava/lang/Object;J)C"), 522 NATIVE_METHOD(Unsafe, getShort, "!(Ljava/lang/Object;J)S"), 523 NATIVE_METHOD(Unsafe, getFloat, "!(Ljava/lang/Object;J)F"), 524 NATIVE_METHOD(Unsafe, getDouble, "!(Ljava/lang/Object;J)D"), 525 NATIVE_METHOD(Unsafe, putBoolean, "!(Ljava/lang/Object;JZ)V"), 526 NATIVE_METHOD(Unsafe, putByte, "!(Ljava/lang/Object;JB)V"), 527 NATIVE_METHOD(Unsafe, putChar, "!(Ljava/lang/Object;JC)V"), 528 NATIVE_METHOD(Unsafe, putShort, "!(Ljava/lang/Object;JS)V"), 529 NATIVE_METHOD(Unsafe, putFloat, "!(Ljava/lang/Object;JF)V"), 530 NATIVE_METHOD(Unsafe, putDouble, "!(Ljava/lang/Object;JD)V"), 531 532 // Each of the getFoo variants are overloaded with a call that operates 533 // directively on a native pointer. 534 OVERLOADED_NATIVE_METHOD(Unsafe, getByte, "!(J)B", getByteJ), 535 OVERLOADED_NATIVE_METHOD(Unsafe, getChar, "!(J)C", getCharJ), 536 OVERLOADED_NATIVE_METHOD(Unsafe, getShort, "!(J)S", getShortJ), 537 OVERLOADED_NATIVE_METHOD(Unsafe, getInt, "!(J)I", getIntJ), 538 OVERLOADED_NATIVE_METHOD(Unsafe, getLong, "!(J)J", getLongJ), 539 OVERLOADED_NATIVE_METHOD(Unsafe, getFloat, "!(J)F", getFloatJ), 540 OVERLOADED_NATIVE_METHOD(Unsafe, getDouble, "!(J)D", getDoubleJ), 541 OVERLOADED_NATIVE_METHOD(Unsafe, putByte, "!(JB)V", putByteJB), 542 OVERLOADED_NATIVE_METHOD(Unsafe, putChar, "!(JC)V", putCharJC), 543 OVERLOADED_NATIVE_METHOD(Unsafe, putShort, "!(JS)V", putShortJS), 544 OVERLOADED_NATIVE_METHOD(Unsafe, putInt, "!(JI)V", putIntJI), 545 OVERLOADED_NATIVE_METHOD(Unsafe, putLong, "!(JJ)V", putLongJJ), 546 OVERLOADED_NATIVE_METHOD(Unsafe, putFloat, "!(JF)V", putFloatJF), 547 OVERLOADED_NATIVE_METHOD(Unsafe, putDouble, "!(JD)V", putDoubleJD), 548 549 // CAS 550 NATIVE_METHOD(Unsafe, loadFence, "!()V"), 551 NATIVE_METHOD(Unsafe, storeFence, "!()V"), 552 NATIVE_METHOD(Unsafe, fullFence, "!()V"), 553}; 554 555void register_sun_misc_Unsafe(JNIEnv* env) { 556 REGISTER_NATIVE_METHODS("sun/misc/Unsafe"); 557} 558 559} // namespace art 560