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 "common_throws.h" 18 #include "gc/accounting/card_table-inl.h" 19 #include "jni_internal.h" 20 #include "mirror/array.h" 21 #include "mirror/class.h" 22 #include "mirror/class-inl.h" 23 #include "mirror/object-inl.h" 24 #include "mirror/object_array-inl.h" 25 #include "scoped_thread_state_change.h" 26 27 /* 28 * We make guarantees about the atomicity of accesses to primitive 29 * variables. These guarantees also apply to elements of arrays. 30 * In particular, 8-bit, 16-bit, and 32-bit accesses must be atomic and 31 * must not cause "word tearing". Accesses to 64-bit array elements must 32 * either be atomic or treated as two 32-bit operations. References are 33 * always read and written atomically, regardless of the number of bits 34 * used to represent them. 35 * 36 * We can't rely on standard libc functions like memcpy(3) and memmove(3) 37 * in our implementation of System.arraycopy, because they may copy 38 * byte-by-byte (either for the full run or for "unaligned" parts at the 39 * start or end). We need to use functions that guarantee 16-bit or 32-bit 40 * atomicity as appropriate. 41 * 42 * System.arraycopy() is heavily used, so having an efficient implementation 43 * is important. The bionic libc provides a platform-optimized memory move 44 * function that should be used when possible. If it's not available, 45 * the trivial "reference implementation" versions below can be used until 46 * a proper version can be written. 47 * 48 * For these functions, The caller must guarantee that dst/src are aligned 49 * appropriately for the element type, and that n is a multiple of the 50 * element size. 51 */ 52 53 /* 54 * Works like memmove(), except: 55 * - if all arguments are at least 32-bit aligned, we guarantee that we 56 * will use operations that preserve atomicity of 32-bit values 57 * - if not, we guarantee atomicity of 16-bit values 58 * 59 * If all three arguments are not at least 16-bit aligned, the behavior 60 * of this function is undefined. (We could remove this restriction by 61 * testing for unaligned values and punting to memmove(), but that's 62 * not currently useful.) 63 * 64 * TODO: add loop for 64-bit alignment 65 * TODO: use __builtin_prefetch 66 * TODO: write ARM/MIPS/x86 optimized versions 67 */ 68 void MemmoveWords(void* dst, const void* src, size_t n) { 69 DCHECK_EQ((((uintptr_t) dst | (uintptr_t) src | n) & 0x01), 0U); 70 71 char* d = reinterpret_cast<char*>(dst); 72 const char* s = reinterpret_cast<const char*>(src); 73 size_t copyCount; 74 75 // If the source and destination pointers are the same, this is 76 // an expensive no-op. Testing for an empty move now allows us 77 // to skip a check later. 78 if (n == 0 || d == s) { 79 return; 80 } 81 82 // Determine if the source and destination buffers will overlap if 83 // we copy data forward (i.e. *dst++ = *src++). 84 // 85 // It's okay if the destination buffer starts before the source and 86 // there is some overlap, because the reader is always ahead of the 87 // writer. 88 if (LIKELY((d < s) || ((size_t)(d - s) >= n))) { 89 // Copy forward. We prefer 32-bit loads and stores even for 16-bit 90 // data, so sort that out. 91 if (((reinterpret_cast<uintptr_t>(d) | reinterpret_cast<uintptr_t>(s)) & 0x03) != 0) { 92 // Not 32-bit aligned. Two possibilities: 93 // (1) Congruent, we can align to 32-bit by copying one 16-bit val 94 // (2) Non-congruent, we can do one of: 95 // a. copy whole buffer as a series of 16-bit values 96 // b. load/store 32 bits, using shifts to ensure alignment 97 // c. just copy the as 32-bit values and assume the CPU 98 // will do a reasonable job 99 // 100 // We're currently using (a), which is suboptimal. 101 if (((reinterpret_cast<uintptr_t>(d) ^ reinterpret_cast<uintptr_t>(s)) & 0x03) != 0) { 102 copyCount = n; 103 } else { 104 copyCount = 2; 105 } 106 n -= copyCount; 107 copyCount /= sizeof(uint16_t); 108 109 while (copyCount--) { 110 *reinterpret_cast<uint16_t*>(d) = *reinterpret_cast<const uint16_t*>(s); 111 d += sizeof(uint16_t); 112 s += sizeof(uint16_t); 113 } 114 } 115 116 // Copy 32-bit aligned words. 117 copyCount = n / sizeof(uint32_t); 118 while (copyCount--) { 119 *reinterpret_cast<uint32_t*>(d) = *reinterpret_cast<const uint32_t*>(s); 120 d += sizeof(uint32_t); 121 s += sizeof(uint32_t); 122 } 123 124 // Check for leftovers. Either we finished exactly, or we have one remaining 16-bit chunk. 125 if ((n & 0x02) != 0) { 126 *reinterpret_cast<uint16_t*>(d) = *reinterpret_cast<const uint16_t*>(s); 127 } 128 } else { 129 // Copy backward, starting at the end. 130 d += n; 131 s += n; 132 133 if (((reinterpret_cast<uintptr_t>(d) | reinterpret_cast<uintptr_t>(s)) & 0x03) != 0) { 134 // try for 32-bit alignment. 135 if (((reinterpret_cast<uintptr_t>(d) ^ reinterpret_cast<uintptr_t>(s)) & 0x03) != 0) { 136 copyCount = n; 137 } else { 138 copyCount = 2; 139 } 140 n -= copyCount; 141 copyCount /= sizeof(uint16_t); 142 143 while (copyCount--) { 144 d -= sizeof(uint16_t); 145 s -= sizeof(uint16_t); 146 *reinterpret_cast<uint16_t*>(d) = *reinterpret_cast<const uint16_t*>(s); 147 } 148 } 149 150 // Copy 32-bit aligned words. 151 copyCount = n / sizeof(uint32_t); 152 while (copyCount--) { 153 d -= sizeof(uint32_t); 154 s -= sizeof(uint32_t); 155 *reinterpret_cast<uint32_t*>(d) = *reinterpret_cast<const uint32_t*>(s); 156 } 157 158 // Copy leftovers. 159 if ((n & 0x02) != 0) { 160 d -= sizeof(uint16_t); 161 s -= sizeof(uint16_t); 162 *reinterpret_cast<uint16_t*>(d) = *reinterpret_cast<const uint16_t*>(s); 163 } 164 } 165 } 166 167 #define move16 MemmoveWords 168 #define move32 MemmoveWords 169 170 namespace art { 171 172 static void ThrowArrayStoreException_NotAnArray(const char* identifier, mirror::Object* array) 173 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 174 std::string actualType(PrettyTypeOf(array)); 175 Thread* self = Thread::Current(); 176 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 177 self->ThrowNewExceptionF(throw_location, "Ljava/lang/ArrayStoreException;", 178 "%s of type %s is not an array", identifier, actualType.c_str()); 179 } 180 181 static void System_arraycopy(JNIEnv* env, jclass, jobject javaSrc, jint srcPos, jobject javaDst, jint dstPos, jint length) { 182 ScopedObjectAccess soa(env); 183 184 // Null pointer checks. 185 if (UNLIKELY(javaSrc == NULL)) { 186 ThrowNullPointerException(NULL, "src == null"); 187 return; 188 } 189 if (UNLIKELY(javaDst == NULL)) { 190 ThrowNullPointerException(NULL, "dst == null"); 191 return; 192 } 193 194 // Make sure source and destination are both arrays. 195 mirror::Object* srcObject = soa.Decode<mirror::Object*>(javaSrc); 196 mirror::Object* dstObject = soa.Decode<mirror::Object*>(javaDst); 197 if (UNLIKELY(!srcObject->IsArrayInstance())) { 198 ThrowArrayStoreException_NotAnArray("source", srcObject); 199 return; 200 } 201 if (UNLIKELY(!dstObject->IsArrayInstance())) { 202 ThrowArrayStoreException_NotAnArray("destination", dstObject); 203 return; 204 } 205 mirror::Array* srcArray = srcObject->AsArray(); 206 mirror::Array* dstArray = dstObject->AsArray(); 207 mirror::Class* srcComponentType = srcArray->GetClass()->GetComponentType(); 208 mirror::Class* dstComponentType = dstArray->GetClass()->GetComponentType(); 209 210 // Bounds checking. 211 if (UNLIKELY(srcPos < 0 || dstPos < 0 || length < 0 || srcPos > srcArray->GetLength() - length || dstPos > dstArray->GetLength() - length)) { 212 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow(); 213 soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/ArrayIndexOutOfBoundsException;", 214 "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d", 215 srcArray->GetLength(), srcPos, dstArray->GetLength(), dstPos, length); 216 return; 217 } 218 219 // Handle primitive arrays. 220 if (srcComponentType->IsPrimitive() || dstComponentType->IsPrimitive()) { 221 // If one of the arrays holds a primitive type the other array must hold the exact same type. 222 if (UNLIKELY(srcComponentType != dstComponentType)) { 223 std::string srcType(PrettyTypeOf(srcArray)); 224 std::string dstType(PrettyTypeOf(dstArray)); 225 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow(); 226 soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/ArrayStoreException;", 227 "Incompatible types: src=%s, dst=%s", 228 srcType.c_str(), dstType.c_str()); 229 return; 230 } 231 232 size_t width = srcArray->GetClass()->GetComponentSize(); 233 uint8_t* dstBytes = reinterpret_cast<uint8_t*>(dstArray->GetRawData(width)); 234 const uint8_t* srcBytes = reinterpret_cast<const uint8_t*>(srcArray->GetRawData(width)); 235 236 switch (width) { 237 case 1: 238 memmove(dstBytes + dstPos, srcBytes + srcPos, length); 239 break; 240 case 2: 241 move16(dstBytes + dstPos * 2, srcBytes + srcPos * 2, length * 2); 242 break; 243 case 4: 244 move32(dstBytes + dstPos * 4, srcBytes + srcPos * 4, length * 4); 245 break; 246 case 8: 247 // We don't need to guarantee atomicity of the entire 64-bit word. 248 move32(dstBytes + dstPos * 8, srcBytes + srcPos * 8, length * 8); 249 break; 250 default: 251 LOG(FATAL) << "Unknown primitive array type: " << PrettyTypeOf(srcArray); 252 } 253 254 return; 255 } 256 257 // Neither class is primitive. Are the types trivially compatible? 258 const size_t width = sizeof(mirror::Object*); 259 uint8_t* dstBytes = reinterpret_cast<uint8_t*>(dstArray->GetRawData(width)); 260 const uint8_t* srcBytes = reinterpret_cast<const uint8_t*>(srcArray->GetRawData(width)); 261 if (dstArray == srcArray || dstComponentType->IsAssignableFrom(srcComponentType)) { 262 // Yes. Bulk copy. 263 COMPILE_ASSERT(sizeof(width) == sizeof(uint32_t), move32_assumes_Object_references_are_32_bit); 264 move32(dstBytes + dstPos * width, srcBytes + srcPos * width, length * width); 265 Runtime::Current()->GetHeap()->WriteBarrierArray(dstArray, dstPos, length); 266 return; 267 } 268 269 // The arrays are not trivially compatible. However, we may still be able to copy some or all of 270 // the elements if the source objects are compatible (for example, copying an Object[] to 271 // String[], the Objects being copied might actually be Strings). 272 // We can't do a bulk move because that would introduce a check-use race condition, so we copy 273 // elements one by one. 274 275 // We already dealt with overlapping copies, so we don't need to cope with that case below. 276 CHECK_NE(dstArray, srcArray); 277 278 mirror::Object* const * srcObjects = 279 reinterpret_cast<mirror::Object* const *>(srcBytes + srcPos * width); 280 mirror::Object** dstObjects = reinterpret_cast<mirror::Object**>(dstBytes + dstPos * width); 281 mirror::Class* dstClass = dstArray->GetClass()->GetComponentType(); 282 283 // We want to avoid redundant IsAssignableFrom checks where possible, so we cache a class that 284 // we know is assignable to the destination array's component type. 285 mirror::Class* lastAssignableElementClass = dstClass; 286 287 mirror::Object* o = NULL; 288 int i = 0; 289 for (; i < length; ++i) { 290 o = srcObjects[i]; 291 if (o != NULL) { 292 mirror::Class* oClass = o->GetClass(); 293 if (lastAssignableElementClass == oClass) { 294 dstObjects[i] = o; 295 } else if (dstClass->IsAssignableFrom(oClass)) { 296 lastAssignableElementClass = oClass; 297 dstObjects[i] = o; 298 } else { 299 // Can't put this element into the array. 300 break; 301 } 302 } else { 303 dstObjects[i] = NULL; 304 } 305 } 306 307 Runtime::Current()->GetHeap()->WriteBarrierArray(dstArray, dstPos, length); 308 if (UNLIKELY(i != length)) { 309 std::string actualSrcType(PrettyTypeOf(o)); 310 std::string dstType(PrettyTypeOf(dstArray)); 311 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow(); 312 soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/ArrayStoreException;", 313 "source[%d] of type %s cannot be stored in destination array of type %s", 314 srcPos + i, actualSrcType.c_str(), dstType.c_str()); 315 return; 316 } 317 } 318 319 static jint System_identityHashCode(JNIEnv* env, jclass, jobject javaObject) { 320 ScopedObjectAccess soa(env); 321 mirror::Object* o = soa.Decode<mirror::Object*>(javaObject); 322 return static_cast<jint>(o->IdentityHashCode()); 323 } 324 325 static JNINativeMethod gMethods[] = { 326 NATIVE_METHOD(System, arraycopy, "(Ljava/lang/Object;ILjava/lang/Object;II)V"), 327 NATIVE_METHOD(System, identityHashCode, "(Ljava/lang/Object;)I"), 328 }; 329 330 void register_java_lang_System(JNIEnv* env) { 331 REGISTER_NATIVE_METHODS("java/lang/System"); 332 } 333 334 } // namespace art 335