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

Reply via email to