summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2013-03-01 11:31:03 -0800
committerElliott Hughes <enh@google.com>2013-03-01 11:31:03 -0800
commit09bcea1fd2a0bade07ab034352fde6c6ff6e01a6 (patch)
treea456d709061d365f27e80bb69b13b74eb21840c9
parentff66631f0e038b56a9a7d84150b400da0d9b5785 (diff)
downloadlibcore-09bcea1fd2a0bade07ab034352fde6c6ff6e01a6.zip
libcore-09bcea1fd2a0bade07ab034352fde6c6ff6e01a6.tar.gz
libcore-09bcea1fd2a0bade07ab034352fde6c6ff6e01a6.tar.bz2
Add Unsafe.allocateInstance.
At the moment, mockers are writing dalvik-specific code that pokes around with our internals and breaks when we change stuff. They're also supporting Unsafe so they can run on the RI. Everyone's better off if we just implement the missing Unsafe call. Bug: 8297640 Change-Id: Ib647e27d920be548009f26ced3b74bad7400a590
-rw-r--r--luni/src/main/java/sun/misc/Unsafe.java10
-rw-r--r--luni/src/main/native/Register.cpp1
-rw-r--r--luni/src/main/native/sub.mk1
-rw-r--r--luni/src/main/native/sun_misc_Unsafe.cpp31
-rw-r--r--luni/src/test/java/sun/misc/UnsafeTest.java22
5 files changed, 64 insertions, 1 deletions
diff --git a/luni/src/main/java/sun/misc/Unsafe.java b/luni/src/main/java/sun/misc/Unsafe.java
index 33bb9f1..884340b 100644
--- a/luni/src/main/java/sun/misc/Unsafe.java
+++ b/luni/src/main/java/sun/misc/Unsafe.java
@@ -27,8 +27,10 @@ import java.lang.reflect.Modifier;
* of Java.
*/
public final class Unsafe {
- /** non-null; unique instance of this class */
+ /** Traditional dalvik name. */
private static final Unsafe THE_ONE = new Unsafe();
+ /** Traditional RI name. */
+ private static final Unsafe theUnsafe = THE_ONE;
/**
* This class is only privately instantiable.
@@ -339,4 +341,10 @@ public final class Unsafe {
throw new IllegalArgumentException("valid for Threads only");
}
}
+
+ /**
+ * Allocates an instance of the given class without running the constructor.
+ * The class' <clinit> will be run, if necessary.
+ */
+ public native Object allocateInstance(Class<?> c);
}
diff --git a/luni/src/main/native/Register.cpp b/luni/src/main/native/Register.cpp
index 29866c7..c94cd5d 100644
--- a/luni/src/main/native/Register.cpp
+++ b/luni/src/main/native/Register.cpp
@@ -73,6 +73,7 @@ int JNI_OnLoad(JavaVM* vm, void*) {
REGISTER(register_org_apache_harmony_dalvik_NativeTestTarget);
REGISTER(register_org_apache_harmony_xml_ExpatParser);
REGISTER(register_org_apache_harmony_xnet_provider_jsse_NativeCrypto);
+ REGISTER(register_sun_misc_Unsafe);
#undef REGISTER
return JNI_VERSION_1_6;
}
diff --git a/luni/src/main/native/sub.mk b/luni/src/main/native/sub.mk
index 6622f7c..7ea5033 100644
--- a/luni/src/main/native/sub.mk
+++ b/luni/src/main/native/sub.mk
@@ -51,6 +51,7 @@ LOCAL_SRC_FILES := \
org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp \
readlink.cpp \
realpath.cpp \
+ sun_misc_Unsafe.cpp \
toStringArray.cpp \
valueOf.cpp
diff --git a/luni/src/main/native/sun_misc_Unsafe.cpp b/luni/src/main/native/sun_misc_Unsafe.cpp
new file mode 100644
index 0000000..d0a23be
--- /dev/null
+++ b/luni/src/main/native/sun_misc_Unsafe.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Unsafe"
+
+#include "JNIHelp.h"
+#include "JniConstants.h"
+
+static jobject Unsafe_allocateInstance(JNIEnv* env, jclass, jclass c) {
+ return env->AllocObject(c);
+}
+
+static JNINativeMethod gMethods[] = {
+ NATIVE_METHOD(Unsafe, allocateInstance, "(Ljava/lang/Class;)Ljava/lang/Object;"),
+};
+void register_sun_misc_Unsafe(JNIEnv* env) {
+ jniRegisterNativeMethods(env, "sun/misc/Unsafe", gMethods, NELEM(gMethods));
+}
diff --git a/luni/src/test/java/sun/misc/UnsafeTest.java b/luni/src/test/java/sun/misc/UnsafeTest.java
index 462d39d..48939f5 100644
--- a/luni/src/test/java/sun/misc/UnsafeTest.java
+++ b/luni/src/test/java/sun/misc/UnsafeTest.java
@@ -18,6 +18,7 @@ package sun.misc;
import junit.framework.TestCase;
+import java.lang.reflect.Field;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
@@ -48,4 +49,25 @@ public class UnsafeTest extends TestCase {
} catch (SecurityException expected) {
}
}
+
+ private class AllocateInstanceTestClass {
+ public int i = 123;
+ public String s = "hello";
+ public Object getThis() { return AllocateInstanceTestClass.this; }
+ }
+
+ private static Unsafe getUnsafe() throws Exception {
+ Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
+ Field f = unsafeClass.getDeclaredField("theUnsafe");
+ f.setAccessible(true);
+ return (Unsafe) f.get(null);
+ }
+
+ public void test_allocateInstance() throws Exception {
+ AllocateInstanceTestClass i = (AllocateInstanceTestClass)
+ getUnsafe().allocateInstance(AllocateInstanceTestClass.class);
+ assertEquals(0, i.i);
+ assertEquals(null, i.s);
+ assertEquals(i, i.getThis());
+ }
}