Support in VMRuntime for allocating "unpadded" arrays.
Bug: 13028925.
Change-Id: I0a53645f0468aaf44d38aabe016cb610fcfefaf7
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index 3da7409..754d1dd 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -46,6 +46,7 @@
return array_class;
}
}
+ DCHECK(!element_class->IsPrimitiveVoid());
std::string descriptor("[");
descriptor += ClassHelper(element_class).GetDescriptor();
SirtRef<mirror::ClassLoader> class_loader(self, element_class->GetClassLoader());
diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc
index 3c703ba..decbc66 100644
--- a/runtime/native/dalvik_system_VMRuntime.cc
+++ b/runtime/native/dalvik_system_VMRuntime.cc
@@ -56,13 +56,17 @@
static jobject VMRuntime_newNonMovableArray(JNIEnv* env, jobject, jclass javaElementClass,
jint length) {
ScopedFastNativeObjectAccess soa(env);
+ if (UNLIKELY(length < 0)) {
+ ThrowNegativeArraySizeException(length);
+ return nullptr;
+ }
mirror::Class* element_class = soa.Decode<mirror::Class*>(javaElementClass);
if (UNLIKELY(element_class == nullptr)) {
ThrowNullPointerException(NULL, "element class == null");
return nullptr;
}
- if (UNLIKELY(length < 0)) {
- ThrowNegativeArraySizeException(length);
+ if (UNLIKELY(element_class->IsPrimitiveVoid())) {
+ ThrowIllegalArgumentException(NULL, "Can't allocate an array of void");
return nullptr;
}
Runtime* runtime = Runtime::Current();
@@ -76,6 +80,34 @@
return soa.AddLocalReference<jobject>(result);
}
+static jobject VMRuntime_newUnpaddedArray(JNIEnv* env, jobject, jclass javaElementClass,
+ jint length) {
+ ScopedFastNativeObjectAccess soa(env);
+ if (UNLIKELY(length < 0)) {
+ ThrowNegativeArraySizeException(length);
+ return nullptr;
+ }
+ mirror::Class* element_class = soa.Decode<mirror::Class*>(javaElementClass);
+ if (UNLIKELY(element_class == nullptr)) {
+ ThrowNullPointerException(NULL, "element class == null");
+ return nullptr;
+ }
+ if (UNLIKELY(element_class->IsPrimitiveVoid())) {
+ ThrowIllegalArgumentException(NULL, "Can't allocate an array of void");
+ return nullptr;
+ }
+ Runtime* runtime = Runtime::Current();
+ mirror::Class* array_class = runtime->GetClassLinker()->FindArrayClass(soa.Self(), element_class);
+ if (UNLIKELY(array_class == nullptr)) {
+ return nullptr;
+ }
+ gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
+ mirror::Array* result = mirror::Array::Alloc<true>(soa.Self(), array_class, length,
+ array_class->GetComponentSize(), allocator,
+ true);
+ return soa.AddLocalReference<jobject>(result);
+}
+
static jlong VMRuntime_addressOf(JNIEnv* env, jobject, jobject javaArray) {
if (javaArray == NULL) { // Most likely allocation failed
return 0;
@@ -497,6 +529,7 @@
NATIVE_METHOD(VMRuntime, isDebuggerActive, "()Z"),
NATIVE_METHOD(VMRuntime, nativeSetTargetHeapUtilization, "(F)V"),
NATIVE_METHOD(VMRuntime, newNonMovableArray, "!(Ljava/lang/Class;I)Ljava/lang/Object;"),
+ NATIVE_METHOD(VMRuntime, newUnpaddedArray, "!(Ljava/lang/Class;I)Ljava/lang/Object;"),
NATIVE_METHOD(VMRuntime, properties, "()[Ljava/lang/String;"),
NATIVE_METHOD(VMRuntime, setTargetSdkVersionNative, "(I)V"),
NATIVE_METHOD(VMRuntime, registerNativeAllocation, "(I)V"),