diff --git a/runtime/native/OpenjdkJvm.cc b/runtime/native/OpenjdkJvm.cc
index 25f1c55..24155da 100644
--- a/runtime/native/OpenjdkJvm.cc
+++ b/runtime/native/OpenjdkJvm.cc
@@ -462,130 +462,21 @@
   }
 }
 
-JNIEXPORT jint JVM_IHashCode(JNIEnv* env, jobject javaObject) {
-  if (UNLIKELY(javaObject == nullptr)) {
-    return 0;
-  }
-  art::ScopedFastNativeObjectAccess soa(env);
-  art::mirror::Object* o = soa.Decode<art::mirror::Object*>(javaObject);
-  return static_cast<jint>(o->IdentityHashCode());
+JNIEXPORT jint JVM_IHashCode(JNIEnv* env ATTRIBUTE_UNUSED,
+                             jobject javaObject ATTRIBUTE_UNUSED) {
+  UNIMPLEMENTED(FATAL) << "JVM_IHashCode is not implemented";
+  return 0;
 }
 
 JNIEXPORT jlong JVM_NanoTime(JNIEnv* env ATTRIBUTE_UNUSED, jclass unused ATTRIBUTE_UNUSED) {
-  timespec now;
-  clock_gettime(CLOCK_MONOTONIC, &now);
-  return now.tv_sec * 1000000000LL + now.tv_nsec;
+  UNIMPLEMENTED(FATAL) << "JVM_NanoTime is not implemented";
+  return 0L;
 }
 
-static void ThrowArrayStoreException_NotAnArray(const char* identifier, art::mirror::Object* array)
-    SHARED_LOCKS_REQUIRED(art::Locks::mutator_lock_) {
-  std::string actualType(art::PrettyTypeOf(array));
-  art::Thread* self = art::Thread::Current();
-  self->ThrowNewExceptionF("Ljava/lang/ArrayStoreException;",
-                           "%s of type %s is not an array", identifier, actualType.c_str());
-}
-
-JNIEXPORT void JVM_ArrayCopy(JNIEnv* env, jclass unused ATTRIBUTE_UNUSED, jobject javaSrc,
-                             jint srcPos, jobject javaDst, jint dstPos, jint length) {
-  // The API is defined in terms of length, but length is somewhat overloaded so we use count.
-  const jint count = length;
-  art::ScopedFastNativeObjectAccess soa(env);
-
-  // Null pointer checks.
-  if (UNLIKELY(javaSrc == nullptr)) {
-    art::ThrowNullPointerException("src == null");
-    return;
-  }
-  if (UNLIKELY(javaDst == nullptr)) {
-    art::ThrowNullPointerException("dst == null");
-    return;
-  }
-
-  // Make sure source and destination are both arrays.
-  art::mirror::Object* srcObject = soa.Decode<art::mirror::Object*>(javaSrc);
-  if (UNLIKELY(!srcObject->IsArrayInstance())) {
-    ThrowArrayStoreException_NotAnArray("source", srcObject);
-    return;
-  }
-  art::mirror::Object* dstObject = soa.Decode<art::mirror::Object*>(javaDst);
-  if (UNLIKELY(!dstObject->IsArrayInstance())) {
-    ThrowArrayStoreException_NotAnArray("destination", dstObject);
-    return;
-  }
-  art::mirror::Array* srcArray = srcObject->AsArray();
-  art::mirror::Array* dstArray = dstObject->AsArray();
-
-  // Bounds checking.
-  if (UNLIKELY(srcPos < 0) || UNLIKELY(dstPos < 0) || UNLIKELY(count < 0) ||
-      UNLIKELY(srcPos > srcArray->GetLength() - count) ||
-      UNLIKELY(dstPos > dstArray->GetLength() - count)) {
-    soa.Self()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
-                                   "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d",
-                                   srcArray->GetLength(), srcPos, dstArray->GetLength(), dstPos,
-                                   count);
-    return;
-  }
-
-  art::mirror::Class* dstComponentType = dstArray->GetClass()->GetComponentType();
-  art::mirror::Class* srcComponentType = srcArray->GetClass()->GetComponentType();
-  art::Primitive::Type dstComponentPrimitiveType = dstComponentType->GetPrimitiveType();
-
-  if (LIKELY(srcComponentType == dstComponentType)) {
-    // Trivial assignability.
-    switch (dstComponentPrimitiveType) {
-      case art::Primitive::kPrimVoid:
-        LOG(FATAL) << "Unreachable, cannot have arrays of type void";
-        return;
-      case art::Primitive::kPrimBoolean:
-      case art::Primitive::kPrimByte:
-        DCHECK_EQ(art::Primitive::ComponentSize(dstComponentPrimitiveType), 1U);
-        dstArray->AsByteSizedArray()->Memmove(dstPos, srcArray->AsByteSizedArray(), srcPos, count);
-        return;
-      case art::Primitive::kPrimChar:
-      case art::Primitive::kPrimShort:
-        DCHECK_EQ(art::Primitive::ComponentSize(dstComponentPrimitiveType), 2U);
-        dstArray->AsShortSizedArray()->Memmove(dstPos, srcArray->AsShortSizedArray(), srcPos, count);
-        return;
-      case art::Primitive::kPrimInt:
-      case art::Primitive::kPrimFloat:
-        DCHECK_EQ(art::Primitive::ComponentSize(dstComponentPrimitiveType), 4U);
-        dstArray->AsIntArray()->Memmove(dstPos, srcArray->AsIntArray(), srcPos, count);
-        return;
-      case art::Primitive::kPrimLong:
-      case art::Primitive::kPrimDouble:
-        DCHECK_EQ(art::Primitive::ComponentSize(dstComponentPrimitiveType), 8U);
-        dstArray->AsLongArray()->Memmove(dstPos, srcArray->AsLongArray(), srcPos, count);
-        return;
-      case art::Primitive::kPrimNot: {
-        art::mirror::ObjectArray<art::mirror::Object>* dstObjArray = dstArray->AsObjectArray<art::mirror::Object>();
-        art::mirror::ObjectArray<art::mirror::Object>* srcObjArray = srcArray->AsObjectArray<art::mirror::Object>();
-        dstObjArray->AssignableMemmove(dstPos, srcObjArray, srcPos, count);
-        return;
-      }
-      default:
-        LOG(FATAL) << "Unknown array type: " << art::PrettyTypeOf(srcArray);
-        return;
-    }
-  }
-  // If one of the arrays holds a primitive type the other array must hold the exact same type.
-  if (UNLIKELY((dstComponentPrimitiveType != art::Primitive::kPrimNot) ||
-               srcComponentType->IsPrimitive())) {
-    std::string srcType(art::PrettyTypeOf(srcArray));
-    std::string dstType(art::PrettyTypeOf(dstArray));
-    soa.Self()->ThrowNewExceptionF("Ljava/lang/ArrayStoreException;",
-                                   "Incompatible types: src=%s, dst=%s",
-                                   srcType.c_str(), dstType.c_str());
-    return;
-  }
-  // Arrays hold distinct types and so therefore can't alias - use memcpy instead of memmove.
-  art::mirror::ObjectArray<art::mirror::Object>* dstObjArray = dstArray->AsObjectArray<art::mirror::Object>();
-  art::mirror::ObjectArray<art::mirror::Object>* srcObjArray = srcArray->AsObjectArray<art::mirror::Object>();
-  // If we're assigning into say Object[] then we don't need per element checks.
-  if (dstComponentType->IsAssignableFrom(srcComponentType)) {
-    dstObjArray->AssignableMemcpy(dstPos, srcObjArray, srcPos, count);
-    return;
-  }
-  dstObjArray->AssignableCheckingMemcpy(dstPos, srcObjArray, srcPos, count, true);
+JNIEXPORT void JVM_ArrayCopy(JNIEnv* /* env */, jclass /* unused */, jobject /* javaSrc */,
+                             jint /* srcPos */, jobject /* javaDst */, jint /* dstPos */,
+                             jint /* length */) {
+  UNIMPLEMENTED(FATAL) << "JVM_ArrayCopy is not implemented";
 }
 
 JNIEXPORT jint JVM_FindSignal(const char* name ATTRIBUTE_UNUSED) {
diff --git a/runtime/native/java_lang_System.cc b/runtime/native/java_lang_System.cc
index 5447275..736b42b 100644
--- a/runtime/native/java_lang_System.cc
+++ b/runtime/native/java_lang_System.cc
@@ -28,6 +28,124 @@
 
 namespace art {
 
+/*
+ * We make guarantees about the atomicity of accesses to primitive variables.  These guarantees
+ * also apply to elements of arrays. In particular, 8-bit, 16-bit, and 32-bit accesses must not
+ * cause "word tearing".  Accesses to 64-bit array elements may be two 32-bit operations.
+ * References are never torn regardless of the number of bits used to represent them.
+ */
+
+static void ThrowArrayStoreException_NotAnArray(const char* identifier, mirror::Object* array)
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  std::string actualType(PrettyTypeOf(array));
+  Thread* self = Thread::Current();
+  self->ThrowNewExceptionF("Ljava/lang/ArrayStoreException;",
+                           "%s of type %s is not an array", identifier, actualType.c_str());
+}
+
+static void System_arraycopy(JNIEnv* env, jclass, jobject javaSrc, jint srcPos, jobject javaDst,
+                             jint dstPos, jint length) {
+  // The API is defined in terms of length, but length is somewhat overloaded so we use count.
+  const jint count = length;
+  ScopedFastNativeObjectAccess soa(env);
+
+  // Null pointer checks.
+  if (UNLIKELY(javaSrc == nullptr)) {
+    ThrowNullPointerException("src == null");
+    return;
+  }
+  if (UNLIKELY(javaDst == nullptr)) {
+    ThrowNullPointerException("dst == null");
+    return;
+  }
+
+  // Make sure source and destination are both arrays.
+  mirror::Object* srcObject = soa.Decode<mirror::Object*>(javaSrc);
+  if (UNLIKELY(!srcObject->IsArrayInstance())) {
+    ThrowArrayStoreException_NotAnArray("source", srcObject);
+    return;
+  }
+  mirror::Object* dstObject = soa.Decode<mirror::Object*>(javaDst);
+  if (UNLIKELY(!dstObject->IsArrayInstance())) {
+    ThrowArrayStoreException_NotAnArray("destination", dstObject);
+    return;
+  }
+  mirror::Array* srcArray = srcObject->AsArray();
+  mirror::Array* dstArray = dstObject->AsArray();
+
+  // Bounds checking.
+  if (UNLIKELY(srcPos < 0) || UNLIKELY(dstPos < 0) || UNLIKELY(count < 0) ||
+      UNLIKELY(srcPos > srcArray->GetLength() - count) ||
+      UNLIKELY(dstPos > dstArray->GetLength() - count)) {
+    soa.Self()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
+                                   "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d",
+                                   srcArray->GetLength(), srcPos, dstArray->GetLength(), dstPos,
+                                   count);
+    return;
+  }
+
+  mirror::Class* dstComponentType = dstArray->GetClass()->GetComponentType();
+  mirror::Class* srcComponentType = srcArray->GetClass()->GetComponentType();
+  Primitive::Type dstComponentPrimitiveType = dstComponentType->GetPrimitiveType();
+
+  if (LIKELY(srcComponentType == dstComponentType)) {
+    // Trivial assignability.
+    switch (dstComponentPrimitiveType) {
+      case Primitive::kPrimVoid:
+        LOG(FATAL) << "Unreachable, cannot have arrays of type void";
+        UNREACHABLE();
+      case Primitive::kPrimBoolean:
+      case Primitive::kPrimByte:
+        DCHECK_EQ(Primitive::ComponentSize(dstComponentPrimitiveType), 1U);
+        dstArray->AsByteSizedArray()->Memmove(dstPos, srcArray->AsByteSizedArray(), srcPos, count);
+        return;
+      case Primitive::kPrimChar:
+      case Primitive::kPrimShort:
+        DCHECK_EQ(Primitive::ComponentSize(dstComponentPrimitiveType), 2U);
+        dstArray->AsShortSizedArray()->Memmove(dstPos, srcArray->AsShortSizedArray(), srcPos, count);
+        return;
+      case Primitive::kPrimInt:
+      case Primitive::kPrimFloat:
+        DCHECK_EQ(Primitive::ComponentSize(dstComponentPrimitiveType), 4U);
+        dstArray->AsIntArray()->Memmove(dstPos, srcArray->AsIntArray(), srcPos, count);
+        return;
+      case Primitive::kPrimLong:
+      case Primitive::kPrimDouble:
+        DCHECK_EQ(Primitive::ComponentSize(dstComponentPrimitiveType), 8U);
+        dstArray->AsLongArray()->Memmove(dstPos, srcArray->AsLongArray(), srcPos, count);
+        return;
+      case Primitive::kPrimNot: {
+        mirror::ObjectArray<mirror::Object>* dstObjArray = dstArray->AsObjectArray<mirror::Object>();
+        mirror::ObjectArray<mirror::Object>* srcObjArray = srcArray->AsObjectArray<mirror::Object>();
+        dstObjArray->AssignableMemmove(dstPos, srcObjArray, srcPos, count);
+        return;
+      }
+      default:
+        LOG(FATAL) << "Unknown array type: " << PrettyTypeOf(srcArray);
+        UNREACHABLE();
+    }
+  }
+  // If one of the arrays holds a primitive type the other array must hold the exact same type.
+  if (UNLIKELY((dstComponentPrimitiveType != Primitive::kPrimNot) ||
+               srcComponentType->IsPrimitive())) {
+    std::string srcType(PrettyTypeOf(srcArray));
+    std::string dstType(PrettyTypeOf(dstArray));
+    soa.Self()->ThrowNewExceptionF("Ljava/lang/ArrayStoreException;",
+                                   "Incompatible types: src=%s, dst=%s",
+                                   srcType.c_str(), dstType.c_str());
+    return;
+  }
+  // Arrays hold distinct types and so therefore can't alias - use memcpy instead of memmove.
+  mirror::ObjectArray<mirror::Object>* dstObjArray = dstArray->AsObjectArray<mirror::Object>();
+  mirror::ObjectArray<mirror::Object>* srcObjArray = srcArray->AsObjectArray<mirror::Object>();
+  // If we're assigning into say Object[] then we don't need per element checks.
+  if (dstComponentType->IsAssignableFrom(srcComponentType)) {
+    dstObjArray->AssignableMemcpy(dstPos, srcObjArray, srcPos, count);
+    return;
+  }
+  dstObjArray->AssignableCheckingMemcpy(dstPos, srcObjArray, srcPos, count, true);
+}
+
 // Template to convert general array to that of its specific primitive type.
 template <typename T>
 inline T* AsPrimitiveArray(mirror::Array* array) {
@@ -97,7 +215,17 @@
       javaDst, dstPos, count);
 }
 
