* src/vmcore/linker.c (build_display): Simplified a bit.
authorStefan Ring <stefan@complang.tuwien.ac.at>
Sun, 23 Nov 2008 11:51:20 +0000 (12:51 +0100)
committerStefan Ring <stefan@complang.tuwien.ac.at>
Sun, 23 Nov 2008 11:51:20 +0000 (12:51 +0100)
* src/vm/builtin.c (fast_subtype_check): Changed comment.

--HG--
branch : subtype

src/vm/builtin.c
src/vmcore/linker.c

index 773ba915c36749d3a26772a7f7a3bce7c2b39891..a4fa2685e0a1b7cdedc8f78f2b90e95457765b3a 100644 (file)
@@ -657,8 +657,9 @@ bool builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o)
 #if USES_NEW_SUBTYPE
 /* fast_subtype_check **********************************************************
 
-   Checks if s is a subtype of t, using the restricted subtype relation (see
-   Cliff Click and John Rose: Fast subtype checking in the Hotspot JVM.)
+   Checks if s is a subtype of t, using both the restricted subtype relation
+   and the overflow array (see Cliff Click and John Rose: Fast subtype checking
+   in the Hotspot JVM.)
 
    RETURN VALUE:
       1......s is a subtype of t.
index 7e53af80ef127dc0051774bcaf0787d838c28c45..f3568c7ee93f63ba1ab41c94f41f07fe4840a619 100644 (file)
@@ -551,78 +551,82 @@ static bool linker_overwrite_method(methodinfo *mg,
 }
 
 
-/* link_class_intern ***********************************************************
+#if USES_NEW_SUBTYPE
+/* build_display ***************************************************************
+
+   Builds the entire display for a class. This entails filling the fixed part
+   as well as allocating and initializing the overflow part.
+
+   See Cliff Click and John Rose: Fast subtype checking in the Hotspot JVM.
 
-   Tries to link a class. The function calculates the length in bytes
-   that an instance of this class requires as well as the VTBL for
-   methods and interface methods.
-       
 *******************************************************************************/
 
-#if USES_NEW_SUBTYPE
-static int build_display_inner(classinfo *topc, classinfo *c, int i)
+static void build_display(classinfo *c)
 {
-       int depth;
-       if (!c)
-               return 0;
+       int depth, i;
+       int depth_fixed;
+       classinfo *super;
+
        do {
-               if (c->vftbl->arraydesc)
-               {
+               /* Handle arrays. */
+               if (c->vftbl->arraydesc) {
                        arraydescriptor *a = c->vftbl->arraydesc;
-                       if (a->elementvftbl && a->elementvftbl->clazz->super)
-                       {
+                       if (a->elementvftbl && a->elementvftbl->clazz->super) {
                                classinfo *cls = a->elementvftbl->clazz->super;
                                int n;
                                for (n=0; n<a->dimension; n++)
                                        cls = class_array_of(cls, true);
-                               depth = build_display_inner(topc, cls, i+1);
+                               super = cls;
                                break;
                        }
-                       if (a->componentvftbl && a->elementvftbl)
-                       {
-                               depth = build_display_inner(topc, a->componentvftbl->clazz, i+1);
+                       if (a->componentvftbl && a->elementvftbl) {
+                               super = a->componentvftbl->clazz;
                                break;
                        }
                }
-               depth = build_display_inner(topc, c->super, i+1);
+               /* Normal classes. */
+               super = c->super;
        } while (false);
-       if (depth >= DISPLAY_SIZE)
-       {
-               if (depth == DISPLAY_SIZE)
-               {
-                       topc->vftbl->subtype_overflow = MNEW(vftbl_t *, i+1);
+       if (super) {
+               build_display(super);
+               depth = super->vftbl->subtype_depth + 1;
+       } else
+               /* java.lang.Object doesn't have a super class. */
+               depth = 0;
+
+       /* Now copy super's display, append c->vftbl and initialize the remaining fields. */
+       if (depth >= DISPLAY_SIZE) {
+               c->vftbl->subtype_overflow = MNEW(vftbl_t *, depth - DISPLAY_SIZE + 1);
 #if defined(ENABLE_STATISTICS)
-                       if (opt_stat)
-                               count_vftbl_len += sizeof(void*) * (i+1);
+               if (opt_stat)
+                       count_vftbl_len += sizeof(vftbl_t*) * (depth - DISPLAY_SIZE + 1);
 #endif
-               }
-               topc->vftbl->subtype_overflow[depth - DISPLAY_SIZE] = c->vftbl;
-               return depth + 1;
+               memcpy(c->vftbl->subtype_overflow, super->vftbl->subtype_overflow, sizeof(vftbl_t*) * (depth - DISPLAY_SIZE));
+               c->vftbl->subtype_overflow[depth - DISPLAY_SIZE] = c->vftbl;
+               depth_fixed = DISPLAY_SIZE;
+       }
+       else {
+               depth_fixed = depth;
+               c->vftbl->subtype_display[depth] = c->vftbl;
        }
-       topc->vftbl->subtype_display[depth] = c->vftbl;
-       return depth + 1;
-}
-
-static void build_display(classinfo *c)
-{
-       int depth;
-       int i;
 
-       depth = build_display_inner(c, c, 0) - 1;
+       if (super)
+               memcpy(c->vftbl->subtype_display, super->vftbl->subtype_display, sizeof(vftbl_t*) * depth_fixed);
+       for (i=depth_fixed+1; i<=DISPLAY_SIZE; i++)
+               c->vftbl->subtype_display[i] = NULL;
+       c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[0]) + sizeof(vftbl_t*) * depth_fixed;
        c->vftbl->subtype_depth = depth;
-       if (depth >= DISPLAY_SIZE)
-       {
-               c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]);
-       }
-       else
-       {
-               c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[0]) + sizeof(void*) * depth;
-               for (i=depth+1; i<=DISPLAY_SIZE; i++)
-                       c->vftbl->subtype_display[i] = NULL;
-       }
 }
 #endif
 
+/* link_class_intern ***********************************************************
+
+   Tries to link a class. The function calculates the length in bytes
+   that an instance of this class requires as well as the VTBL for
+   methods and interface methods.
+       
+*******************************************************************************/
+
 static classinfo *link_class_intern(classinfo *c)
 {
        classinfo *super;             /* super class                              */