diff options
author | Elliott Hughes <enh@google.com> | 2013-03-01 11:31:03 -0800 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2013-03-01 11:31:03 -0800 |
commit | 09bcea1fd2a0bade07ab034352fde6c6ff6e01a6 (patch) | |
tree | a456d709061d365f27e80bb69b13b74eb21840c9 | |
parent | ff66631f0e038b56a9a7d84150b400da0d9b5785 (diff) | |
download | libcore-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.java | 10 | ||||
-rw-r--r-- | luni/src/main/native/Register.cpp | 1 | ||||
-rw-r--r-- | luni/src/main/native/sub.mk | 1 | ||||
-rw-r--r-- | luni/src/main/native/sun_misc_Unsafe.cpp | 31 | ||||
-rw-r--r-- | luni/src/test/java/sun/misc/UnsafeTest.java | 22 |
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()); + } } |