libcore_io_Memory.cpp revision 329af9cb39b3cd325a6ac6d1bc906af8877eff9f
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * you may not use this file except in compliance with the License. 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * You may obtain a copy of the License at 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 17f934c3d2c8dd9e6bc5299cef41adace2a671637dElliott Hughes#define LOG_TAG "Memory" 18c08f9fb2a3be82bb1a3f477ca1524ddcf7a1d4b8Elliott Hughes 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include "JNIHelp.h" 20a9f5c16a864ff63ba63f810410f8a27c086d5d52Elliott Hughes#include "JniConstants.h" 216c1e5f4ad36c1f51687aa2b059e998a7c2db2e36Elliott Hughes#include "Portability.h" 220568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes#include "ScopedBytes.h" 23692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes#include "ScopedPrimitiveArray.h" 24034db7d210969f6e516d347810695633d063eb4bElliott Hughes#include "UniquePtr.h" 25034db7d210969f6e516d347810695633d063eb4bElliott Hughes 26034db7d210969f6e516d347810695633d063eb4bElliott Hughes#include <errno.h> 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include <stdlib.h> 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include <string.h> 29034db7d210969f6e516d347810695633d063eb4bElliott Hughes#include <sys/mman.h> 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 316116e6265924a0983bb462e3441c8c4a0bb7e47eElliott Hughes#if defined(__arm__) 327d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes// 32-bit ARM has load/store alignment restrictions for longs. 336116e6265924a0983bb462e3441c8c4a0bb7e47eElliott Hughes#define LONG_ALIGNMENT_MASK 0x3 34b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman#define INT_ALIGNMENT_MASK 0x0 35b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman#define SHORT_ALIGNMENT_MASK 0x0 36b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman#elif defined(__mips__) 37b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman// MIPS has load/store alignment restrictions for longs, ints and shorts. 38b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman#define LONG_ALIGNMENT_MASK 0x7 39b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman#define INT_ALIGNMENT_MASK 0x3 40b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman#define SHORT_ALIGNMENT_MASK 0x1 410121106d9dc1ba713b53822886355e4d9339e852Joel Dice#elif defined(__i386__) || defined(__x86_64__) 426116e6265924a0983bb462e3441c8c4a0bb7e47eElliott Hughes// x86 can load anything at any alignment. 436116e6265924a0983bb462e3441c8c4a0bb7e47eElliott Hughes#define LONG_ALIGNMENT_MASK 0x0 44b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman#define INT_ALIGNMENT_MASK 0x0 45b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman#define SHORT_ALIGNMENT_MASK 0x0 466116e6265924a0983bb462e3441c8c4a0bb7e47eElliott Hughes#else 476116e6265924a0983bb462e3441c8c4a0bb7e47eElliott Hughes#error unknown load/store alignment restrictions for this architecture 486116e6265924a0983bb462e3441c8c4a0bb7e47eElliott Hughes#endif 496116e6265924a0983bb462e3441c8c4a0bb7e47eElliott Hughes 50b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman// Use packed structures for access to unaligned data on targets with alignment restrictions. 51b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman// The compiler will generate appropriate code to access these structures without 52b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman// generating alignment exceptions. 53b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearmantemplate <typename T> static inline T get_unaligned(const T* address) { 54b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman struct unaligned { T v; } __attribute__ ((packed)); 55b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman const unaligned* p = reinterpret_cast<const unaligned*>(address); 56b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman return p->v; 57b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman} 58b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman 59b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearmantemplate <typename T> static inline void put_unaligned(T* address, T v) { 60b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman struct unaligned { T v; } __attribute__ ((packed)); 61b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman unaligned* p = reinterpret_cast<unaligned*>(address); 62b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman p->v = v; 63b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman} 64b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman 650121106d9dc1ba713b53822886355e4d9339e852Joel Dicetemplate <typename T> static T cast(jlong address) { 66034db7d210969f6e516d347810695633d063eb4bElliott Hughes return reinterpret_cast<T>(static_cast<uintptr_t>(address)); 67034db7d210969f6e516d347810695633d063eb4bElliott Hughes} 68034db7d210969f6e516d347810695633d063eb4bElliott Hughes 69b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman// Byte-swap 2 jshort values packed in a jint. 70b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearmanstatic inline jint bswap_2x16(jint v) { 71b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman // v is initially ABCD 72b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman#if defined(__mips__) && defined(__mips_isa_rev) && (__mips_isa_rev >= 2) 73b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman __asm__ volatile ("wsbh %0, %0" : "+r" (v)); // v=BADC 74b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman#else 757ba6c51277526eb66b328657abdaa85c05791826Chris Dearman v = bswap_32(v); // v=DCBA 76b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman v = (v << 16) | ((v >> 16) & 0xffff); // v=BADC 77b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman#endif 78b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman return v; 79b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman} 80b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman 812f85e921e4753cf4e87696014754278eda5f95efElliott Hughesstatic inline void swapShorts(jshort* dstShorts, const jshort* srcShorts, size_t count) { 827d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes // Do 32-bit swaps as long as possible... 837d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes jint* dst = reinterpret_cast<jint*>(dstShorts); 847d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes const jint* src = reinterpret_cast<const jint*>(srcShorts); 85b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman 86b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman if ((reinterpret_cast<uintptr_t>(dst) & INT_ALIGNMENT_MASK) == 0 && 87b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman (reinterpret_cast<uintptr_t>(src) & INT_ALIGNMENT_MASK) == 0) { 88b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman for (size_t i = 0; i < count / 2; ++i) { 89b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman jint v = *src++; 90b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman *dst++ = bswap_2x16(v); 91b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman } 92b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman // ...with one last 16-bit swap if necessary. 93b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman if ((count % 2) != 0) { 94b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman jshort v = *reinterpret_cast<const jshort*>(src); 95b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman *reinterpret_cast<jshort*>(dst) = bswap_16(v); 96b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman } 97b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman } else { 98b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman for (size_t i = 0; i < count / 2; ++i) { 99b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman jint v = get_unaligned<jint>(src++); 100b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman put_unaligned<jint>(dst++, bswap_2x16(v)); 101b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman } 102b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman if ((count % 2) != 0) { 103b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman jshort v = get_unaligned<jshort>(reinterpret_cast<const jshort*>(src)); 104b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman put_unaligned<jshort>(reinterpret_cast<jshort*>(dst), bswap_16(v)); 105b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman } 106692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes } 107692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes} 108692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes 1092f85e921e4753cf4e87696014754278eda5f95efElliott Hughesstatic inline void swapInts(jint* dstInts, const jint* srcInts, size_t count) { 110b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman if ((reinterpret_cast<uintptr_t>(dstInts) & INT_ALIGNMENT_MASK) == 0 && 111b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman (reinterpret_cast<uintptr_t>(srcInts) & INT_ALIGNMENT_MASK) == 0) { 112b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman for (size_t i = 0; i < count; ++i) { 113b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman jint v = *srcInts++; 114b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman *dstInts++ = bswap_32(v); 115b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman } 116b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman } else { 117b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman for (size_t i = 0; i < count; ++i) { 118b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman jint v = get_unaligned<int>(srcInts++); 119b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman put_unaligned<jint>(dstInts++, bswap_32(v)); 120b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman } 121692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes } 122692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes} 123692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes 1242f85e921e4753cf4e87696014754278eda5f95efElliott Hughesstatic inline void swapLongs(jlong* dstLongs, const jlong* srcLongs, size_t count) { 1257d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes jint* dst = reinterpret_cast<jint*>(dstLongs); 1267d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes const jint* src = reinterpret_cast<const jint*>(srcLongs); 127b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman if ((reinterpret_cast<uintptr_t>(dstLongs) & INT_ALIGNMENT_MASK) == 0 && 128b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman (reinterpret_cast<uintptr_t>(srcLongs) & INT_ALIGNMENT_MASK) == 0) { 129b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman for (size_t i = 0; i < count; ++i) { 130b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman jint v1 = *src++; 131b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman jint v2 = *src++; 132b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman *dst++ = bswap_32(v2); 133b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman *dst++ = bswap_32(v1); 134b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman } 135b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman } else { 136b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman for (size_t i = 0; i < count; ++i) { 137b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman jint v1 = get_unaligned<jint>(src++); 138b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman jint v2 = get_unaligned<jint>(src++); 139b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman put_unaligned<jint>(dst++, bswap_32(v2)); 140b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman put_unaligned<jint>(dst++, bswap_32(v1)); 141b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman } 142692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes } 143692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes} 144692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes 1450568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughesstatic void Memory_memmove(JNIEnv* env, jclass, jobject dstObject, jint dstOffset, jobject srcObject, jint srcOffset, jlong length) { 1460568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes ScopedBytesRW dstBytes(env, dstObject); 1470568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes if (dstBytes.get() == NULL) { 1480568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes return; 1490568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes } 1500568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes ScopedBytesRO srcBytes(env, srcObject); 1510568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes if (srcBytes.get() == NULL) { 1520568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes return; 1530568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes } 1540568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes memmove(dstBytes.get() + dstOffset, srcBytes.get() + srcOffset, length); 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1570121106d9dc1ba713b53822886355e4d9339e852Joel Dicestatic jbyte Memory_peekByte(JNIEnv*, jclass, jlong srcAddress) { 158034db7d210969f6e516d347810695633d063eb4bElliott Hughes return *cast<const jbyte*>(srcAddress); 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1610121106d9dc1ba713b53822886355e4d9339e852Joel Dicestatic void Memory_peekByteArray(JNIEnv* env, jclass, jlong srcAddress, jbyteArray dst, jint dstOffset, jint byteCount) { 162692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes env->SetByteArrayRegion(dst, dstOffset, byteCount, cast<const jbyte*>(srcAddress)); 163692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes} 164692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes 1657d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes// Implements the peekXArray methods: 1667d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes// - For unswapped access, we just use the JNI SetXArrayRegion functions. 1677d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes// - For swapped access, we use GetXArrayElements and our own copy-and-swap routines. 1687d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes// GetXArrayElements is disproportionately cheap on Dalvik because it doesn't copy (as opposed 1697d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes// to Hotspot, which always copies). The SWAP_FN copies and swaps in one pass, which is cheaper 1707d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes// than copying and then swapping in a second pass. Depending on future VM/GC changes, the 1717d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes// swapped case might need to be revisited. 1727d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes#define PEEKER(SCALAR_TYPE, JNI_NAME, SWAP_TYPE, SWAP_FN) { \ 1737d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes if (swap) { \ 1747d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes Scoped ## JNI_NAME ## ArrayRW elements(env, dst); \ 1757d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes if (elements.get() == NULL) { \ 1767d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes return; \ 1777d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes } \ 1787d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes const SWAP_TYPE* src = cast<const SWAP_TYPE*>(srcAddress); \ 1797d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes SWAP_FN(reinterpret_cast<SWAP_TYPE*>(elements.get()) + dstOffset, src, count); \ 1807d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes } else { \ 1817d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes const SCALAR_TYPE* src = cast<const SCALAR_TYPE*>(srcAddress); \ 1827d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes env->Set ## JNI_NAME ## ArrayRegion(dst, dstOffset, count, src); \ 1837d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes } \ 184961da1e7487bdb8ad8ac226d4f2789d003aa87b9Elliott Hughes} 185961da1e7487bdb8ad8ac226d4f2789d003aa87b9Elliott Hughes 1860121106d9dc1ba713b53822886355e4d9339e852Joel Dicestatic void Memory_peekCharArray(JNIEnv* env, jclass, jlong srcAddress, jcharArray dst, jint dstOffset, jint count, jboolean swap) { 1877d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes PEEKER(jchar, Char, jshort, swapShorts); 188961da1e7487bdb8ad8ac226d4f2789d003aa87b9Elliott Hughes} 189961da1e7487bdb8ad8ac226d4f2789d003aa87b9Elliott Hughes 1900121106d9dc1ba713b53822886355e4d9339e852Joel Dicestatic void Memory_peekDoubleArray(JNIEnv* env, jclass, jlong srcAddress, jdoubleArray dst, jint dstOffset, jint count, jboolean swap) { 1917d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes PEEKER(jdouble, Double, jlong, swapLongs); 192961da1e7487bdb8ad8ac226d4f2789d003aa87b9Elliott Hughes} 193961da1e7487bdb8ad8ac226d4f2789d003aa87b9Elliott Hughes 1940121106d9dc1ba713b53822886355e4d9339e852Joel Dicestatic void Memory_peekFloatArray(JNIEnv* env, jclass, jlong srcAddress, jfloatArray dst, jint dstOffset, jint count, jboolean swap) { 1957d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes PEEKER(jfloat, Float, jint, swapInts); 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1980121106d9dc1ba713b53822886355e4d9339e852Joel Dicestatic void Memory_peekIntArray(JNIEnv* env, jclass, jlong srcAddress, jintArray dst, jint dstOffset, jint count, jboolean swap) { 1997d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes PEEKER(jint, Int, jint, swapInts); 200961da1e7487bdb8ad8ac226d4f2789d003aa87b9Elliott Hughes} 201961da1e7487bdb8ad8ac226d4f2789d003aa87b9Elliott Hughes 2020121106d9dc1ba713b53822886355e4d9339e852Joel Dicestatic void Memory_peekLongArray(JNIEnv* env, jclass, jlong srcAddress, jlongArray dst, jint dstOffset, jint count, jboolean swap) { 2037d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes PEEKER(jlong, Long, jlong, swapLongs); 2047d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes} 2057d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes 2060121106d9dc1ba713b53822886355e4d9339e852Joel Dicestatic void Memory_peekShortArray(JNIEnv* env, jclass, jlong srcAddress, jshortArray dst, jint dstOffset, jint count, jboolean swap) { 2077d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes PEEKER(jshort, Short, jshort, swapShorts); 208961da1e7487bdb8ad8ac226d4f2789d003aa87b9Elliott Hughes} 209961da1e7487bdb8ad8ac226d4f2789d003aa87b9Elliott Hughes 2100121106d9dc1ba713b53822886355e4d9339e852Joel Dicestatic void Memory_pokeByte(JNIEnv*, jclass, jlong dstAddress, jbyte value) { 211034db7d210969f6e516d347810695633d063eb4bElliott Hughes *cast<jbyte*>(dstAddress) = value; 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2140121106d9dc1ba713b53822886355e4d9339e852Joel Dicestatic void Memory_pokeByteArray(JNIEnv* env, jclass, jlong dstAddress, jbyteArray src, jint offset, jint length) { 215034db7d210969f6e516d347810695633d063eb4bElliott Hughes env->GetByteArrayRegion(src, offset, length, cast<jbyte*>(dstAddress)); 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2187d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes// Implements the pokeXArray methods: 2197d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes// - For unswapped access, we just use the JNI GetXArrayRegion functions. 2207d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes// - For swapped access, we use GetXArrayElements and our own copy-and-swap routines. 2217d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes// GetXArrayElements is disproportionately cheap on Dalvik because it doesn't copy (as opposed 2227d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes// to Hotspot, which always copies). The SWAP_FN copies and swaps in one pass, which is cheaper 2237d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes// than copying and then swapping in a second pass. Depending on future VM/GC changes, the 2247d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes// swapped case might need to be revisited. 2257d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes#define POKER(SCALAR_TYPE, JNI_NAME, SWAP_TYPE, SWAP_FN) { \ 2267d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes if (swap) { \ 2277d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes Scoped ## JNI_NAME ## ArrayRO elements(env, src); \ 2287d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes if (elements.get() == NULL) { \ 2297d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes return; \ 2307d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes } \ 2317d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes const SWAP_TYPE* src = reinterpret_cast<const SWAP_TYPE*>(elements.get()) + srcOffset; \ 2327d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes SWAP_FN(cast<SWAP_TYPE*>(dstAddress), src, count); \ 2337d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes } else { \ 2347d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes env->Get ## JNI_NAME ## ArrayRegion(src, srcOffset, count, cast<SCALAR_TYPE*>(dstAddress)); \ 2357d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes } \ 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2380121106d9dc1ba713b53822886355e4d9339e852Joel Dicestatic void Memory_pokeCharArray(JNIEnv* env, jclass, jlong dstAddress, jcharArray src, jint srcOffset, jint count, jboolean swap) { 2397d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes POKER(jchar, Char, jshort, swapShorts); 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2420121106d9dc1ba713b53822886355e4d9339e852Joel Dicestatic void Memory_pokeDoubleArray(JNIEnv* env, jclass, jlong dstAddress, jdoubleArray src, jint srcOffset, jint count, jboolean swap) { 2437d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes POKER(jdouble, Double, jlong, swapLongs); 244692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes} 245692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes 2460121106d9dc1ba713b53822886355e4d9339e852Joel Dicestatic void Memory_pokeFloatArray(JNIEnv* env, jclass, jlong dstAddress, jfloatArray src, jint srcOffset, jint count, jboolean swap) { 2477d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes POKER(jfloat, Float, jint, swapInts); 248692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes} 249692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes 2500121106d9dc1ba713b53822886355e4d9339e852Joel Dicestatic void Memory_pokeIntArray(JNIEnv* env, jclass, jlong dstAddress, jintArray src, jint srcOffset, jint count, jboolean swap) { 2517d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes POKER(jint, Int, jint, swapInts); 252692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes} 253692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes 2540121106d9dc1ba713b53822886355e4d9339e852Joel Dicestatic void Memory_pokeLongArray(JNIEnv* env, jclass, jlong dstAddress, jlongArray src, jint srcOffset, jint count, jboolean swap) { 2557d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes POKER(jlong, Long, jlong, swapLongs); 2567d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes} 257692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes 2580121106d9dc1ba713b53822886355e4d9339e852Joel Dicestatic void Memory_pokeShortArray(JNIEnv* env, jclass, jlong dstAddress, jshortArray src, jint srcOffset, jint count, jboolean swap) { 2597d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes POKER(jshort, Short, jshort, swapShorts); 260bfb0099cc4c8eca744eeda0f20e5b3644f1a4cb9Owen Lin} 261bfb0099cc4c8eca744eeda0f20e5b3644f1a4cb9Owen Lin 262329af9cb39b3cd325a6ac6d1bc906af8877eff9fVladimir Markostatic jshort Memory_peekShortNative(JNIEnv*, jclass, jlong srcAddress) { 263329af9cb39b3cd325a6ac6d1bc906af8877eff9fVladimir Marko return *cast<const jshort*>(srcAddress); 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 266329af9cb39b3cd325a6ac6d1bc906af8877eff9fVladimir Markostatic void Memory_pokeShortNative(JNIEnv*, jclass, jlong dstAddress, jshort value) { 2677d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes *cast<jshort*>(dstAddress) = value; 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 270329af9cb39b3cd325a6ac6d1bc906af8877eff9fVladimir Markostatic jint Memory_peekIntNative(JNIEnv*, jclass, jlong srcAddress) { 271329af9cb39b3cd325a6ac6d1bc906af8877eff9fVladimir Marko return *cast<const jint*>(srcAddress); 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 274329af9cb39b3cd325a6ac6d1bc906af8877eff9fVladimir Markostatic void Memory_pokeIntNative(JNIEnv*, jclass, jlong dstAddress, jint value) { 2757d5299b162863ea898dd863004afe79f7a93fbceElliott Hughes *cast<jint*>(dstAddress) = value; 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 278329af9cb39b3cd325a6ac6d1bc906af8877eff9fVladimir Markostatic jlong Memory_peekLongNative(JNIEnv*, jclass, jlong srcAddress) { 2796116e6265924a0983bb462e3441c8c4a0bb7e47eElliott Hughes jlong result; 280b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman const jlong* src = cast<const jlong*>(srcAddress); 2816116e6265924a0983bb462e3441c8c4a0bb7e47eElliott Hughes if ((srcAddress & LONG_ALIGNMENT_MASK) == 0) { 282b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman result = *src; 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 284b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman result = get_unaligned<jlong>(src); 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2861b9018762e87e3dda69020248817011efd5a40dcElliott Hughes return result; 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 289329af9cb39b3cd325a6ac6d1bc906af8877eff9fVladimir Markostatic void Memory_pokeLongNative(JNIEnv*, jclass, jlong dstAddress, jlong value) { 290b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman jlong* dst = cast<jlong*>(dstAddress); 2916116e6265924a0983bb462e3441c8c4a0bb7e47eElliott Hughes if ((dstAddress & LONG_ALIGNMENT_MASK) == 0) { 292b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman *dst = value; 2936116e6265924a0983bb462e3441c8c4a0bb7e47eElliott Hughes } else { 294b7e0772d25499ddf5435e53a90cf1a6d753786d7Chris Dearman put_unaligned<jlong>(dst, value); 2951b9018762e87e3dda69020248817011efd5a40dcElliott Hughes } 296034db7d210969f6e516d347810695633d063eb4bElliott Hughes} 297034db7d210969f6e516d347810695633d063eb4bElliott Hughes 2988fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughesstatic void unsafeBulkCopy(jbyte* dst, const jbyte* src, jint byteCount, 2998fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes jint sizeofElement, jboolean swap) { 3008fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes if (!swap) { 3018fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes memcpy(dst, src, byteCount); 3028fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes return; 3038fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes } 3048fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes 3058fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes if (sizeofElement == 2) { 3068fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes jshort* dstShorts = reinterpret_cast<jshort*>(dst); 3078fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes const jshort* srcShorts = reinterpret_cast<const jshort*>(src); 3088fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes swapShorts(dstShorts, srcShorts, byteCount / 2); 3098fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes } else if (sizeofElement == 4) { 3108fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes jint* dstInts = reinterpret_cast<jint*>(dst); 3118fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes const jint* srcInts = reinterpret_cast<const jint*>(src); 3128fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes swapInts(dstInts, srcInts, byteCount / 4); 3138fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes } else if (sizeofElement == 8) { 3148fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes jlong* dstLongs = reinterpret_cast<jlong*>(dst); 3158fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes const jlong* srcLongs = reinterpret_cast<const jlong*>(src); 3168fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes swapLongs(dstLongs, srcLongs, byteCount / 8); 3178fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes } 3188fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes} 3198fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes 320f934c3d2c8dd9e6bc5299cef41adace2a671637dElliott Hughesstatic void Memory_unsafeBulkGet(JNIEnv* env, jclass, jobject dstObject, jint dstOffset, 3218fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes jint byteCount, jbyteArray srcArray, jint srcOffset, jint sizeofElement, jboolean swap) { 3228fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes ScopedByteArrayRO srcBytes(env, srcArray); 3236944bea4a129dc2d4be687c72f2a9f228ec532bcElliott Hughes if (srcBytes.get() == NULL) { 3246944bea4a129dc2d4be687c72f2a9f228ec532bcElliott Hughes return; 3256944bea4a129dc2d4be687c72f2a9f228ec532bcElliott Hughes } 3268fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes jarray dstArray = reinterpret_cast<jarray>(dstObject); 3276944bea4a129dc2d4be687c72f2a9f228ec532bcElliott Hughes jbyte* dstBytes = reinterpret_cast<jbyte*>(env->GetPrimitiveArrayCritical(dstArray, NULL)); 3286944bea4a129dc2d4be687c72f2a9f228ec532bcElliott Hughes if (dstBytes == NULL) { 3296944bea4a129dc2d4be687c72f2a9f228ec532bcElliott Hughes return; 3306944bea4a129dc2d4be687c72f2a9f228ec532bcElliott Hughes } 3318fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes jbyte* dst = dstBytes + dstOffset*sizeofElement; 3328fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes const jbyte* src = srcBytes.get() + srcOffset; 3338fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes unsafeBulkCopy(dst, src, byteCount, sizeofElement, swap); 3346944bea4a129dc2d4be687c72f2a9f228ec532bcElliott Hughes env->ReleasePrimitiveArrayCritical(dstArray, dstBytes, 0); 3356944bea4a129dc2d4be687c72f2a9f228ec532bcElliott Hughes} 3366944bea4a129dc2d4be687c72f2a9f228ec532bcElliott Hughes 337f934c3d2c8dd9e6bc5299cef41adace2a671637dElliott Hughesstatic void Memory_unsafeBulkPut(JNIEnv* env, jclass, jbyteArray dstArray, jint dstOffset, 3388fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes jint byteCount, jobject srcObject, jint srcOffset, jint sizeofElement, jboolean swap) { 3398fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes ScopedByteArrayRW dstBytes(env, dstArray); 3408fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes if (dstBytes.get() == NULL) { 3418fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes return; 3428fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes } 3438fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes jarray srcArray = reinterpret_cast<jarray>(srcObject); 3448fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes jbyte* srcBytes = reinterpret_cast<jbyte*>(env->GetPrimitiveArrayCritical(srcArray, NULL)); 3458fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes if (srcBytes == NULL) { 3468fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes return; 3478fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes } 3488fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes jbyte* dst = dstBytes.get() + dstOffset; 3498fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes const jbyte* src = srcBytes + srcOffset*sizeofElement; 3508fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes unsafeBulkCopy(dst, src, byteCount, sizeofElement, swap); 3518fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes env->ReleasePrimitiveArrayCritical(srcArray, srcBytes, 0); 3528fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes} 3538fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectstatic JNINativeMethod gMethods[] = { 3550568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes NATIVE_METHOD(Memory, memmove, "(Ljava/lang/Object;ILjava/lang/Object;IJ)V"), 3560121106d9dc1ba713b53822886355e4d9339e852Joel Dice NATIVE_METHOD(Memory, peekByte, "!(J)B"), 3570121106d9dc1ba713b53822886355e4d9339e852Joel Dice NATIVE_METHOD(Memory, peekByteArray, "(J[BII)V"), 3580121106d9dc1ba713b53822886355e4d9339e852Joel Dice NATIVE_METHOD(Memory, peekCharArray, "(J[CIIZ)V"), 3590121106d9dc1ba713b53822886355e4d9339e852Joel Dice NATIVE_METHOD(Memory, peekDoubleArray, "(J[DIIZ)V"), 3600121106d9dc1ba713b53822886355e4d9339e852Joel Dice NATIVE_METHOD(Memory, peekFloatArray, "(J[FIIZ)V"), 361329af9cb39b3cd325a6ac6d1bc906af8877eff9fVladimir Marko NATIVE_METHOD(Memory, peekIntNative, "!(J)I"), 3620121106d9dc1ba713b53822886355e4d9339e852Joel Dice NATIVE_METHOD(Memory, peekIntArray, "(J[IIIZ)V"), 363329af9cb39b3cd325a6ac6d1bc906af8877eff9fVladimir Marko NATIVE_METHOD(Memory, peekLongNative, "!(J)J"), 3640121106d9dc1ba713b53822886355e4d9339e852Joel Dice NATIVE_METHOD(Memory, peekLongArray, "(J[JIIZ)V"), 365329af9cb39b3cd325a6ac6d1bc906af8877eff9fVladimir Marko NATIVE_METHOD(Memory, peekShortNative, "!(J)S"), 3660121106d9dc1ba713b53822886355e4d9339e852Joel Dice NATIVE_METHOD(Memory, peekShortArray, "(J[SIIZ)V"), 3670121106d9dc1ba713b53822886355e4d9339e852Joel Dice NATIVE_METHOD(Memory, pokeByte, "!(JB)V"), 3680121106d9dc1ba713b53822886355e4d9339e852Joel Dice NATIVE_METHOD(Memory, pokeByteArray, "(J[BII)V"), 3690121106d9dc1ba713b53822886355e4d9339e852Joel Dice NATIVE_METHOD(Memory, pokeCharArray, "(J[CIIZ)V"), 3700121106d9dc1ba713b53822886355e4d9339e852Joel Dice NATIVE_METHOD(Memory, pokeDoubleArray, "(J[DIIZ)V"), 3710121106d9dc1ba713b53822886355e4d9339e852Joel Dice NATIVE_METHOD(Memory, pokeFloatArray, "(J[FIIZ)V"), 372329af9cb39b3cd325a6ac6d1bc906af8877eff9fVladimir Marko NATIVE_METHOD(Memory, pokeIntNative, "!(JI)V"), 3730121106d9dc1ba713b53822886355e4d9339e852Joel Dice NATIVE_METHOD(Memory, pokeIntArray, "(J[IIIZ)V"), 374329af9cb39b3cd325a6ac6d1bc906af8877eff9fVladimir Marko NATIVE_METHOD(Memory, pokeLongNative, "!(JJ)V"), 3750121106d9dc1ba713b53822886355e4d9339e852Joel Dice NATIVE_METHOD(Memory, pokeLongArray, "(J[JIIZ)V"), 376329af9cb39b3cd325a6ac6d1bc906af8877eff9fVladimir Marko NATIVE_METHOD(Memory, pokeShortNative, "!(JS)V"), 3770121106d9dc1ba713b53822886355e4d9339e852Joel Dice NATIVE_METHOD(Memory, pokeShortArray, "(J[SIIZ)V"), 378f934c3d2c8dd9e6bc5299cef41adace2a671637dElliott Hughes NATIVE_METHOD(Memory, unsafeBulkGet, "(Ljava/lang/Object;II[BIIZ)V"), 379f934c3d2c8dd9e6bc5299cef41adace2a671637dElliott Hughes NATIVE_METHOD(Memory, unsafeBulkPut, "([BIILjava/lang/Object;IIZ)V"), 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}; 3817cd6760f7045d771faae8080a8c6150bf678f679Elliott Hughesvoid register_libcore_io_Memory(JNIEnv* env) { 3827cd6760f7045d771faae8080a8c6150bf678f679Elliott Hughes jniRegisterNativeMethods(env, "libcore/io/Memory", gMethods, NELEM(gMethods)); 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 384