Array classes have classloader set to the classloader of its element class. For primitive arrays, the classloader is always bootstrap classloader.
This is a bug fix which reveals itself after introducing a classloader-aware cache. Loading of array classes [I and [[I can be initiated with different classloaders. The former is always loaded with bootstrap classloader (primitive array) while loading of the latter can be initiated with any classloader. Class [[I must be eventually loaded with bootstrap classloader too. Signed-off-by: Tomek Grabiec <tgrab...@gmail.com> --- include/vm/types.h | 6 ++++++ vm/classloader.c | 16 +++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/include/vm/types.h b/include/vm/types.h index 4695d9c..1f3350b 100644 --- a/include/vm/types.h +++ b/include/vm/types.h @@ -3,6 +3,7 @@ #include <assert.h> #include <stdbool.h> +#include <string.h> #include "lib/list.h" @@ -62,6 +63,11 @@ static inline int vm_type_slot_size(enum vm_type type) return 1; } +static inline bool is_primitive_array(const char *name) +{ + return name[0] == '[' && name[strlen(name) - 1] != ';'; +} + static inline enum vm_type mimic_stack_type(enum vm_type type) { switch (type) { diff --git a/vm/classloader.c b/vm/classloader.c index 66682a7..e86aba4 100644 --- a/vm/classloader.c +++ b/vm/classloader.c @@ -400,6 +400,7 @@ struct vm_class *classloader_load_primitive(const char *class_name) return NULL; } + class->classloader = NULL; class->primitive_vm_type = str_to_type(class_name); if (vm_class_link_primitive_class(class, class_name)) { @@ -439,6 +440,8 @@ load_array_class(struct vm_object *loader, const char *class_name) else elem_class = classloader_load(loader, elem_class_name); + array_class->classloader = elem_class->classloader; + if (vm_class_link_array_class(array_class, elem_class, class_name)) { signal_new_exception(vm_java_lang_OutOfMemoryError, NULL); return NULL; @@ -505,8 +508,10 @@ static struct vm_class *load_class(struct vm_object *loader, } out_filename: - free(filename); + if (result) + result->classloader = NULL; + free(filename); return result; } @@ -569,6 +574,13 @@ classloader_load(struct vm_object *loader, const char *class_name) vmc = NULL; + /* + * Array classes have classloader set to the classloader of its elements. + * Primitive types are always loaded with bootstrap classloader. + */ + if (is_primitive_array(class_name)) + loader = NULL; + pthread_mutex_lock(&classloader_mutex); class = find_class(slash_class_name); @@ -619,8 +631,6 @@ classloader_load(struct vm_object *loader, const char *class_name) pthread_mutex_lock(&classloader_mutex); - vmc->classloader = loader; - class->class = vmc; class->status = CLASS_LOADED; -- 1.6.0.4 ------------------------------------------------------------------------------ Come build with us! The BlackBerry(R) Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9 - 12, 2009. Register now! http://p.sf.net/sfu/devconference _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel