<div>Looks good, with one comment.</div><div><br></div>On Wed, Nov 16, 2011 at 12:15 AM, Will Dietz <span dir="ltr"><<a href="mailto:wdietz2@illinois.edu" target="_blank">wdietz2@illinois.edu</a>></span> wrote:<br><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Inlined below.<br>
<br>
No functionality change other than switching baseToPtr to fieldPtr.<br>
<br>
This patch mostly is to make the next patch cleaner.<br>
<br>
~Will<br>
<br>
>From 0c7a31e4a5fecae30ddf92cb4d2886e8f5cfae76 Mon Sep 17 00:00:00 2001<br>
From: Will Dietz <<a href="mailto:w@wdtz.org" target="_blank">w@wdtz.org</a>><br>
Date: Tue, 15 Nov 2011 16:55:11 -0600<br>
Subject: [PATCH 2/3] Unsafe.inc: Rearrange code into related groups of<br>
methods.<br>
<br>
Also, rename baseToPtr, with more useful fieldPtr.<br>
---<br>
lib/J3/ClassLib/Unsafe.inc | 371 ++++++++++++++++++++++++--------------------<br>
1 files changed, 203 insertions(+), 168 deletions(-)<br>
<br>
diff --git a/lib/J3/ClassLib/Unsafe.inc b/lib/J3/ClassLib/Unsafe.inc<br>
index dcccc65..5fe64db 100644<br>
--- a/lib/J3/ClassLib/Unsafe.inc<br>
+++ b/lib/J3/ClassLib/Unsafe.inc<br>
@@ -10,107 +10,175 @@<br>
#include "VMStaticInstance.h"<br>
#include <stdlib.h><br>
<br>
-// Convert a 'base' JavaObject to its pointer representation.<br>
-// Handles our special VMStaticInstance wrapper.<br>
-static inline uint8 *baseToPtr(JavaObject *base) {<br>
- if (VMStaticInstance::isVMStaticInstance(base))<br>
- return (uint8*)((VMStaticInstance*)base)->getStaticInstance();<br>
+/// fieldPtr - Compute the address of the field specified by the given<br>
+/// base/offset pair. Non-trivial due to our handling of static instances,<br>
+/// and this also handles null-checking as required.<br>
+///<br>
+static inline uint8 *fieldPtr(JavaObject *base, long long offset,<br></blockquote><div><br></div><div>Please use int64_t instead of long long.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ bool throwOnNull = true) {<br>
+<br>
+ // For most uses, a 'null' base should throw an exception.<br>
+ if (throwOnNull) verifyNull(base);<br>
+<br>
+ if (base && VMStaticInstance::isVMStaticInstance(base))<br>
+ return (uint8*)((VMStaticInstance*)base)->getStaticInstance() + offset;<br>
else<br>
- return (uint8*)base;<br>
+ return (uint8*)base + offset;<br>
}<br>
<br>
extern "C" {<br>
<br>
-// Never throws.<br>
-JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapLong(<br>
-#ifdef NATIVE_JNI<br>
-JNIEnv *env,<br>
-#endif<br>
-JavaObject* unsafe, JavaObject* obj, jlong offset, jlong expect,<br>
jlong update) {<br>
+//===--- Base/Offset methods<br>
----------------------------------------------===//<br>
<br>
+/// staticFieldOffset - Return the offset of a particular static field<br>
+/// Only valid to be used with the corresponding staticFieldBase<br>
+///<br>
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_staticFieldOffset(<br>
+JavaObject* unsafe, JavaObjectField* _field) {<br>
llvm_gcroot(unsafe, 0);<br>
- llvm_gcroot(obj, 0);<br>
- jlong *ptr;<br>
- jlong value;<br>
+ llvm_gcroot(_field, 0);<br>
<br>
- ptr = (jlong *) (((uint8 *) obj) + offset);<br>
+ jlong res = 0;<br>
+ BEGIN_NATIVE_EXCEPTION(0)<br>
<br>
- value = *ptr;<br>
+ JavaField * field = JavaObjectField::getInternalField(_field);<br>
+ assert(field);<br>
<br>
- if (value == expect) {<br>
- *ptr = update;<br>
- return true;<br>
- } else {<br>
- return false;<br>
- }<br>
+ res = field->ptrOffset;<br>
<br>
+ END_NATIVE_EXCEPTION;<br>
+<br>
+ return res;<br>
}<br>
<br>
-// Never throws.<br>
-JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapInt(<br>
+/// staticFieldBase - Return a JavaObject* representing the static instance.<br>
+/// Note that our static instances aren't actually java objects, so we use<br>
+/// a placeholder object "VMStaticInstance" that also ensures that<br>
+/// the corresponding class doesn't get GC'd underneath it.<br>
+///<br>
+JNIEXPORT JavaObject* JNICALL Java_sun_misc_Unsafe_staticFieldBase(<br>
+JavaObject* unsafe, JavaObjectField* _field) {<br>
+ JavaObject* res = 0;<br>
+ llvm_gcroot(unsafe, 0);<br>
+ llvm_gcroot(_field, 0);<br>
+ llvm_gcroot(res, 0);<br>
+ BEGIN_NATIVE_EXCEPTION(0)<br>
+<br>
+ JavaField * field = JavaObjectField::getInternalField(_field);<br>
+ assert(field);<br>
+ field->classDef->initialiseClass(JavaThread::get()->getJVM());<br>
+<br>
+ res = VMStaticInstance::allocate(field->classDef);<br>
+<br>
+ END_NATIVE_EXCEPTION;<br>
+<br>
+ return res;<br>
+}<br>
+<br>
+/// arrayBaseOffset - Offset from the array object where the actual<br>
+/// element data begins.<br>
+///<br>
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_arrayBaseOffset(<br>
+JavaObject* unsafe, JavaObject* clazz) {<br>
+ // Array starts at beginning of object<br>
+ return 0;<br>
+}<br>
+<br>
+/// arrayIndexScale - Indexing scale for the element type in<br>
+/// the specified array. For use with arrayBaseOffset,<br>
+/// NthElementPtr = ArrayObject + BaseOffset + N*IndexScale<br>
+/// Return '0' if our JVM stores the elements in a way that<br>
+/// makes this type of access impossible or unsupported.<br>
+///<br>
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_arrayIndexScale(<br>
+JavaObject* unsafe, JavaObject* clazz) {<br>
+ // For now, just return '0', indicating we don't support this indexing.<br>
+ // TODO: Implement this for the array types we /do/ support this way.<br>
+ return 0;<br>
+}<br>
+<br>
+<br>
+<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, JavaObject* obj, jlong offset, jint expect, jint update) {<br>
+JavaObject* Unsafe, JavaObjectField* Field) {<br>
<br>
- llvm_gcroot(unsafe, 0);<br>
- llvm_gcroot(obj, 0);<br>
- jint *ptr;<br>
+ llvm_gcroot(Field, 0);<br>
+ llvm_gcroot(Unsafe, 0);<br>
<br>
- ptr = (jint *) (((uint8 *) obj) + offset);<br>
+ JavaField* field = JavaObjectField::getInternalField(Field);<br>
+ return (jlong)field->ptrOffset;<br>
+}<br>
<br>
- return __sync_bool_compare_and_swap(ptr, expect, update);<br>
+//===--- Double-register addressing field accessors<br>
-----------------------===//<br>
+// See objectFieldOffset, staticFieldOffset, staticFieldBase<br>
+// Can also be an array, if/when we support arrayIndexScale/arrayBaseOffset<br>
+#define GET_PUT_OFFSET(Type,jtype,shorttype) \<br>
+JNIEXPORT jtype JNICALL Java_sun_misc_Unsafe_get ## Type ##<br>
__Ljava_lang_Object_2J( \<br>
+JavaObject* unsafe, JavaObject* base, jlong offset) { \<br>
+ jtype res = 0; \<br>
+ BEGIN_NATIVE_EXCEPTION(0) \<br>
+ jtype* ptr = (jtype*)fieldPtr(base,offset); \<br>
+ res = *ptr; \<br>
+ END_NATIVE_EXCEPTION \<br>
+ return res; \<br>
+} \<br>
+ \<br>
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_put ## Type ##<br>
__Ljava_lang_Object_2J ## shorttype( \<br>
+JavaObject* unsafe, JavaObject* base, jlong offset, jtype val) { \<br>
+ BEGIN_NATIVE_EXCEPTION(0) \<br>
+ jtype* ptr = (jtype*)fieldPtr(base, offset); \<br>
+ *ptr = 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>
+<br>
+//===--- Get/Put of Objects, due to GC needs special handling<br>
-------------===//<br>
+// JavaObject field accessors:<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* update) {<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(obj, 0);<br>
- llvm_gcroot(expect, 0);<br>
- llvm_gcroot(update, 0);<br>
+ llvm_gcroot(base, 0);<br>
+ llvm_gcroot(res, 0);<br>
<br>
- JavaObject** ptr = (JavaObject**) (((uint8 *) obj) + offset);<br>
+ BEGIN_NATIVE_EXCEPTION(0)<br>
+ JavaObject** ptr = (JavaObject**)fieldPtr(base, offset);<br>
+ res = *ptr;<br>
+ END_NATIVE_EXCEPTION;<br>
<br>
- return mvm::Collector::objectReferenceTryCASBarrier((gc*)obj,<br>
(gc**)ptr, (gc*)expect, (gc*)update);<br>
+ return res;<br>
}<br>
<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* obj, jlong offset, JavaObject* value) {<br>
+JavaObject* unsafe, JavaObject* base, jlong offset, JavaObject* value) {<br>
llvm_gcroot(unsafe, 0);<br>
- llvm_gcroot(obj, 0);<br>
+ llvm_gcroot(base, 0);<br>
llvm_gcroot(value, 0);<br>
<br>
- JavaObject** ptr = (JavaObject**) (((uint8 *) obj) + offset);<br>
- mvm::Collector::objectReferenceWriteBarrier((gc*)obj, (gc**)ptr, (gc*)value);<br>
-}<br>
-<br>
-JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_allocateMemory(<br>
-JavaObject* unsafe, jlong size) {<br>
- // TODO: Invalid size/OOM/etc handling!<br>
- jlong res = 0;<br>
- BEGIN_NATIVE_EXCEPTION(0)<br>
- res = (jlong)malloc(size);<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>
- BEGIN_NATIVE_EXCEPTION(0)<br>
- free((void*)ptr);<br>
- END_NATIVE_EXCEPTION<br>
+ JavaObject** ptr = (JavaObject**)fieldPtr(base, offset);<br>
+ mvm::Collector::objectReferenceWriteBarrier((gc*)base, (gc**)ptr,<br>
(gc*)value);<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>
@@ -128,104 +196,78 @@ JavaObject* unsafe, jlong ptr) {<br>
return res;<br>
}<br>
<br>
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_ensureClassInitialized(<br>
-JavaObject* unsafe, JavaObject* clazz) {<br>
- llvm_gcroot(unsafe, 0);<br>
- llvm_gcroot(clazz, 0);<br>
- BEGIN_NATIVE_EXCEPTION(0)<br>
-<br>
- Jnjvm* vm = JavaThread::get()->getJVM();<br>
<br>
- CommonClass * cl = JavaObject::getClass(clazz);<br>
- assert(cl && cl->isClass());<br>
- cl->asClass()->resolveClass();<br>
- cl->asClass()->initialiseClass(vm);<br>
-<br>
- END_NATIVE_EXCEPTION;<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>
<br>
-JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_staticFieldOffset(<br>
-JavaObject* unsafe, JavaObjectField* _field) {<br>
llvm_gcroot(unsafe, 0);<br>
- llvm_gcroot(_field, 0);<br>
-<br>
- jlong res = 0;<br>
- BEGIN_NATIVE_EXCEPTION(0)<br>
+ llvm_gcroot(obj, 0);<br>
+ jlong *ptr;<br>
+ jlong value;<br>
<br>
- JavaField * field = JavaObjectField::getInternalField(_field);<br>
- assert(field);<br>
+ ptr = (jlong *) (((uint8 *) obj) + offset);<br>
<br>
- res = field->ptrOffset;<br>
+ value = *ptr;<br>
<br>
- END_NATIVE_EXCEPTION;<br>
+ if (value == expect) {<br>
+ *ptr = update;<br>
+ return true;<br>
+ } else {<br>
+ return false;<br>
+ }<br>
<br>
- return res;<br>
}<br>
<br>
-JNIEXPORT JavaObject* JNICALL Java_sun_misc_Unsafe_staticFieldBase(<br>
-JavaObject* unsafe, JavaObjectField* _field) {<br>
- JavaObject* res = 0;<br>
- llvm_gcroot(unsafe, 0);<br>
- llvm_gcroot(_field, 0);<br>
- llvm_gcroot(res, 0);<br>
- BEGIN_NATIVE_EXCEPTION(0)<br>
-<br>
- JavaField * field = JavaObjectField::getInternalField(_field);<br>
- assert(field);<br>
- field->classDef->initialiseClass(JavaThread::get()->getJVM());<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>
<br>
- res = VMStaticInstance::allocate(field->classDef);<br>
+ llvm_gcroot(unsafe, 0);<br>
+ llvm_gcroot(obj, 0);<br>
+ jint *ptr;<br>
<br>
- END_NATIVE_EXCEPTION;<br>
+ ptr = (jint *) (((uint8 *) obj) + offset);<br>
<br>
- return res;<br>
+ return __sync_bool_compare_and_swap(ptr, expect, update);<br>
}<br>
<br>
-/// objectFieldOffset - Pointer offset of the specified field<br>
-///<br>
-JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_objectFieldOffset(<br>
+// Never throws.<br>
+JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapObject(<br>
#ifdef NATIVE_JNI<br>
JNIEnv *env,<br>
#endif<br>
-JavaObject* Unsafe, JavaObjectField* Field) {<br>
+JavaObject* unsafe, JavaObject* obj, jlong offset, JavaObject* expect,<br>
+JavaObject* update) {<br>
+ llvm_gcroot(unsafe, 0);<br>
+ llvm_gcroot(obj, 0);<br>
+ llvm_gcroot(expect, 0);<br>
+ llvm_gcroot(update, 0);<br>
<br>
- llvm_gcroot(Field, 0);<br>
- llvm_gcroot(Unsafe, 0);<br>
+ JavaObject** ptr = (JavaObject**) (((uint8 *) obj) + offset);<br>
<br>
- JavaField* field = JavaObjectField::getInternalField(Field);<br>
- return (jlong)field->ptrOffset;<br>
+ return mvm::Collector::objectReferenceTryCASBarrier((gc*)obj,<br>
(gc**)ptr, (gc*)expect, (gc*)update);<br>
}<br>
<br>
-JNIEXPORT JavaObject* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(<br>
-JavaObject* unsafe, JavaObject* base, jlong offset) {<br>
- JavaObject * res = 0;<br>
+//===--- Class-related functions<br>
------------------------------------------===//<br>
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_ensureClassInitialized(<br>
+JavaObject* unsafe, JavaObject* clazz) {<br>
llvm_gcroot(unsafe, 0);<br>
- llvm_gcroot(base, 0);<br>
- llvm_gcroot(res, 0);<br>
-<br>
+ llvm_gcroot(clazz, 0);<br>
BEGIN_NATIVE_EXCEPTION(0)<br>
- JavaObject** ptr = (JavaObject**) (baseToPtr(base) + offset);<br>
- res = *ptr;<br>
- END_NATIVE_EXCEPTION;<br>
<br>
- return res;<br>
-}<br>
+ Jnjvm* vm = JavaThread::get()->getJVM();<br>
<br>
-JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_arrayBaseOffset(<br>
-JavaObject* unsafe, JavaObject* clazz) {<br>
- // Array starts at beginning of object<br>
- return 0;<br>
-}<br>
+ CommonClass * cl = JavaObject::getClass(clazz);<br>
+ assert(cl && cl->isClass());<br>
+ cl->asClass()->resolveClass();<br>
+ cl->asClass()->initialiseClass(vm);<br>
<br>
-JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_arrayIndexScale(<br>
-#ifdef NATIVE_JNI<br>
-JNIEnv *env,<br>
-#endif<br>
-JavaObject* unsafe, JavaObject* clazz) {<br>
- // Return '0' if we don't support indexing this way.<br>
- // (We might pack fields specially, etc)<br>
- // TODO: Implement this for the array types we support this way<br>
- return 0;<br>
+ END_NATIVE_EXCEPTION;<br>
}<br>
<br>
JNIEXPORT JavaObject* JNICALL<br>
Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2(<br>
@@ -281,6 +323,31 @@ JavaObject* unsafe, JavaObjectClass * clazz) {<br>
}<br>
<br>
<br>
+//===--- Memory functions<br>
-------------------------------------------------===//<br>
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_allocateMemory(<br>
+JavaObject* unsafe, jlong size) {<br>
+ // TODO: Invalid size/OOM/etc handling!<br>
+ jlong res = 0;<br>
+ BEGIN_NATIVE_EXCEPTION(0)<br>
+ res = (jlong)malloc(size);<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>
+ BEGIN_NATIVE_EXCEPTION(0)<br>
+ free((void*)ptr);<br>
+ END_NATIVE_EXCEPTION<br>
+}<br>
+<br>
+<br>
+//===--- Misc support functions<br>
-------------------------------------------===//<br>
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_registerNatives(JavaObject*) {<br>
+ // Nothing, we define the Unsafe methods with the expected signatures.<br>
+}<br>
+<br>
JNIEXPORT void JNICALL Java_sun_misc_Unsafe_throwException(<br>
JavaObject* unsafe, JavaObject * obj) {<br>
llvm_gcroot(unsafe, 0);<br>
@@ -289,38 +356,6 @@ JavaObject* unsafe, JavaObject * obj) {<br>
JavaThread::get()->throwException(obj);<br>
}<br>
<br>
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_registerNatives(JavaObject*) {<br>
- // Nothing<br>
-}<br>
-<br>
-// TODO: Add the Volatile variants<br>
-#define GET_PUT_OFFSET(Type,jtype,shorttype) \<br>
-JNIEXPORT jtype JNICALL Java_sun_misc_Unsafe_get ## Type ##<br>
__Ljava_lang_Object_2J( \<br>
-JavaObject* unsafe, JavaObject* base, jlong offset) { \<br>
- jtype res = 0; \<br>
- BEGIN_NATIVE_EXCEPTION(0) \<br>
- jtype* ptr = (jtype*) (baseToPtr(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>
__Ljava_lang_Object_2J ## shorttype( \<br>
-JavaObject* unsafe, JavaObject* base, jlong offset, jtype val) { \<br>
- BEGIN_NATIVE_EXCEPTION(0) \<br>
- jtype* ptr = (jtype*) (baseToPtr(base) + offset); \<br>
- *ptr = 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>
<br>
}<br>
<span><font color="#888888">--<br>
1.7.5.1<br>
_______________________________________________<br>
vmkit-commits mailing list<br>
<a href="mailto:vmkit-commits@cs.uiuc.edu" target="_blank">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>