From: Martin Zaun Date: July 2 2011 10:09am Subject: bzr commit into mysql-5.1-telco-7.1 branch (martin.zaun:4277) List-Archive: http://lists.mysql.com/commits/140065 Message-Id: <201107021009.p62A9RcI007810@acsmt356.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============5638035109591058994==" --===============5638035109591058994== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///Users/mz/mysql/ndb-7.1-jtie/ based on revid:maitrayi.sabaratnam@stripped 4277 Martin Zaun 2011-07-02 ndbjtie - fixed class reference assumptions in MemberIdCache, added code doc, some clean up. modified: storage/ndb/src/ndbjtie/jtie/jtie_tconv_idcache_impl.hpp storage/ndb/src/ndbjtie/jtie/jtie_tconv_object.hpp storage/ndb/src/ndbjtie/jtie/jtie_tconv_object_impl.hpp storage/ndb/src/ndbjtie/jtie/jtie_tconv_ptrbybb_impl.hpp === modified file 'storage/ndb/src/ndbjtie/jtie/jtie_tconv_idcache_impl.hpp' --- a/storage/ndb/src/ndbjtie/jtie/jtie_tconv_idcache_impl.hpp 2011-02-02 09:52:33 +0000 +++ b/storage/ndb/src/ndbjtie/jtie/jtie_tconv_idcache_impl.hpp 2011-07-02 10:09:08 +0000 @@ -54,7 +54,7 @@ // --------------------------------------------------------------------------- -// JNI helper functions +// Local JNI helper functions template< typename T > inline T @@ -108,30 +108,120 @@ jniGetMemberID< jfieldID >(JNIEnv * env, /** * Instantiates an info type describing a member of a Java class. */ -#define JTIE_INSTANTIATE_CLASS_MEMBER_INFO( T, CN, MN, MD ) \ - const char * const T::class_name = CN; \ - const char * const T::member_name = MN; \ - const char * const T::member_descriptor = MD; \ - template struct MemberId< T >; \ +#define JTIE_INSTANTIATE_CLASS_MEMBER_INFO( T, CN, MN, MD ) \ + const char * const T::class_name = CN; \ + const char * const T::member_name = MN; \ + const char * const T::member_descriptor = MD; \ + template struct MemberId< T >; \ template struct MemberIdCache< T >; -// XXX document these classes... - +/** + * Provides uniform access to the JNI Field/Method ID of a Java class member + * as described by the member info type 'C'. + * + * This base class does not cache the member ID and the class object, but + * it retrieves the member ID from JNI upon each access; different caching + * strategies are provided by derived classes. + * + * This class (and its derived classes) impose a strict usage pattern. + * For example, given definitions... + * + * // Defines the field info type for MyClass.myField. + * JTIE_DEFINE_FIELD_MEMBER_INFO(_MyClass_myField) + * + * // Provides a (cached) access to field Id of MyClass.myField. + * typedef JniMemberId< _MyClass_myField > MyClass_myField; + * + * any use of a member ID must be bracketed by getClass() and releaseRef(): + * + * // obtain a class reference + * jclass cls = MyClass_myField::getClass(env); + * if (cls == NULL) { + * // exception pending + * } else { + * // get the field ID valid along with the class reference + * jfieldID fid = MyClass_myField::getId(env, cls); + * if (fid == NULL) { + * // exception pending + * } else { + * // OK to access field using 'fid' + * } + * // allow for releasing the class reference + * MyClass_myField::releaseRef(env, cls); + * } + * + * Derived classes implement any caching underneath this usage pattern. + */ template< typename C > struct MemberId { typedef typename C::memberID_t ID_t; - - // number of JNI GetID() invocations + + // number of JNI GetID() invocations for statistics static unsigned long nIdLookUps; + /** + * Allows for storing a (global) class reference. + * + * Usually only called from getClass(), but enables "cache preloading" + * from a (native, static) function called at class initialization. + * + * Pre condition: + * - this thread has no pending JNI exception (!env->ExceptionCheck()) + * - a valid local or global class reference: assert(cls != NULL) + */ static void setClass(JNIEnv * env, jclass cls) { + assert(cls != NULL); (void)env; (void)cls; } + /** + * Returns a JNI Reference to the class declaring the member specified + * by info type 'C'. + * + * Depending upon the underlying caching strategy, a returned reference + * may be local or global, weak or strong; the scope of its use must be + * demarcated by releaseRef(). + * + * Pre condition: + * - this thread has no pending JNI exception (!env->ExceptionCheck()) + * + * Post condition: + * - return value is + * NULL: + * - this thread has a pending JNI exception (env->ExceptionCheck()) + * otherwise: + * - this thread has no pending JNI exception (!env->ExceptionCheck()) + * - the returned reference is valid (at least) until releaseRef() + */ static jclass getClass(JNIEnv * env) { - return env->FindClass(C::class_name); + assert(env->ExceptionCheck() == JNI_OK); + jclass cls = env->FindClass(C::class_name); + if (cls == NULL) { // break out for better diagnostics + assert(env->ExceptionCheck() != JNI_OK); // exception pending + } else { + assert(env->ExceptionCheck() == JNI_OK); // ok + } + return cls; } + /** + * Returns the JNI Field/Method ID of a Java class member. + * + * The member ID is only valid along with a class object obtained by + * getClass() and before releaseRef(). + * + * Pre condition: + * - this thread has no pending JNI exception (!env->ExceptionCheck()) + * - a valid class reference obtained by getClass(): assert(cls != NULL) + * + * Post condition: + * - return value is + * NULL: + * - this thread has a pending JNI exception (env->ExceptionCheck()) + * otherwise: + * - this thread has no pending JNI exception (!env->ExceptionCheck()) + * - the returned member ID is valid (at least) until releaseRef() + */ static ID_t getId(JNIEnv * env, jclass cls) { assert(cls != NULL); // multithreaded access ok, inaccurate if non-atomic increment @@ -139,71 +229,104 @@ struct MemberId { return jniGetMemberID< ID_t >(env, cls, C::member_name, C::member_descriptor); } - + + /** + * Allows for a class reference to be released along with any member IDs. + * + * Pre condition: + * - a valid class reference obtained by getClass(): assert(cls != NULL) + * - this thread may have a pending JNI exception (env->ExceptionCheck()) + */ static void releaseRef(JNIEnv * env, jclass cls) { + assert(cls != NULL); env->DeleteLocalRef(cls); } }; +/** + * Base class for caching of JNI Field/Method IDs. + */ template< typename C > struct MemberIdCache : MemberId< C > { typedef typename C::memberID_t ID_t; static ID_t getId(JNIEnv * env, jclass cls) { - assert (cls != NULL); + assert(cls != NULL); + // the cached member id is only valid along with global class ref + assert(env->IsSameObject(gClassRef, NULL) == JNI_FALSE); (void)env; (void)cls; return mid; } protected: + // the cached global (weak or strong) class ref static jclass gClassRef; + + // the cached member id (only valid along with global class ref) static ID_t mid; }; +/** + * Provides caching of JNI Field/Method IDs using weak class references, + * allowing classes to be unloaded when no longer used by Java code. + */ template< typename C > struct MemberIdWeakCache : MemberIdCache< C > { typedef MemberId< C > A; typedef MemberIdCache< C > Base; static void setClass(JNIEnv * env, jclass cls) { - assert (cls != NULL); + assert(cls != NULL); // multithreaded access ok, sets same class/member object - Base::gClassRef = static_cast(env->NewWeakGlobalRef(cls)); + Base::gClassRef = static_cast< jclass >(env->NewWeakGlobalRef(cls)); Base::mid = A::getId(env, cls); } - using Base::getId; - + using Base::getId; // use as inherited (some compiler wanted this) + static jclass getClass(JNIEnv * env) { - jclass cls = static_cast(env->NewLocalRef(Base::gClassRef)); + // a weak global class ref may refer to a freed object at any time + // (i.e.: env->IsSameObject(Base::gClassRef, NULL)) + // unless we've obtained a strong (local or global) non-NULL class ref + jclass cls = static_cast< jclass >(env->NewLocalRef(Base::gClassRef)); if (cls == NULL) { + // global class ref was NULL or referencing a freed object cls = A::getClass(env); - setClass(env, cls); + if (cls == NULL) { + // exception pending + } else { + setClass(env, cls); + } } return cls; } - + static void releaseRef(JNIEnv * env, jclass cls) { + assert(cls != NULL); env->DeleteLocalRef(cls); } }; +/** + * Provides caching of JNI Field/Method IDs using strong class references, + * preventing classes from being unloaded even if no longer used by Java code. + */ template< typename C > struct MemberIdStrongCache : MemberIdCache< C > { typedef MemberId< C > A; typedef MemberIdCache< C > Base; - + static void setClass(JNIEnv * env, jclass cls) { - assert (cls != NULL); + assert(cls != NULL); // multithreaded access ok, sets same class/member object - Base::gClassRef = static_cast(env->NewGlobalRef(cls)); + Base::gClassRef = static_cast< jclass >(env->NewGlobalRef(cls)); Base::mid = A::getId(env, cls); } - using Base::getId; - + using Base::getId; // use as inherited (some compiler wanted this) + static jclass getClass(JNIEnv * env) { jclass cls = Base::gClassRef; if (cls == NULL) { @@ -212,48 +335,61 @@ struct MemberIdStrongCache : MemberIdCac } return cls; } - + static void releaseRef(JNIEnv * env, jclass cls) { + assert(cls != NULL); + (void)env; (void)cls; } }; +/** + * Provides caching of JNI Field/Method IDs using weak class references + * with preloading (at class initialization) -- VERY TRICKY, NOT SUPPORTED. + */ template< typename C > struct MemberIdPreloadedWeakCache : MemberIdWeakCache< C > { typedef MemberIdWeakCache< C > Base; - - using Base::setClass; - using Base::getId; - + using Base::setClass; // use as inherited (some compiler wanted this) + + using Base::getId; // use as inherited (some compiler wanted this) + static jclass getClass(JNIEnv * env) { + // weak global class ref is assumed to be preloaded and valid jclass cls = Base::gClassRef; - assert (cls != NULL); + assert(env->IsSameObject(cls, NULL) == JNI_FALSE); return cls; } - + static void releaseRef(JNIEnv * env, jclass cls) { + assert(cls != NULL); + (void)env; (void)cls; } }; +/** + * Provides caching of JNI Field/Method IDs using strong class references + * with preloading (at class initialization) -- VERY TRICKY, NOT SUPPORTED. + */ template< typename C > struct MemberIdPreloadedStrongCache : MemberIdStrongCache< C > { typedef MemberIdStrongCache< C > Base; - - using Base::setClass; - using Base::getId; - + using Base::setClass; // use as inherited (some compiler wanted this) + + using Base::getId; // use as inherited (some compiler wanted this) + static jclass getClass(JNIEnv * env) { + // strong global class ref is assumed to be preloaded and valid jclass cls = Base::gClassRef; - assert (cls != NULL); + assert(env->IsSameObject(cls, NULL) == JNI_FALSE); return cls; - } + } - using Base::releaseRef; + using Base::releaseRef; // use as inherited (some compiler wanted this) }; -// XXX test with multiple compilation units <-> jtie_lib.hpp - +// XXX static initialization <-> multiple compilation units <-> jtie_lib.hpp template< typename C > unsigned long MemberId< C > ::nIdLookUps = 0; @@ -265,14 +401,22 @@ template< typename C > typename C::membe // XXX document +/** + * The supported caching strategies for member IDs and class references. + */ enum JniMemberIdCaching { - NO_CACHING, - WEAK_CACHING, - STRONG_CACHING, - WEAK_CACHING_PRELOAD, - STRONG_CACHING_PRELOAD + NO_CACHING + ,WEAK_CACHING + ,STRONG_CACHING +#if 0 // preloaded caching very tricky, not supported at this time + ,WEAK_CACHING_PRELOAD + ,STRONG_CACHING_PRELOAD +#endif // preloaded caching very tricky, not supported at this time }; +/** + * Generic class for member ID access with selection of caching strategy. + */ template< JniMemberIdCaching M, typename C > struct JniMemberId; @@ -288,6 +432,7 @@ template< typename C > struct JniMemberId< STRONG_CACHING, C > : MemberIdStrongCache< C > {}; +#if 0 // preloaded caching very tricky, not supported at this time template< typename C > struct JniMemberId< WEAK_CACHING_PRELOAD, C > : MemberIdPreloadedWeakCache< C > {}; @@ -295,6 +440,7 @@ struct JniMemberId< WEAK_CACHING_PRELOAD template< typename C > struct JniMemberId< STRONG_CACHING_PRELOAD, C > : MemberIdPreloadedStrongCache< C > {}; +#endif // preloaded caching very tricky, not supported at this time // --------------------------------------------------------------------------- === modified file 'storage/ndb/src/ndbjtie/jtie/jtie_tconv_object.hpp' --- a/storage/ndb/src/ndbjtie/jtie/jtie_tconv_object.hpp 2011-02-02 09:52:33 +0000 +++ b/storage/ndb/src/ndbjtie/jtie/jtie_tconv_object.hpp 2011-07-02 10:09:08 +0000 @@ -44,6 +44,13 @@ struct _jtie_Object : _jobject { // XXX, document: type specifying an Object mapping with a class name // trait type wrapping named-parametrized Object mappings for specialization +// XXX make use of +// JTIE_DEFINE_METHOD_MEMBER_INFO( _jtie_ObjectMapper< T > ) +// to replace +// static const char * const class_name; +// static const char * const member_name; +// static const char * const member_descriptor; +// typedef _jmethodID * memberID_t; template< typename J > struct _jtie_ObjectMapper : _jtie_Object { // the name of the Java peer class in the JVM format (i.e., '/'-separated) @@ -55,11 +62,10 @@ struct _jtie_ObjectMapper : _jtie_Object typedef _jmethodID * memberID_t; }; -// XXX can/should these definitions be moves to _lib ? - +// XXX static initialization <-> multiple compilation units <-> jtie_lib.hpp template< typename J > const char * const _jtie_ObjectMapper< J >::class_name - = J::class_name; + = J::class_name; // XXX static initialization order dependency? template< typename J > const char * const _jtie_ObjectMapper< J >::member_name @@ -214,6 +220,13 @@ const char * const _jtie_ObjectMapper< J #endif // XXX cleanup this unsupported mapping // XXX to document +// XXX static initialization <-> multiple compilation units <-> jtie_lib.hpp +// XXX replace +// template struct MemberId< _jtie_ObjectMapper< T > >; +// template struct MemberIdCache< _jtie_ObjectMapper< T > >; +// with +// JTIE_INSTANTIATE_CLASS_MEMBER_INFO_X(_jtie_ObjectMapper< T >, +// JCN, "", "()V") #define JTIE_INSTANTIATE_PEER_CLASS_MAPPING( T, JCN ) \ const char * const T::class_name = JCN; \ template struct _jtie_ObjectMapper< T >; \ === modified file 'storage/ndb/src/ndbjtie/jtie/jtie_tconv_object_impl.hpp' --- a/storage/ndb/src/ndbjtie/jtie/jtie_tconv_object_impl.hpp 2011-02-02 09:52:33 +0000 +++ b/storage/ndb/src/ndbjtie/jtie/jtie_tconv_object_impl.hpp 2011-07-02 10:09:08 +0000 @@ -40,14 +40,10 @@ // Defines the field info type for Wrapper.cdelegate. JTIE_DEFINE_FIELD_MEMBER_INFO(_Wrapper_cdelegate) -// XXX fix and test _PRELOAD caching - -// Provides a (cached) access to field Id of Wrapper.cdelegate. +// Provides a (cached) access to field Id of Wrapper.cdelegate. //typedef JniMemberId< NO_CACHING, _Wrapper_cdelegate > Wrapper_cdelegate; typedef JniMemberId< WEAK_CACHING, _Wrapper_cdelegate > Wrapper_cdelegate; //typedef JniMemberId< STRONG_CACHING, _Wrapper_cdelegate > Wrapper_cdelegate; -//typedef JniMemberId< WEAK_CACHING_PRELOAD, _Wrapper_cdelegate > Wrapper_cdelegate; -//typedef JniMemberId< STRONG_CACHING_PRELOAD, _Wrapper_cdelegate > Wrapper_cdelegate; // XXX consider changing //template< typename C > struct ObjectParam< _jtie_Object *, C * > { === modified file 'storage/ndb/src/ndbjtie/jtie/jtie_tconv_ptrbybb_impl.hpp' --- a/storage/ndb/src/ndbjtie/jtie/jtie_tconv_ptrbybb_impl.hpp 2011-02-02 09:52:33 +0000 +++ b/storage/ndb/src/ndbjtie/jtie/jtie_tconv_ptrbybb_impl.hpp 2011-07-02 10:09:08 +0000 @@ -132,7 +132,7 @@ struct ByteBufferPtrParam { } else { // ok s = 0; - c = static_cast(a); + c = static_cast< C * >(a); } } } @@ -333,7 +333,7 @@ getBufferPosition(jtie_j_n_ByteBuffer jb inline void * getByteBufferAddress(jtie_j_n_ByteBuffer jbb, JNIEnv * env) { // get the internal buffer address of direct ByteBuffer - char * a = static_cast(env->GetDirectBufferAddress(jbb)); + char * a = static_cast< char * >(env->GetDirectBufferAddress(jbb)); if (a == NULL) { #ifndef JTIE_BYTEBUFFER_NO_ZERO_CAPACITY_MAPPING // check for direct ByteBuffer of zero-capacity --===============5638035109591058994== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/martin.zaun@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: martin.zaun@stripped # target_branch: file:///Users/mz/mysql/ndb-7.1-jtie/ # testament_sha1: 7b3503a2fbd585d65da4d012cd5bb38f5df3c8bc # timestamp: 2011-07-02 03:09:30 -0700 # base_revision_id: maitrayi.sabaratnam@stripped\ # is57kd0av272f2tn # # Begin bundle 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 --===============5638035109591058994==--