+static jint System_identityHashCode(JNIEnv* env, jclass, jobject javaObject) {
+  if (UNLIKELY(javaObject == nullptr)) {
+    return 0;
+  }
+  ScopedFastNativeObjectAccess soa(env);
+  mirror::Object* o = soa.Decode<mirror::Object*>(javaObject);
+  return static_cast<jint>(o->IdentityHashCode());
+}
+
 static JNINativeMethod gMethods[] = {
+  NATIVE_METHOD(System, arraycopy, "!(Ljava/lang/Object;ILjava/lang/Object;II)V"),
   NATIVE_METHOD(System, arraycopyCharUnchecked, "!([CI[CII)V"),
   NATIVE_METHOD(System, arraycopyByteUnchecked, "!([BI[BII)V"),
   NATIVE_METHOD(System, arraycopyShortUnchecked, "!([SI[SII)V"),
@@ -106,6 +234,7 @@
   NATIVE_METHOD(System, arraycopyFloatUnchecked, "!([FI[FII)V"),
   NATIVE_METHOD(System, arraycopyDoubleUnchecked, "!([DI[DII)V"),
   NATIVE_METHOD(System, arraycopyBooleanUnchecked, "!([ZI[ZII)V"),
+  NATIVE_METHOD(System, identityHashCode, "!(Ljava/lang/Object;)I"),
 };
 
 void register_java_lang_System(JNIEnv* env) {
