Index: vm/vmcore/include/Class.h =================================================================== --- vm/vmcore/include/Class.h (revision 597289) +++ vm/vmcore/include/Class.h (working copy) @@ -966,7 +966,12 @@ // array of fields; size is m_num_fields Field* m_fields; + unsigned long nbuket_field; + unsigned long nchain_field; + unsigned long *bucket_field; + unsigned long *chain_field; + // size of this class' static data block unsigned m_static_data_size; @@ -977,8 +982,17 @@ uint16 m_num_methods; // array of methods; size is m_num_methods + int harmony_class; Method* m_methods; + unsigned int nbucket_method; + unsigned int nchain_method; + unsigned int *bucket_method; + unsigned int *chain_method; + unsigned int nbucket_reduced_method; + unsigned int nchain_reduced_method; + unsigned int *bucket_reduced_method; + unsigned int *chain_reduced_method; // pointer to finalize method, NULL if none exists Method* m_finalize_method; @@ -1667,6 +1681,7 @@ * @return The looked-up method, if found in the given class; * otherwise NULL.*/ Method* lookup_method(const String* name, const String* desc); + Method* lookup_reflection_method(const String* name, const String* desc); /** Allocates an instance of the given class and returns a pointer to it. * @return A managed pointer to the allocated class instance; @@ -1830,6 +1845,9 @@ uint64 get_total_padding_bytes() const { return m_num_field_padding_bytes; } private: + void build_method_hashtable(void); + void build_reflection_method_hashtable(void); + void build_method_hashtable0(void); /*4debugging*/ /** Parses super-interfaces information from a class-file stream. * @param[in] cfs - a class-file stream to parse superinterfaces information from * @return true if information was succesfully parsed; @@ -1965,6 +1983,7 @@ * @return Requested method, if the method exists, * NULL otherwise.*/ Method* class_lookup_method_recursive(Class* clss, const char* name, const char* desc); +Method* class_lookup_reflection_method_recursive(Class* clss, const char* name, const char* desc); /** Looks up method in the given class only. * @param[in] clss - class to lookup method in. * @param[in] name - name of the method. @@ -1972,6 +1991,7 @@ * @return Requested method, if the method exists, * NULL otherwise.*/ Method* class_lookup_method(Class* clss, const char* name, const char* desc); +Method* class_lookup_reflection_method(Class* clss, const char* name, const char* desc); /** Gets method given its offset in the vtable. * @param[in] vt - vtable containing method. * @param[in] offset - offset of the method in the vtable. @@ -2051,5 +2071,5 @@ - +unsigned long hash(const char*); #endif // _CLASS_H_ Index: vm/vmcore/src/jni/jni_utils.cpp =================================================================== --- vm/vmcore/src/jni/jni_utils.cpp (revision 597289) +++ vm/vmcore/src/jni/jni_utils.cpp (working copy) @@ -373,20 +373,11 @@ return NULL; } // LookupField -Method* LookupMethod(Class* clss, const char* mname, const char* mdesc) +Method* LookupMethod(Class* clazz, const char* mname, const char* mdesc) { Method* m = 0; - Class* oclss = clss; - for (; clss; clss = clss->get_super_class()) { // for each superclass - if((m = LookupDeclaredMethod(clss, mname, mdesc))) - return m; - } - - for(int i = 0; i < oclss->get_number_of_superinterfaces(); i++) - if((m = LookupMethod(oclss->get_superinterface(i), mname, mdesc))) - return m; - - return NULL; // method not found + m = class_lookup_reflection_method_recursive(clazz, mname, (mdesc == NULL?"()":mdesc)); + return m; } // LookupMethod char PrimitiveNameToSignature (const char* name) @@ -554,24 +545,9 @@ Method* LookupDeclaredMethod(Class *clss, const char *mname, const char *mdesc) { - String *method_name = VM_Global_State::loader_env->string_pool.lookup(mname); - - size_t len = strlen (mdesc); Method *m = 0; - for (unsigned i =0; i < clss->get_number_of_methods(); i++) { // for each method - m = clss->get_method(i); - if (m->is_fake_method()) { - continue; // ignore fake methods - } - const char* desc = m->get_descriptor()->bytes; - if ((m->get_name() == method_name) // if names and signatures - && (strncmp (mdesc, desc, len) == 0)) // (excluding return types) match - { - return m; // return method - } - } - - return NULL; // method not found + m = class_lookup_reflection_method(clss, mname, (mdesc == NULL?"()":mdesc)); + return m; } // LookupDeclaredMethod //Checks if the object is null. Index: vm/vmcore/src/reflection/reflection.cpp =================================================================== --- vm/vmcore/src/reflection/reflection.cpp (revision 597289) +++ vm/vmcore/src/reflection/reflection.cpp (working copy) @@ -34,6 +34,7 @@ #include "exceptions.h" #include "heap.h" #include "primitives_support.h" +#include "native_utils.h" jclass descriptor_to_jclass(Type_Info_Handle desc){ Class_Handle clss = type_info_get_class(desc); @@ -83,6 +84,7 @@ "(JLjava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V"); Method* member_constr = type->lookup_method(genv->Init_String, desc); + if (member == NULL) return (NULL); jstring jname = String_to_interned_jstring(member->get_name()); if (jname == NULL) { assert(exn_raised()); @@ -285,6 +287,32 @@ return member_array; } // reflection_get_class_methods +jobject reflection_findMatchingMethod(JNIEnv* jenv, jclass clazz, jstring method_name, jobjectArray args) +{ + char *sign; + Method *meth; + Class_Handle clss = jni_get_class_handle(jenv, clazz); + jint l; + TRACE("get class methods : " << class_get_name(clss)); + + sign = ParameterTypesToMethodSignature(jenv, args, class_get_name(clss)); + meth = LookupMethod(clss, JavaStringToCharArray(jenv, method_name, &l), sign?sign:"()"); + return (reflection_reflect_method(jenv, meth)); +} + +jobject reflection_findMatchingDeclaredMethod(JNIEnv* jenv, jclass clazz, jstring method_name, jobjectArray args) +{ + char *sign; + Method *meth; + Class_Handle clss = jni_get_class_handle(jenv, clazz); + jint l; + TRACE("get class methods : " << class_get_name(clss)); + + sign = ParameterTypesToMethodSignature(jenv, args, class_get_name(clss)); + meth = LookupDeclaredMethod(clss, JavaStringToCharArray(jenv, method_name, &l), sign?sign:"()"); + return (reflection_reflect_method(jenv, meth)); +} + /* The following function eases conversion from jobjectArray parameters to JNI friendly jvalue array. Index: vm/vmcore/src/kernel_classes/native/java_lang_VMClassRegistry.cpp =================================================================== --- vm/vmcore/src/kernel_classes/native/java_lang_VMClassRegistry.cpp (revision 597289) +++ vm/vmcore/src/kernel_classes/native/java_lang_VMClassRegistry.cpp (working copy) @@ -627,3 +627,20 @@ String* str = clazz->get_simple_name(); return str ? String_to_interned_jstring(str) : NULL; } + +jobject reflection_findMatchingMethod(JNIEnv *, jclass, jstring, jstring); +jobject reflection_findMatchingDeclaredMethod(JNIEnv *, jclass, jstring, jstring); + +JNIEXPORT jobject JNICALL Java_java_lang_VMClassRegistry_findMatchingMethod +(JNIEnv *jenv, jclass self, jclass clazz, jstring methodname, jobjectArray arg) +{ + + return reflection_findMatchingMethod(jenv, clazz, methodname, arg); +} + +JNIEXPORT jobject JNICALL Java_java_lang_VMClassRegistry_findMatchingDeclaredMethod +(JNIEnv *jenv, jclass self, jclass clazz, jstring methodname, jobjectArray arg) +{ + + return reflection_findMatchingDeclaredMethod(jenv, clazz, methodname, arg); +} Index: vm/vmcore/src/kernel_classes/native/java_lang_VMClassRegistry.h =================================================================== --- vm/vmcore/src/kernel_classes/native/java_lang_VMClassRegistry.h (revision 597289) +++ vm/vmcore/src/kernel_classes/native/java_lang_VMClassRegistry.h (working copy) @@ -209,6 +209,12 @@ JNIEXPORT jstring JNICALL Java_java_lang_VMClassRegistry_getSimpleName (JNIEnv *, jclass, jclass); +JNIEXPORT jobject JNICALL Java_java_lang_VMClassRegistry_findMatchingMethod +(JNIEnv *, jclass , jclass , jstring, jobjectArray ); + +JNIEXPORT jobject JNICALL Java_java_lang_VMClassRegistry_findMatchingDeclaredMethod +(JNIEnv *, jclass , jclass , jstring , jobjectArray ); + #ifdef __cplusplus } #endif Index: vm/vmcore/src/kernel_classes/javasrc/java/lang/VMClassRegistry.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/java/lang/VMClassRegistry.java (revision 597289) +++ vm/vmcore/src/kernel_classes/javasrc/java/lang/VMClassRegistry.java (working copy) @@ -302,4 +302,7 @@ * @api2vm */ static native void loadLibrary(String filename, ClassLoader loader); + + static native Method findMatchingMethod(Class clazz, String methodName, Class[] args); + static native Method findMatchingDeclaredMethod(Class clazz, String methodName, Class[] args); } Index: vm/vmcore/src/kernel_classes/javasrc/java/lang/Class.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/java/lang/Class.java (revision 597289) +++ vm/vmcore/src/kernel_classes/javasrc/java/lang/Class.java (working copy) @@ -392,16 +392,12 @@ */ public Method getDeclaredMethod(String methodName, Class... argumentTypes) throws NoSuchMethodException { - if (reflectionData == null) { - initReflectionData(); - } + checkMemberAccess(Member.DECLARED); - if (reflectionData.declaredMethods == null) { - reflectionData.initDeclaredMethods(); - } + Method m = VMClassRegistry.findMatchingDeclaredMethod(this, methodName, argumentTypes); + if (m == null) throw new NoSuchMethodException("No such method " + methodName); return Reflection - .copyMethod(findMatchingMethod(reflectionData.declaredMethods, - methodName, argumentTypes)); + .copyMethod(m); } /** @@ -465,13 +461,12 @@ */ public Method getMethod(String methodName, Class... argumentTypes) throws NoSuchMethodException { - if (reflectionData == null) { - initReflectionData(); - } + checkMemberAccess(Member.PUBLIC); + Method m = VMClassRegistry.findMatchingMethod(this, methodName, argumentTypes); + if (m == null) throw new NoSuchMethodException("No such method" + methodName); return Reflection - .copyMethod(findMatchingMethod(reflectionData.getPublicMethods(), - methodName, argumentTypes)); + .copyMethod(m); } /** Index: vm/vmcore/src/class_support/Class.cpp =================================================================== --- vm/vmcore/src/class_support/Class.cpp (revision 597289) +++ vm/vmcore/src/class_support/Class.cpp (working copy) @@ -418,10 +418,51 @@ // Field* Class::lookup_field(const String* name, const String* desc) { +#if 0 for(uint16 i = 0; i < m_num_fields; i++) { if(m_fields[i].get_name() == name && m_fields[i].get_descriptor() == desc) return &m_fields[i]; } +#else + + Field *fd; + char key[1024]; + unsigned long h, x, y; + if(m_num_fields == 0) + return (NULL); + memset(key, 0, 1024); + strncat(key, name->bytes, name->len); + strncat(key, desc->bytes, desc->len); + + h = hash(key); + y = h%nbuket_field; + fd = &m_fields[y]; + if (fd->get_name() == name + && fd->get_descriptor() == desc) + return (fd); + for (x = bucket_field[y]; 1 ; x = chain_field[x]) { + if (x == (unsigned long)~0) + break; + fd = &m_fields[x]; + + if (fd->get_name() == name + && fd->get_descriptor() == desc) { + return (fd); + } + + } + + if (nchain_field == m_num_fields) return(NULL); + for(uint16 i = 0; i < m_num_fields; i++) { + if(m_fields[i].get_name() == name && m_fields[i].get_descriptor() == desc) { + /*Some times hash_miss happends , on IOffice startup scenario there are two hash misses*/ +// fprintf("Hash miss!!!!\n"); + return &m_fields[i]; + } + } + + +#endif return NULL; } // Class::lookup_field @@ -459,14 +500,96 @@ return field; } // Class::lookup_field_recursive +Method* Class::lookup_reflection_method(const String* name, const String* desc) +{ + Method *mc; + char key[1024]; + unsigned long h, x, y; + const char *tr; + if(m_num_methods == 0) + return (NULL); + key[0] = 0; + strncat(key, name->bytes, name->len); + key[name->len] = 0; + strncat(key+name->len, desc->bytes, desc->len); + key[name->len+desc->len] = 0; + tr = strchr(desc->bytes,')'); + tr++; + h = hash(key); + y = h%nbucket_reduced_method; + mc = &m_methods[y]; + //fprintf(stderr, "%s:%s %s::%s:%s\n", name->bytes, desc->bytes, get_name()->bytes,mc->get_name()->bytes, mc->get_descriptor()->bytes); + if (mc->get_name() == name + && strncmp(mc->get_descriptor()->bytes, desc->bytes, desc->len) == 0) { + return (mc); + } + for (x = bucket_reduced_method[y]; 1 ; x = chain_reduced_method[x]) { + if (x == (unsigned long)~0) + break; + mc = &m_methods[x]; + + //fprintf(stderr,"%s:%s %s::%s:%s\n", name->bytes, desc->bytes, get_name()->bytes, mc->get_name()->bytes, mc->get_descriptor()->bytes); + if (mc->get_name() == name + && strncmp(mc->get_descriptor()->bytes, desc->bytes, desc->len) == 0) { + return (mc); + } + } + if (nchain_method == m_num_methods) + return(NULL); + + for(unsigned i = 0; i < m_num_methods; i++) { + if (m_methods[i].get_name() == name ) { + if (strncmp(m_methods[i].get_descriptor()->bytes, desc->bytes, desc->len) == 0) + return &m_methods[i]; + } + } + + return(NULL); + +} // Class::lookup_reflection_method + Method* Class::lookup_method(const String* name, const String* desc) { + Method *mc; + char key[1024]; + unsigned long h, x, y; + if(m_num_methods == 0) + return (NULL); + key[0] = 0; + strncat(key, name->bytes, name->len); + key[name->len] = 0; + strncat(key+name->len, desc->bytes, desc->len); + key[name->len+desc->len] = 0; + + h = hash(key); + y = h%nbucket_method; + mc = &m_methods[y]; + if (mc->get_name() == name + && mc->get_descriptor() == desc) + return (mc); + x = bucket_method[y]; + while (x != (unsigned int)~0) { + mc = &m_methods[x]; + + if (mc->get_name() == name + && mc->get_descriptor() == desc) { + return (mc); + } + x = chain_method[x]; + + } + if (nchain_method == m_num_methods) + return(NULL); + for(unsigned i = 0; i < m_num_methods; i++) { - if(m_methods[i].get_name() == name && m_methods[i].get_descriptor() == desc) - return &m_methods[i]; + if (m_methods[i].get_name() == name ) { + if (m_methods[i].get_descriptor() == desc) + return &m_methods[i]; + } } - return NULL; + + return(NULL); } // Class::lookup_method @@ -537,24 +660,47 @@ assert(clss); Method *m = 0; Class *oclss = clss; - m = clss->lookup_method(name, desc); + m = oclss->lookup_method(name, desc); if(m)return m; - for(clss = clss->get_super_class(); clss && !m; clss = clss->get_super_class()) { - m = class_lookup_method_recursive(clss, name, desc); + for(oclss = oclss->get_super_class(); oclss && !m; oclss = oclss->get_super_class()) { + m = class_lookup_method_recursive(oclss, name, desc); } if(m)return m; //if not found, search in interfaces, that means // clss itself is also interface + oclss = clss; for(int i = 0; i < oclss->get_number_of_superinterfaces(); i++) if((m = class_lookup_method_recursive(oclss->get_superinterface(i), name, desc))) return m; return NULL; } //class_lookup_method_recursive +Method* class_lookup_reflection_method_recursive(Class *clss, const String* name, const String* desc) +{ + assert(clss); + Method *m = 0; + Class *oclss = clss; + m = oclss->lookup_reflection_method(name, desc); + if(m)return m; + for(oclss = oclss->get_super_class(); oclss && !m; oclss = oclss->get_super_class()) { + m = class_lookup_reflection_method_recursive(oclss, name, desc); + } + if(m)return m; + //if not found, search in interfaces, that means + // clss itself is also interface + oclss = clss; + for(int i = 0; i < oclss->get_number_of_superinterfaces(); i++) + if((m = class_lookup_reflection_method_recursive(oclss->get_superinterface(i), name, desc))) + return m; + return NULL; +} //class_lookup_method_recursive + + + Method *class_lookup_method_recursive(Class *clss, const char *name, const char *descr) @@ -567,7 +713,18 @@ return class_lookup_method_recursive(clss, method_name, method_descr); } //class_lookup_method_recursive +Method *class_lookup_reflection_method_recursive(Class *clss, + const char *name, + const char *descr) +{ + String *method_name = + VM_Global_State::loader_env->string_pool.lookup(name); + String *method_descr = + VM_Global_State::loader_env->string_pool.lookup(descr); + return class_lookup_reflection_method_recursive(clss, method_name, method_descr); +} //class_lookup_method_recursive + Method* class_lookup_method(Class* clss, const char* name, const char* descr) @@ -580,6 +737,18 @@ return clss->lookup_method(method_name, method_descr); } // class_lookup_method +Method* class_lookup_reflection_method(Class* clss, + const char* name, + const char* descr) +{ + String* method_name = + VM_Global_State::loader_env->string_pool.lookup(name); + String* method_descr = + VM_Global_State::loader_env->string_pool.lookup(descr); + + return clss->lookup_reflection_method(method_name, method_descr); +} // class_lookup_method + Method* class_get_method_from_vt_offset(VTable* vt, unsigned offset) { Index: vm/vmcore/src/class_support/Class_File_Loader.cpp =================================================================== --- vm/vmcore/src/class_support/Class_File_Loader.cpp (revision 597289) +++ vm/vmcore/src/class_support/Class_File_Loader.cpp (working copy) @@ -2176,7 +2176,16 @@ m_fields = new Field[m_num_fields]; // ppervov: FIXME: should throw OOME + char key[1024]; + nchain_field = (unsigned long)num_fields_in_class_file; + nbuket_field = nchain_field>10?nchain_field/10:nchain_field; + chain_field = (unsigned long *)STD_MALLOC(sizeof(unsigned long) * nchain_field); + memset(chain_field, (unsigned long)~0, sizeof(unsigned long) * nchain_field); + bucket_field = (unsigned long *)STD_MALLOC(sizeof(unsigned long) * nbuket_field); + memset(bucket_field, (unsigned long)~0, sizeof(unsigned long) * nbuket_field); + m_num_static_fields = 0; + unsigned short j; unsigned short last_nonstatic_field = (unsigned short)num_fields_in_class_file; for(i=0; i < num_fields_in_class_file; i++) { Field fd; @@ -2184,16 +2193,35 @@ return false; if(fd.is_static()) { m_fields[m_num_static_fields] = fd; + j = m_num_static_fields; m_num_static_fields++; } else { last_nonstatic_field--; + j = last_nonstatic_field; m_fields[last_nonstatic_field] = fd; } + unsigned long x,y; + memset(key, 0, 1024); + strncat(key, m_fields[j].get_name()->bytes, m_fields[j].get_name()->len); + strncat(key, m_fields[j].get_descriptor()->bytes, m_fields[j].get_descriptor()->len); + unsigned long h = hash(key); + y = h%nbuket_field; + if (bucket_field[y] == (unsigned long)~0) { + bucket_field[y] = j; + } else { + x = bucket_field[y]; + while (chain_field[x] != (unsigned long)~0) { + x = chain_field[x]; + } + chain_field[x] = j; + } + } assert(last_nonstatic_field == m_num_static_fields); //See specification 4.6 Fields: //No two fields in one class file may have the same name and descriptor. +#if 0 for (int j = 0; j < num_fields_in_class_file; j++){ for(int k = j + 1; k < num_fields_in_class_file; k++){ if((m_fields[j].get_name() == m_fields[k].get_name()) @@ -2205,6 +2233,7 @@ } } } +#endif for(i = 0; i < int(sizeof(vm_extra_fields)/sizeof(VMExtraFieldDescription)); i++) { if(get_name() == vm_extra_fields[i].classname) { @@ -2230,6 +2259,86 @@ long _total_method_bytes = 0; +void Class::build_method_hashtable() { + char key[1024]; + nchain_method = (unsigned long)m_num_methods; + nbucket_method = nchain_method>20?nchain_method/10:nchain_method; + chain_method = (unsigned int *)STD_MALLOC(sizeof(unsigned long) * nchain_method); + memset(chain_method, (unsigned int)~0, sizeof(unsigned long) * nchain_method); + bucket_method = (unsigned int *)STD_MALLOC(sizeof(unsigned long) * nbucket_method); + memset(bucket_method, (unsigned int)~0, sizeof(unsigned long) * nbucket_method); + + for(unsigned i = 0; i < m_num_methods; i++) { + + //fprintf(stderr,"<<%s::%s:%s\n", get_name()->bytes,m_methods[i].get_name()->bytes, m_methods[i].get_descriptor()->bytes); + unsigned long x,y; + int namelen = m_methods[i].get_name()->len; + int siglen =m_methods[i].get_descriptor()->len; + Method* m = &m_methods[i]; + String *name = m_methods[i].get_name(); + strncpy(key, m_methods[i].get_name()->bytes, namelen); + key[namelen] = 0; + strncat(key, m_methods[i].get_descriptor()->bytes, siglen); + key[namelen + siglen] = 0; + unsigned long h = hash(key); + y = h%nbucket_method; + if (bucket_method[y] == (unsigned long)~0) { + bucket_method[y] = i; + } else { + x = bucket_method[y]; + while (chain_method[x] != (unsigned long)~0) { + x = chain_method[x]; + } + chain_method[x] = i; + } + } +} + +void Class::build_reflection_method_hashtable() { + char key[1024]; + + nchain_reduced_method= (unsigned int)m_num_methods; + nbucket_reduced_method = nchain_reduced_method>20?nchain_reduced_method/10:nchain_reduced_method; + chain_reduced_method = (unsigned int *)STD_MALLOC(sizeof(unsigned int) * nchain_reduced_method); + memset(chain_reduced_method, (unsigned int)~0, sizeof(unsigned int) * nchain_reduced_method); + bucket_reduced_method = (unsigned int *)STD_MALLOC(sizeof(unsigned int) * nbucket_reduced_method); + memset(bucket_reduced_method, (unsigned int)~0, sizeof(unsigned int) * nbucket_reduced_method); + + for(unsigned i = 0; i < m_num_methods; i++) { + + unsigned long x,y; + int namelen = m_methods[i].get_name()->len; + int siglen =m_methods[i].get_descriptor()->len; + Method* m = &m_methods[i]; + String *name = m_methods[i].get_name(); + strncpy(key, m_methods[i].get_name()->bytes, namelen); + key[namelen] = 0; + strncat(key, m_methods[i].get_descriptor()->bytes, siglen); + key[namelen + siglen] = 0; + if (m->is_fake_method() == 0 + && m->is_init() == 0 + && m->is_clinit() == 0) { + char *tr = strchr(key, ')'); + if (tr != NULL) { + *(++tr) = '\0'; + unsigned long h = hash(key); + y = h%nbucket_reduced_method; + if (bucket_reduced_method[y] == (unsigned long)~0) { + bucket_reduced_method[y] = i; + } else { + x = bucket_reduced_method[y]; + while (chain_reduced_method[x] != (unsigned long)~0) { + x = chain_reduced_method[x]; + } + chain_reduced_method[x] = i; + } + } + } + + } +} + + bool Class::parse_methods(Global_Env* env, ByteReader &cfs, bool is_trusted_cl) { if(!cfs.parse_u2_be(&m_num_methods)) { @@ -2247,8 +2356,7 @@ return false; } - Method* m = &m_methods[i]; - if(m->is_clinit()) { + if(m_methods[i].is_clinit()) { // There can be at most one clinit per class. if(m_static_initializer) { REPORT_FAILED_CLASS_FORMAT(this, ": there is more than one class initialization method"); @@ -2257,8 +2365,8 @@ m_static_initializer = &(m_methods[i]); } // to cache the default constructor - if (m->get_name() == VM_Global_State::loader_env->Init_String - && m->get_descriptor() == VM_Global_State::loader_env->VoidVoidDescriptor_String) + if (m_methods[i].get_name() == VM_Global_State::loader_env->Init_String + && m_methods[i].get_descriptor() == VM_Global_State::loader_env->VoidVoidDescriptor_String) { m_default_constructor = &m_methods[i]; } @@ -2266,6 +2374,7 @@ //See specification 4.7 Methods: //No two methods in one class file may have the same name and descriptor. +#if 0 for (int j = 0; j < m_num_methods; j++){ for(int k = j + 1; k < m_num_methods; k++){ if((m_methods[j].get_name() == m_methods[k].get_name()) @@ -2277,7 +2386,7 @@ } } } - +#endif return true; // success } //class_parse_methods @@ -3326,7 +3435,8 @@ "InnerClasses presence for class {0}" << m_name->bytes); } - + build_method_hashtable(); + build_reflection_method_hashtable(); return true; } // Class::parse @@ -3505,3 +3615,34 @@ Class *clss = env->bootstrap_class_loader->LoadVerifyAndPrepareClass(env, classname); return clss; } +#if 0 + +unsigned long +hash(const char *name) +{ + const unsigned char *p = (const unsigned char *) name; + unsigned long h = 0; + unsigned long g; + unsigned long c; + + for (; ((c = *p) != '\0'); p++) { + h <<= 4; + h += c; + if ((g = h & 0xf0000000) != 0) { + h ^= g; + h ^= g >> 24; + } + } + return (h); +} +#else +unsigned long +hash(const char *s) +{ + unsigned char c; + unsigned long h = 5381; + for (c = *s; (c != '\0'); c = *++s) + h = h * 33 + c; + return h & 0xffffffff; +} +#endif