Looks good with a few comments.<br><br><div class="gmail_quote">On Wed, Nov 16, 2011 at 12:17 AM, Will Dietz <span dir="ltr"><<a href="mailto:wdietz2@illinois.edu">wdietz2@illinois.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Inlined below.<br>
<br>
Thanks! :)<br>
<br>
~Will<br>
<br>
>From 3ace0392fcfffe9398c876e5921e79b9f349c53a Mon Sep 17 00:00:00 2001<br>
From: Will Dietz <<a href="mailto:w@wdtz.org">w@wdtz.org</a>><br>
Date: Tue, 15 Nov 2011 17:01:39 -0600<br>
Subject: [PATCH 3/3] Define all methods in sun.misc.Unsafe, fixes to<br>
existing.<br>
<br>
* Add full set of get/put, including volatile and ordered. Update existing<br>
volatile to use memory barrier on writes.<br>
* Fix all get/put to make use of fieldPtr, thereby correctly handling both<br>
staticInstances as well as throwing null pointer exceptions.<br>
* Add memory methods: memcpy, memset, realloc<br>
* Add empty park/unpark methods. (Very) inefficient, but these methods are<br>
allowed to return arbitrarily, so this is allowed and gets code going.<br>
* Add misc query functions (pageSize/addressSize/etc)<br>
* Drop NATIVE_JNI in this file, while we're at it.<br>
<br>
The functions that I've never seen called still have UNIMPLEMENTED,<br>
the rest have been used in 'real' code and seem to work fine.<br>
Only exception to this is the putOrdered variants.<br>
---<br>
lib/J3/ClassLib/Unsafe.inc | 273 ++++++++++++++++++++++++++++++++++++-------<br>
1 files changed, 228 insertions(+), 45 deletions(-)<br>
<br>
diff --git a/lib/J3/ClassLib/Unsafe.inc b/lib/J3/ClassLib/Unsafe.inc<br>
index 5fe64db..240d0ec 100644<br>
--- a/lib/J3/ClassLib/Unsafe.inc<br>
+++ b/lib/J3/ClassLib/Unsafe.inc<br>
@@ -102,9 +102,6 @@ JavaObject* unsafe, JavaObject* clazz) {<br>
/// objectFieldOffset - Pointer offset of the specified field<br>
///<br>
JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_objectFieldOffset(<br>
-#ifdef NATIVE_JNI<br>
-JNIEnv *env,<br>
-#endif<br>
JavaObject* Unsafe, JavaObjectField* Field) {<br>
<br>
llvm_gcroot(Field, 0);<br>
@@ -136,19 +133,110 @@ JavaObject* unsafe, JavaObject* base, jlong<br>
offset, jtype val) { \<br>
END_NATIVE_EXCEPTION \<br>
}<br>
<br>
-GET_PUT_OFFSET(Boolean,jboolean,Z)<br>
-GET_PUT_OFFSET(Byte,jbyte,B)<br>
-GET_PUT_OFFSET(Char,jchar,C)<br>
-GET_PUT_OFFSET(Short,jshort,S)<br>
-GET_PUT_OFFSET(Int,jint,I)<br>
-GET_PUT_OFFSET(Long,jlong,J)<br>
-GET_PUT_OFFSET(Float,jfloat,F)<br>
-GET_PUT_OFFSET(Double,jdouble,D)<br>
+//===--- Direct address read/write acccessors<br>
-----------------------------===//<br>
+#define GET_PUT_DIRECT(Type,jtype,shorttype) \<br>
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_put ## Type ## __J ## shorttype( \<br>
+JavaObject* unsafe, jlong ptr, jtype val) { \<br>
+ BEGIN_NATIVE_EXCEPTION(0) \<br>
+ *(jtype*)ptr = val; \<br>
+ END_NATIVE_EXCEPTION \<br>
+} \<br>
+ \<br>
+JNIEXPORT jtype JNICALL Java_sun_misc_Unsafe_get ## Type ## __J( \<br>
+JavaObject* unsafe, jlong ptr) { \<br>
+ jtype res = 0; \<br>
+ BEGIN_NATIVE_EXCEPTION(0) \<br>
+ res = *(jtype*)ptr; \<br>
+ END_NATIVE_EXCEPTION \<br>
+ return res; \<br>
+}<br>
+<br>
+//===--- Volatile variant of field accessors<br>
------------------------------===//<br>
+// Memory barriers after writes to ensure new value is seen elsewhere<br>
+#define GET_PUT_OFFSET_VOLATILE(Type,jtype,shorttype) \<br>
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_put ## Type ##<br>
Volatile__J ## shorttype( \<br>
+JavaObject* unsafe, jlong ptr, jtype val) { \<br>
+ BEGIN_NATIVE_EXCEPTION(0) \<br>
+ *(volatile jtype*)ptr = val; \<br>
+ __sync_synchronize(); \<br>
+ END_NATIVE_EXCEPTION \<br>
+} \<br>
+ \<br>
+JNIEXPORT jtype JNICALL Java_sun_misc_Unsafe_get ## Type ## Volatile__J( \<br>
+JavaObject* unsafe, jlong ptr) { \<br>
+ jtype res = 0; \<br>
+ BEGIN_NATIVE_EXCEPTION(0) \<br>
+ res = *(volatile jtype*)ptr; \<br>
+ END_NATIVE_EXCEPTION \<br>
+ return res; \<br>
+}<br>
+<br>
+//===--- Volatile variant of direct address accessors<br>
---------------------===//<br>
+#define GET_PUT_DIRECT_VOLATILE(Type,jtype,shorttype) \<br>
+JNIEXPORT jtype JNICALL Java_sun_misc_Unsafe_get ## Type ##<br>
Volatile__Ljava_lang_Object_2J( \<br>
+JavaObject* unsafe, JavaObject* base, jlong offset) { \<br>
+ jtype res = 0; \<br>
+ BEGIN_NATIVE_EXCEPTION(0) \<br>
+ volatile jtype* ptr = (volatile jtype*)fieldPtr(base,offset); \<br>
+ res = *ptr; \<br>
+ END_NATIVE_EXCEPTION \<br>
+ \<br>
+ return res; \<br>
+} \<br>
+ \<br>
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_put ## Type ##<br>
Volatile__Ljava_lang_Object_2J ## shorttype( \<br>
+JavaObject* unsafe, JavaObject* base, jlong offset, jtype val) { \<br>
+ BEGIN_NATIVE_EXCEPTION(0) \<br>
+ volatile jtype* ptr = (volatile jtype*)fieldPtr(base,offset); \<br>
+ *ptr = val; \<br>
+ __sync_synchronize(); \<br>
+ END_NATIVE_EXCEPTION \<br>
+}<br>
+<br>
+//===--- Ordered variant of field accessors<br>
-------------------------------===//<br>
+#define GET_PUT_FIELD_ORDERED(Type,jtype,shorttype) \<br>
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrdered ## Type( \<br>
+JavaObject* unsafe, JavaObject* base, jlong offset, jtype val) { \<br>
+ BEGIN_NATIVE_EXCEPTION(0) \<br>
+ volatile jtype* ptr = (volatile jtype*)fieldPtr(base,offset); \<br>
+ *ptr = val; \<br>
+ /* No memory barrier */ \<br>
+ END_NATIVE_EXCEPTION \<br>
+}<br>
+<br>
+#define GET_PUT_ALL(Type,jtype,shorttype) \<br>
+ GET_PUT_OFFSET(Type,jtype,shorttype) \<br>
+ GET_PUT_DIRECT(Type,jtype,shorttype) \<br>
+ GET_PUT_OFFSET_VOLATILE(Type,jtype,shorttype) \<br>
+ GET_PUT_DIRECT_VOLATILE(Type,jtype,shorttype)<br>
+<br>
+GET_PUT_ALL(Boolean,jboolean,Z)<br>
+GET_PUT_ALL(Byte,jbyte,B)<br>
+GET_PUT_ALL(Char,jchar,C)<br>
+GET_PUT_ALL(Short,jshort,S)<br>
+GET_PUT_ALL(Int,jint,I)<br>
+GET_PUT_ALL(Long,jlong,J) // TODO: Long needs special handling!<br>
+GET_PUT_ALL(Float,jfloat,F)<br>
+GET_PUT_ALL(Double,jdouble,D)<br>
+<br>
+// Ordered:<br>
+GET_PUT_FIELD_ORDERED(Int,jint,I)<br>
+GET_PUT_FIELD_ORDERED(Long,jlong,J)<br>
<br>
//===--- Get/Put of Objects, due to GC needs special handling<br>
-------------===//<br>
// JavaObject field accessors:<br>
-// Never throws.<br>
-JNIEXPORT JavaObject* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(<br>
+JNIEXPORT void JNICALL<br>
Java_sun_misc_Unsafe_putObject__Ljava_lang_Object_2JLjava_lang_Object_2(<br>
+JavaObject* unsafe, JavaObject* base, jlong offset, JavaObject* value) {<br>
+ llvm_gcroot(unsafe, 0);<br>
+ llvm_gcroot(base, 0);<br>
+ llvm_gcroot(value, 0);<br>
+<br>
+ JavaObject** ptr = (JavaObject**)fieldPtr(base, offset);<br>
+ mvm::Collector::objectReferenceWriteBarrier((gc*)base, (gc**)ptr,<br>
(gc*)value);<br>
+}<br>
+<br>
+<br>
+JNIEXPORT JavaObject* JNICALL<br>
Java_sun_misc_Unsafe_getObject__Ljava_lang_Object_2J(<br>
JavaObject* unsafe, JavaObject* base, jlong offset) {<br>
JavaObject * res = 0;<br>
llvm_gcroot(unsafe, 0);<br>
@@ -166,9 +254,6 @@ JavaObject* unsafe, JavaObject* base, jlong offset) {<br>
// Volatile JavaObject field accessors:<br>
// Never throws.<br>
JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObjectVolatile(<br>
-#ifdef NATIVE_JNI<br>
-JNIEnv *env,<br>
-#endif<br>
JavaObject* unsafe, JavaObject* base, jlong offset, JavaObject* value) {<br>
llvm_gcroot(unsafe, 0);<br>
llvm_gcroot(base, 0);<br>
@@ -176,38 +261,49 @@ JavaObject* unsafe, JavaObject* base, jlong<br>
offset, JavaObject* value) {<br>
<br>
JavaObject** ptr = (JavaObject**)fieldPtr(base, offset);<br>
mvm::Collector::objectReferenceWriteBarrier((gc*)base, (gc**)ptr,<br>
(gc*)value);<br>
+ // Ensure this value is seen.<br>
+ __sync_synchronize();<br>
}<br>
<br>
-//===--- Misc get/put defined, TODO: generalize!<br>
--------------------------===//<br>
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong__JJ(<br>
-JavaObject* unsafe, jlong ptr, jlong value) {<br>
- BEGIN_NATIVE_EXCEPTION(0)<br>
- *(jlong*)ptr = value;<br>
- END_NATIVE_EXCEPTION<br>
-}<br>
+JNIEXPORT JavaObject* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(<br>
+JavaObject* unsafe, JavaObject* base, jlong offset) {<br>
+ JavaObject * res = 0;<br>
+ llvm_gcroot(unsafe, 0);<br>
+ llvm_gcroot(base, 0);<br>
+ llvm_gcroot(res, 0);<br>
<br>
-JNIEXPORT jbyte JNICALL Java_sun_misc_Unsafe_getByte__J(<br>
-JavaObject* unsafe, jlong ptr) {<br>
- jbyte res = 0;<br>
BEGIN_NATIVE_EXCEPTION(0)<br>
- res = *(jbyte*)ptr;<br>
- END_NATIVE_EXCEPTION<br>
+ JavaObject* volatile* ptr = (JavaObject* volatile*)fieldPtr(base, offset);<br>
+ res = *ptr;<br>
+ END_NATIVE_EXCEPTION;<br>
<br>
return res;<br>
}<br>
<br>
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrderedObject(<br>
+JavaObject* unsafe, JavaObject* base, jlong offset, JavaObject* value) {<br>
+ llvm_gcroot(unsafe, 0);<br>
+ llvm_gcroot(base, 0);<br>
+ llvm_gcroot(value, 0);<br>
+<br>
+ JavaObject** ptr = (JavaObject**)fieldPtr(base, offset);<br>
+ mvm::Collector::objectReferenceWriteBarrier((gc*)base, (gc**)ptr,<br>
(gc*)value);<br>
+ // No barrier (difference between volatile and ordered)<br>
+}<br>
+<br>
<br>
//===--- CompareAndSwap field accessors<br>
-----------------------------------===//<br>
// Never throws.<br>
JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapLong(<br>
-JavaObject* unsafe, JavaObject* obj, jlong offset, jlong expect,<br>
jlong update) {<br>
+JavaObject* unsafe, JavaObject* base, jlong offset, jlong expect,<br>
jlong update) {<br>
<br>
llvm_gcroot(unsafe, 0);<br>
- llvm_gcroot(obj, 0);<br>
+ llvm_gcroot(base, 0);<br>
jlong *ptr;<br>
jlong value;<br>
<br>
- ptr = (jlong *) (((uint8 *) obj) + offset);<br>
+ // TODO: Why isn't this atomic?<br></blockquote><div><br></div><div>Why would it be on a 32 bit system?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
+ ptr = (jlong*)fieldPtr(base, offset);<br>
<br>
value = *ptr;<br>
<br>
@@ -222,37 +318,31 @@ JavaObject* unsafe, JavaObject* obj, jlong<br>
offset, jlong expect, jlong update) {<br>
<br>
// Never throws.<br>
JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapInt(<br>
-#ifdef NATIVE_JNI<br>
-JNIEnv *env,<br>
-#endif<br>
-JavaObject* unsafe, JavaObject* obj, jlong offset, jint expect, jint update) {<br>
+JavaObject* unsafe, JavaObject* base, jlong offset, jint expect, jint update) {<br>
<br>
llvm_gcroot(unsafe, 0);<br>
- llvm_gcroot(obj, 0);<br>
+ llvm_gcroot(base, 0);<br>
jint *ptr;<br>
<br>
- ptr = (jint *) (((uint8 *) obj) + offset);<br>
+ ptr = (jint *)fieldPtr(base, offset);<br>
<br>
return __sync_bool_compare_and_swap(ptr, expect, update);<br>
}<br>
<br>
// Never throws.<br>
JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapObject(<br>
-#ifdef NATIVE_JNI<br>
-JNIEnv *env,<br>
-#endif<br>
-JavaObject* unsafe, JavaObject* obj, jlong offset, JavaObject* expect,<br>
+JavaObject* unsafe, JavaObject* base, jlong offset, JavaObject* expect,<br>
JavaObject* update) {<br>
llvm_gcroot(unsafe, 0);<br>
- llvm_gcroot(obj, 0);<br>
+ llvm_gcroot(base, 0);<br>
llvm_gcroot(expect, 0);<br>
llvm_gcroot(update, 0);<br>
<br>
- JavaObject** ptr = (JavaObject**) (((uint8 *) obj) + offset);<br>
-<br>
- return mvm::Collector::objectReferenceTryCASBarrier((gc*)obj,<br>
(gc**)ptr, (gc*)expect, (gc*)update);<br>
+ JavaObject** ptr = (JavaObject**)fieldPtr(base, offset);<br>
+ return mvm::Collector::objectReferenceTryCASBarrier((gc*)base,<br>
(gc**)ptr, (gc*)expect, (gc*)update);<br>
}<br>
<br>
+<br>
//===--- Class-related functions<br>
------------------------------------------===//<br>
JNIEXPORT void JNICALL Java_sun_misc_Unsafe_ensureClassInitialized(<br>
JavaObject* unsafe, JavaObject* clazz) {<br>
@@ -270,6 +360,11 @@ JavaObject* unsafe, JavaObject* clazz) {<br>
END_NATIVE_EXCEPTION;<br>
}<br>
<br>
+JNIEXPORT JavaObject* JNICALL<br>
Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BII(<br>
+JavaObject* unsafe, JavaString *name, ArrayObject * bytesArr, jint<br>
off, jint len) {<br>
+ UNIMPLEMENTED();<br>
+}<br>
+<br>
JNIEXPORT JavaObject* JNICALL<br>
Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2(<br>
JavaObject* unsafe, JavaString *name, ArrayObject * bytesArr, jint<br>
off, jint len, JavaObject * loader, JavaObject * pd) {<br>
JavaObject* res = 0;<br>
@@ -322,8 +417,34 @@ JavaObject* unsafe, JavaObjectClass * clazz) {<br>
return res;<br>
}<br>
<br>
+JNIEXPORT JavaObject* JNICALL Java_sun_Unsafe_defineAnonymousClass(<br>
+JavaObject* unsafe, ...) {<br>
+ UNIMPLEMENTED();<br>
+}<br>
<br>
//===--- Memory functions<br>
-------------------------------------------------===//<br>
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_setMemory__JJB(<br>
+JavaObject* unsafe, long address, long bytes, jbyte value) {<br>
+ memset((void*)address, value, bytes);<br>
+}<br>
+<br>
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_copyMemory__JJJ(<br>
+JavaObject* unsafe, jlong src, jlong dst, jlong size) {<br>
+ memcpy((void*)dst, (void*)src, size);<br>
+}<br>
+<br>
+JNIEXPORT void JNICALL<br>
Java_sun_misc_Unsafe_copyMemory__Ljava_lang_Object_2JLjava_lang_Object_2JJ(<br>
+JavaObject* unsafe,<br>
+JavaObject* srcBase, jlong srcOffset,<br>
+JavaObject* dstBase, jlong dstOffset,<br>
+jlong size) {<br>
+ BEGIN_NATIVE_EXCEPTION(0)<br>
+ uint8_t* src = fieldPtr(srcBase, srcOffset, false /* Don't throw on<br>
null base*/ );<br>
+ uint8_t* dst = fieldPtr(dstBase, dstOffset, false /* Don't throw on<br>
null base*/ );<br>
+ memcpy(dst, src, size);<br></blockquote><div><br></div><div>How does that deal with GC barriers?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
+ END_NATIVE_EXCEPTION<br>
+}<br>
+<br>
JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_allocateMemory(<br>
JavaObject* unsafe, jlong size) {<br>
// TODO: Invalid size/OOM/etc handling!<br>
@@ -334,6 +455,16 @@ JavaObject* unsafe, jlong size) {<br>
return res;<br>
}<br>
<br>
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_reallocateMemory(<br>
+JavaObject* unsafe, jlong ptr, jlong newsize) {<br>
+ // TODO: Invalid size/OOM/etc handling!<br>
+ jlong res = 0;<br>
+ BEGIN_NATIVE_EXCEPTION(0)<br>
+ res = (jlong)realloc((void*)ptr, newsize);<br>
+ END_NATIVE_EXCEPTION<br>
+ return res;<br>
+}<br>
+<br>
JNIEXPORT void JNICALL Java_sun_misc_Unsafe_freeMemory(<br>
JavaObject* unsafe, jlong ptr) {<br>
// TODO: Exception handling...<br>
@@ -342,6 +473,45 @@ JavaObject* unsafe, jlong ptr) {<br>
END_NATIVE_EXCEPTION<br>
}<br>
<br>
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_getAddress(<br>
+JavaObject* unsafe, jlong ptr) {<br>
+ return (jlong)*(void**)ptr;<br>
+}<br>
+<br>
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_putAddress(<br>
+JavaObject* unsafe, jlong ptr, jlong val) {<br>
+ *(void**)ptr = (void*)val;<br>
+}<br>
+<br>
+//===--- Park/Unpark thread support<br>
---------------------------------------===//<br>
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_park(<br>
+JavaObject* unsafe, jboolean isAbsolute, jlong time) {<br>
+ // Nothing, for now.<br>
+}<br>
+<br>
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_unpark(<br>
+JavaObject* unsafe, JavaObject* thread) {<br>
+ // Nothing, for now.<br>
+}<br>
+<br>
+//===--- Monitor support<br>
--------------------------------------------------===//<br>
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_tryMonitorEnter(<br>
+JavaObject* unsafe, JavaObject * obj) {<br>
+ //TODO: Implement me!<br>
+ UNIMPLEMENTED();<br>
+}<br>
+<br>
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_monitorEnter(<br>
+JavaObject* unsafe, JavaObject * obj) {<br>
+ //TODO: Implement me!<br>
+ UNIMPLEMENTED();<br>
+}<br>
+<br>
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_monitorExit(<br>
+JavaObject* unsafe, JavaObject * obj) {<br>
+ //TODO: Implement me!<br>
+ UNIMPLEMENTED();<br>
+}<br>
<br>
//===--- Misc support functions<br>
-------------------------------------------===//<br>
JNIEXPORT void JNICALL Java_sun_misc_Unsafe_registerNatives(JavaObject*) {<br>
@@ -356,6 +526,19 @@ JavaObject* unsafe, JavaObject * obj) {<br>
JavaThread::get()->throwException(obj);<br>
}<br>
<br>
+JNIEXPORT jint JNICALL Java_sun_misc_Unsafe_pageSize(<br>
+JavaObject* unsafe) {<br>
+ return mvm::System::GetPageSize();<br>
+}<br>
<br>
+JNIEXPORT jint JNICALL Java_sun_misc_Unsafe_addressSize(<br>
+JavaObject* unsafe) {<br>
+ return mvm::kWordSize;<br>
+}<br>
+<br>
+JNIEXPORT jint JNICALL Java_sun_misc_Unsafe_getLoadAverage(<br>
+JavaObject* unsafe, ...) {<br>
+ UNIMPLEMENTED();<br>
+}<br>
<br>
}<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.7.5.1<br>
_______________________________________________<br>
vmkit-commits mailing list<br>
<a href="mailto:vmkit-commits@cs.uiuc.edu">vmkit-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/vmkit-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/vmkit-commits</a><br>
</font></span></blockquote></div><br>