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