Return-Path: X-Original-To: apmail-subversion-commits-archive@minotaur.apache.org Delivered-To: apmail-subversion-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 2A18110322 for ; Fri, 22 Nov 2013 10:33:29 +0000 (UTC) Received: (qmail 25197 invoked by uid 500); 22 Nov 2013 10:33:28 -0000 Delivered-To: apmail-subversion-commits-archive@subversion.apache.org Received: (qmail 25055 invoked by uid 500); 22 Nov 2013 10:33:25 -0000 Mailing-List: contact commits-help@subversion.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@subversion.apache.org Delivered-To: mailing list commits@subversion.apache.org Received: (qmail 25041 invoked by uid 99); 22 Nov 2013 10:33:22 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 22 Nov 2013 10:33:22 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED,T_FILL_THIS_FORM_SHORT X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 22 Nov 2013 10:33:18 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 13CE523889CB; Fri, 22 Nov 2013 10:32:56 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1544467 - in /subversion/trunk/subversion/bindings/javahl/native/jniwrapper: jni_class_cache.cpp jni_list.cpp jni_list.hpp jni_object.hpp jni_string_map.cpp jni_string_map.hpp Date: Fri, 22 Nov 2013 10:32:55 -0000 To: commits@subversion.apache.org From: brane@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20131122103256.13CE523889CB@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: brane Date: Fri Nov 22 10:32:55 2013 New Revision: 1544467 URL: http://svn.apache.org/r1544467 Log: Begin converting newstyle JavaHL native classes to cache all method and field IDs. Since we do cache some classes, and they won't be unloaded until the classloader is GC'd, and field and method IDs are immutable for the lifetime of said classes ... we may as well cache the whole shebang. [in subversion/bindings/javahl] * native/jniwrapper/jni_object.hpp (ClassCache): Declare new cached classes: list, array_list, map, set, iterator, map_entry, hash_map. * native/jniwrapper/jni_class_cache.cpp (ClassCache::ClassCache): Init members and call static initializers for wrapped classes: BaseList, BaseMutableList, BaseMap, BaseMap::Set, BaseMap::Iterator, BaseMap::Entry and BaseMutableMap. * native/jniwrapper/jni_list.hpp, native/jniwrapper/jni_list.cpp, native/jniwrapper/jni_string_map.hpp, native/jniwrapper/jni_string_map.cpp: Convert all wrapper classes to init static method IDs and use the cached class references. Modified: subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_class_cache.cpp subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_list.cpp subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_list.hpp subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_object.hpp subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_string_map.cpp subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_string_map.hpp Modified: subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_class_cache.cpp URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_class_cache.cpp?rev=1544467&r1=1544466&r2=1544467&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_class_cache.cpp (original) +++ subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_class_cache.cpp Fri Nov 22 10:32:55 2013 @@ -30,6 +30,9 @@ #include "jni_object.hpp" #include "jni_string.hpp" +#include "jni_list.hpp" +#include "jni_string_map.hpp" + #include "../SubversionException.hpp" namespace Java { @@ -90,6 +93,15 @@ ClassCache::ClassCache(Env env) SVN_JAVAHL_JNIWRAPPER_CLASS_CACHE_INIT(throwable, Exception), SVN_JAVAHL_JNIWRAPPER_CLASS_CACHE_INIT(string, String), + SVN_JAVAHL_JNIWRAPPER_CLASS_CACHE_INIT(list, BaseList), + SVN_JAVAHL_JNIWRAPPER_CLASS_CACHE_INIT(array_list, BaseMutableList), + + SVN_JAVAHL_JNIWRAPPER_CLASS_CACHE_INIT(map, BaseMap), + SVN_JAVAHL_JNIWRAPPER_CLASS_CACHE_INIT(set, BaseMap::Set), + SVN_JAVAHL_JNIWRAPPER_CLASS_CACHE_INIT(iterator, BaseMap::Iterator), + SVN_JAVAHL_JNIWRAPPER_CLASS_CACHE_INIT(map_entry, BaseMap::Entry), + SVN_JAVAHL_JNIWRAPPER_CLASS_CACHE_INIT(hash_map, BaseMutableMap), + SVN_JAVAHL_JNIWRAPPER_CLASS_CACHE_INIT(subversion_exception, ::JavaHL::SubversionException) { @@ -98,6 +110,16 @@ ClassCache::ClassCache(Env env) Class::static_init(env); Exception::static_init(env); // no-op: String::static_init(env); + + BaseList::static_init(env); + BaseMutableList::static_init(env); + + BaseMap::static_init(env); + BaseMap::Set::static_init(env); + BaseMap::Iterator::static_init(env); + BaseMap::Entry::static_init(env); + BaseMutableMap::static_init(env); + // no-op: ::JavaHL::SubversionException::static_init(env); } #undef SVN_JAVAHL_JNIWRAPPER_CLASS_CACHE_INIT Modified: subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_list.cpp URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_list.cpp?rev=1544467&r1=1544466&r2=1544467&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_list.cpp (original) +++ subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_list.cpp Fri Nov 22 10:32:55 2013 @@ -29,22 +29,29 @@ namespace Java { const char* const BaseList::m_class_name = "java/util/List"; +MethodID BaseList::m_mid_size; +MethodID BaseList::m_mid_get; + +void BaseList::static_init(Env env) +{ + const jclass cls = ClassCache::get_list(); + m_mid_size = env.GetMethodID(cls, "size", "()I"); + m_mid_get = env.GetMethodID(cls, "get", "(I)Ljava/lang/Object;"); +} + BaseList::ovector -BaseList::convert_to_vector(Env env, jclass cls, jobject jlist) +BaseList::convert_to_vector(Env env, jobject jlist) { - const jint length = env.CallIntMethod( - jlist, env.GetMethodID(cls, "size", "()I")); + const jint length = env.CallIntMethod(jlist, m_mid_size); if (!length) return ovector(); - const jmethodID mid_get = env.GetMethodID(cls, "get", - "(I)Ljava/lang/Object;"); ovector contents(length); ovector::iterator it; jint i; for (i = 0, it = contents.begin(); it != contents.end(); ++it, ++i) - *it = env.CallObjectMethod(jlist, mid_get, i); + *it = env.CallObjectMethod(jlist, m_mid_get, i); return contents; } @@ -53,46 +60,20 @@ BaseList::convert_to_vector(Env env, jcl const char* const BaseMutableList::m_class_name = "java/util/ArrayList"; -namespace { -jobject make_array_list(Env env, const char* class_name, jint length) -{ - const jclass cls = env.FindClass(class_name); - const jmethodID mid_ctor = env.GetMethodID(cls, "", "(I)V"); - return env.NewObject(cls, mid_ctor, length); -} -} // anonymous namespace - -BaseMutableList::BaseMutableList(Env env, jint length) - : Object(env, m_class_name, - make_array_list(env, m_class_name, length)) -{} - -void BaseMutableList::add(jobject obj) -{ - if (!m_mid_add) - m_mid_add = m_env.GetMethodID(m_class, "add", "(Ljava/lang/Object;)Z"); - m_env.CallBooleanMethod(m_jthis, m_mid_add, obj); -} - -void BaseMutableList::clear() -{ - if (!m_mid_clear) - m_mid_clear = m_env.GetMethodID(m_class, "clear", "()V"); - m_env.CallVoidMethod(m_jthis, m_mid_clear); -} - -jobject BaseMutableList::operator[](jint index) const -{ - if (!m_mid_get) - m_mid_get = m_env.GetMethodID(m_class, "get", "(I)Ljava/lang/Object;"); - return m_env.CallObjectMethod(m_jthis, m_mid_get, index); -} - -jint BaseMutableList::length() const -{ - if (!m_mid_size) - m_mid_size = m_env.GetMethodID(m_class, "size", "()I"); - return m_env.CallIntMethod(m_jthis, m_mid_size); +MethodID BaseMutableList::m_mid_ctor; +MethodID BaseMutableList::m_mid_add; +MethodID BaseMutableList::m_mid_clear; +MethodID BaseMutableList::m_mid_get; +MethodID BaseMutableList::m_mid_size; + +void BaseMutableList::static_init(Env env) +{ + const jclass cls = ClassCache::get_array_list(); + m_mid_ctor = env.GetMethodID(cls, "", "(I)V"); + m_mid_add = env.GetMethodID(cls, "add", "(Ljava/lang/Object;)Z"); + m_mid_clear = env.GetMethodID(cls, "clear", "()V"); + m_mid_get = env.GetMethodID(cls, "get", "(I)Ljava/lang/Object;"); + m_mid_size = env.GetMethodID(cls, "size", "()I"); } } // namespace Java Modified: subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_list.hpp URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_list.hpp?rev=1544467&r1=1544466&r2=1544467&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_list.hpp (original) +++ subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_list.hpp Fri Nov 22 10:32:55 2013 @@ -58,8 +58,8 @@ protected: * @c std::vector. */ explicit BaseList(Env env, jobject jlist) - : Object(env, m_class_name, jlist), - m_contents(convert_to_vector(env, m_class, m_jthis)) + : Object(env, ClassCache::get_list(), jlist), + m_contents(convert_to_vector(env, m_jthis)) {} /** @@ -74,8 +74,12 @@ protected: const ovector m_contents; private: + friend class ClassCache; + static void static_init(Env env); static const char* const m_class_name; - static ovector convert_to_vector(Env env, jclass cls, jobject jlist); + static MethodID m_mid_size; + static MethodID m_mid_get; + static ovector convert_to_vector(Env env, jobject jlist); }; /** @@ -148,12 +152,18 @@ public: /** * Clears the contents of the list. */ - void clear(); + void clear() + { + m_env.CallVoidMethod(m_jthis, m_mid_clear); + } /** * Returns the number of elements in the list. */ - jint length() const; + jint length() const + { + return m_env.CallIntMethod(m_jthis, m_mid_size); + } /** * Checks if the list is empty. @@ -175,25 +185,38 @@ protected: * Constructs and wraps an empty list of type @c java.util.ArrayList * with initial allocation size @a length. */ - explicit BaseMutableList(Env env, jint length); + explicit BaseMutableList(Env env, jint length) + : Object(env, ClassCache::get_array_list(), + env.NewObject(ClassCache::get_array_list(), m_mid_ctor, length)) + {} + /** * Appends @a obj to the end of the list. */ - void add(jobject obj); + void add(jobject obj) + { + m_env.CallBooleanMethod(m_jthis, m_mid_add, obj); + } /** * Returns the object reference at @a index. * @note Throws a Java exception if the index value is not valid. */ - jobject operator[](jint index) const; + jobject operator[](jint index) const + { + return m_env.CallObjectMethod(m_jthis, m_mid_get, index); + } private: + friend class ClassCache; + static void static_init(Env env); static const char* const m_class_name; - MethodID m_mid_add; - MethodID m_mid_clear; - mutable MethodID m_mid_get; - mutable MethodID m_mid_size; + static MethodID m_mid_ctor; + static MethodID m_mid_add; + static MethodID m_mid_clear; + static MethodID m_mid_get; + static MethodID m_mid_size; }; /** Modified: subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_object.hpp URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_object.hpp?rev=1544467&r1=1544466&r2=1544467&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_object.hpp (original) +++ subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_object.hpp Fri Nov 22 10:32:55 2013 @@ -145,6 +145,16 @@ class ClassCache SVN_JAVAHL_JNIWRAPPER_CACHED_CLASS(classtype); SVN_JAVAHL_JNIWRAPPER_CACHED_CLASS(throwable); SVN_JAVAHL_JNIWRAPPER_CACHED_CLASS(string); + + SVN_JAVAHL_JNIWRAPPER_CACHED_CLASS(list); + SVN_JAVAHL_JNIWRAPPER_CACHED_CLASS(array_list); + + SVN_JAVAHL_JNIWRAPPER_CACHED_CLASS(map); + SVN_JAVAHL_JNIWRAPPER_CACHED_CLASS(set); + SVN_JAVAHL_JNIWRAPPER_CACHED_CLASS(iterator); + SVN_JAVAHL_JNIWRAPPER_CACHED_CLASS(map_entry); + SVN_JAVAHL_JNIWRAPPER_CACHED_CLASS(hash_map); + SVN_JAVAHL_JNIWRAPPER_CACHED_CLASS(subversion_exception); #undef SVN_JAVAHL_JNIWRAPPER_CACHED_CLASS Modified: subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_string_map.cpp URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_string_map.cpp?rev=1544467&r1=1544466&r2=1544467&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_string_map.cpp (original) +++ subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_string_map.cpp Fri Nov 22 10:32:55 2013 @@ -31,6 +31,43 @@ namespace Java { // Class Java::BaseMap const char* const BaseMap::m_class_name = "java/util/Map"; +MethodID BaseMap::m_mid_size; +MethodID BaseMap::m_mid_entry_set; +void BaseMap::static_init(Env env) +{ + const jclass cls = ClassCache::get_map(); + m_mid_size = env.GetMethodID(cls, "size", "()I"); + m_mid_entry_set = env.GetMethodID(cls, "entrySet", "()Ljava/util/Set;"); +} + +const char* const BaseMap::Set::m_class_name = "java/util/Set"; +MethodID BaseMap::Set::m_mid_iterator; +void BaseMap::Set::static_init(Env env) +{ + m_mid_iterator = env.GetMethodID(ClassCache::get_set(), "iterator", + "()Ljava/util/Iterator;"); +} + +const char* const BaseMap::Iterator::m_class_name = "java/util/Iterator"; +MethodID BaseMap::Iterator::m_mid_has_next; +MethodID BaseMap::Iterator::m_mid_next; +void BaseMap::Iterator::static_init(Env env) +{ + const jclass cls = ClassCache::get_iterator(); + m_mid_has_next = env.GetMethodID(cls, "hasNext", "()Z"); + m_mid_next = env.GetMethodID(cls, "next", "()Ljava/lang/Object;"); +} + +const char* const BaseMap::Entry::m_class_name = "java/util/Map$Entry"; +MethodID BaseMap::Entry::m_mid_get_key; +MethodID BaseMap::Entry::m_mid_get_value; +void BaseMap::Entry::static_init(Env env) +{ + const jclass cls = ClassCache::get_map_entry(); + m_mid_get_key = env.GetMethodID(cls, "getKey", "()Ljava/lang/Object;"); + m_mid_get_value = env.GetMethodID(cls, "getValue", "()Ljava/lang/Object;"); +} + jobject BaseMap::operator[](const std::string& index) const { @@ -44,37 +81,25 @@ jobject BaseMap::operator[](const std::s return it->second; } -BaseMap::somap BaseMap::convert_to_map(Env env, jclass cls, jobject jmap) +BaseMap::somap BaseMap::convert_to_map(Env env, jobject jmap) { - if (!env.CallIntMethod(jmap, env.GetMethodID(cls, "size", "()I"))) + if (!env.CallIntMethod(jmap, m_mid_size)) return somap(); // Get an iterator over the map's entry set - const jobject entries = env.CallObjectMethod( - jmap, env.GetMethodID(cls, "entrySet", "()Ljava/util/Set;")); - const jobject iterator = env.CallObjectMethod( - entries, env.GetMethodID(env.GetObjectClass(entries), "iterator", - "()Ljava/util/Iterator;")); - const jclass cls_iterator = env.GetObjectClass(iterator); - const jmethodID mid_it_has_next = env.GetMethodID(cls_iterator, - "hasNext", "()Z"); - const jmethodID mid_it_next = env.GetMethodID(cls_iterator, "next", - "()Ljava/lang/Object;"); - - // Find the methods for retreiving the key and value from an entry - const jclass cls_entry = env.FindClass("java/util/Map$Entry"); - const jmethodID mid_get_key = env.GetMethodID(cls_entry, "getKey", - "()Ljava/lang/Object;"); - const jmethodID mid_get_value = env.GetMethodID(cls_entry, "getValue", - "()Ljava/lang/Object;"); + const jobject entries = env.CallObjectMethod(jmap, m_mid_entry_set); + const jobject iterator = env.CallObjectMethod(entries, Set::m_mid_iterator); - // And finally ... iterate over the map, filling the native map + // Yterate over the map, filling the native map somap contents; - while (env.CallBooleanMethod(iterator, mid_it_has_next)) + while (env.CallBooleanMethod(iterator, Iterator::m_mid_has_next)) { - const jobject e = env.CallObjectMethod(iterator, mid_it_next); - const String keystr(env, jstring(env.CallObjectMethod(e, mid_get_key))); - const jobject value(env.CallObjectMethod(e, mid_get_value)); + const jobject entry = + env.CallObjectMethod(iterator, Iterator::m_mid_next); + const String keystr( + env, jstring(env.CallObjectMethod(entry, Entry::m_mid_get_key))); + const jobject value( + env.CallObjectMethod(entry, Entry::m_mid_get_value)); const String::Contents key(keystr); contents.insert(somap::value_type(key.c_str(), value)); } @@ -85,49 +110,31 @@ BaseMap::somap BaseMap::convert_to_map(E const char* const BaseMutableMap::m_class_name = "java/util/HashMap"; -namespace { -jobject make_hash_map(Env env, const char* class_name, jint length) -{ - const jclass cls = env.FindClass(class_name); - const jmethodID mid_ctor = env.GetMethodID(cls, "", "(I)V"); - return env.NewObject(cls, mid_ctor, length); -} -} // anonymous namespace - -BaseMutableMap::BaseMutableMap(Env env, jint length) - : Object(env, m_class_name, - make_hash_map(env, m_class_name, length)) -{} - -void BaseMutableMap::clear() -{ - if (!m_mid_clear) - m_mid_clear = m_env.GetMethodID(m_class, "clear", "()V"); - m_env.CallVoidMethod(m_jthis, m_mid_clear); -} - -jint BaseMutableMap::length() const -{ - if (!m_mid_size) - m_mid_size = m_env.GetMethodID(m_class, "size", "()I"); - return m_env.CallIntMethod(m_jthis, m_mid_size); +MethodID BaseMutableMap::m_mid_ctor; +MethodID BaseMutableMap::m_mid_put; +MethodID BaseMutableMap::m_mid_clear; +MethodID BaseMutableMap::m_mid_has_key; +MethodID BaseMutableMap::m_mid_get; +MethodID BaseMutableMap::m_mid_size; + +void BaseMutableMap::static_init(Env env) +{ + const jclass cls = ClassCache::get_hash_map(); + m_mid_ctor = env.GetMethodID(cls, "", "(I)V"); + m_mid_put = env.GetMethodID(cls, "put", + "(Ljava/lang/Object;Ljava/lang/Object;)" + "Ljava/lang/Object;"); + m_mid_clear = env.GetMethodID(cls, "clear", "()V"); + m_mid_has_key = env.GetMethodID(cls, "containsKey", + "(Ljava/lang/Object;)Z"); + m_mid_get = env.GetMethodID(cls, "get", + "(Ljava/lang/Object;)Ljava/lang/Object;"); + m_mid_size = env.GetMethodID(cls, "size", "()I"); } -void BaseMutableMap::put(const std::string& key, jobject obj) -{ - if (!m_mid_put) - m_mid_put = m_env.GetMethodID(m_class, "put", - "(Ljava/lang/Object;Ljava/lang/Object;)" - "Ljava/lang/Object;"); - m_env.CallObjectMethod(m_jthis, m_mid_put, String(m_env, key).get(), obj); -} jobject BaseMutableMap::operator[](const std::string& index) const { - if (!m_mid_has_key) - m_mid_has_key = m_env.GetMethodID(m_class, "containsKey", - "(Ljava/lang/Object;)Z"); - const String key(m_env, index); if (!m_env.CallBooleanMethod(m_jthis, m_mid_has_key, key.get())) { @@ -135,10 +142,6 @@ jobject BaseMutableMap::operator[](const msg += index; throw std::out_of_range(msg.c_str()); } - - if (!m_mid_get) - m_mid_get = m_env.GetMethodID(m_class, "get", - "(Ljava/lang/Object;)Ljava/lang/Object;"); return m_env.CallObjectMethod(m_jthis, m_mid_get, key.get()); } Modified: subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_string_map.hpp URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_string_map.hpp?rev=1544467&r1=1544466&r2=1544467&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_string_map.hpp (original) +++ subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_string_map.hpp Fri Nov 22 10:32:55 2013 @@ -61,8 +61,8 @@ protected: * @c std::map. */ explicit BaseMap(Env env, jobject jmap) - : Object(env, m_class_name, jmap), - m_contents(convert_to_map(env, m_class, m_jthis)) + : Object(env, ClassCache::get_map(), jmap), + m_contents(convert_to_map(env, m_jthis)) {} /** @@ -74,8 +74,36 @@ protected: const somap m_contents; private: + friend class ClassCache; + static void static_init(Env env); static const char* const m_class_name; - static somap convert_to_map(Env env, jclass cls, jobject jmap); + + struct Set + { + static MethodID m_mid_iterator; + static void static_init(Env env); + static const char* const m_class_name; + }; + + struct Iterator + { + static MethodID m_mid_has_next; + static MethodID m_mid_next; + static void static_init(Env env); + static const char* const m_class_name; + }; + + struct Entry + { + static MethodID m_mid_get_key; + static MethodID m_mid_get_value; + static void static_init(Env env); + static const char* const m_class_name; + }; + + static MethodID m_mid_size; + static MethodID m_mid_entry_set; + static somap convert_to_map(Env env, jobject jmap); }; /** @@ -153,12 +181,18 @@ public: /** * Clears the contents of the map. */ - void clear(); + void clear() + { + m_env.CallVoidMethod(m_jthis, m_mid_clear); + } /** * Returns the number of elements in the map. */ - jint length() const; + jint length() const + { + return m_env.CallIntMethod(m_jthis, m_mid_size); + } /** * Checks if the map is empty. @@ -180,12 +214,20 @@ protected: * Constructs and wraps an empty map of type @c java.util.HashMap * with initial allocation size @a length. */ - explicit BaseMutableMap(Env env, jint length); + explicit BaseMutableMap(Env env, jint length) + : Object(env, ClassCache::get_hash_map(), + env.NewObject(ClassCache::get_hash_map(), m_mid_ctor, length)) + {} + /** * Inserts @a obj identified by @a key into the map. */ - void put(const std::string& key, jobject obj); + void put(const std::string& key, jobject obj) + { + m_env.CallObjectMethod(m_jthis, m_mid_put, + String(m_env, key).get(), obj); + } /** * Returns the object reference identified by @a index. @@ -194,12 +236,15 @@ protected: jobject operator[](const std::string& index) const; private: + friend class ClassCache; + static void static_init(Env env); static const char* const m_class_name; - MethodID m_mid_put; - MethodID m_mid_clear; - mutable MethodID m_mid_has_key; - mutable MethodID m_mid_get; - mutable MethodID m_mid_size; + static MethodID m_mid_ctor; + static MethodID m_mid_put; + static MethodID m_mid_clear; + static MethodID m_mid_has_key; + static MethodID m_mid_get; + static MethodID m_mid_size; }; /**