Merged subtype branch to new head.
[cacao.git] / src / vm / jit / builtin.cpp
index a343bd4065d4ffdfd7f3ad7d5e7538fbd317de90..5dbd12a7520dda46fab14008d0e0265fefdd58d2 100644 (file)
@@ -653,6 +653,19 @@ bool builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o)
 
 *******************************************************************************/
 
+bool fast_subtype_check(struct _vftbl *s, struct _vftbl *t)
+{
+       int i;
+       if (s->subtype_display[t->subtype_depth] == t)
+               return true;
+       if (t->subtype_offset != OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]))
+               return false;
+       for (i=0; i<s->subtype_overflow_length; i++)
+               if (s->subtype_overflow[i] == t)
+                       return true;
+       return false;
+}
+
 bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
 {
        arraydescriptor *desc;
@@ -685,8 +698,6 @@ bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
                if (valuevftbl == componentvftbl)
                        return 1;
 
-               linker_classrenumber_mutex->lock();
-
                baseval = componentvftbl->baseval;
 
                if (baseval <= 0) {
@@ -696,11 +707,8 @@ bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
                                          (valuevftbl->interfacetable[baseval] != NULL));
                }
                else {
-                       diffval = valuevftbl->baseval - componentvftbl->baseval;
-                       result  = diffval <= (uint32_t) componentvftbl->diffval;
+                       result = fast_subtype_check(valuevftbl, componentvftbl);
                }
-
-               linker_classrenumber_mutex->unlock();
        }
        else if (valuedesc == NULL) {
                /* {oa has dimension > 1} */
@@ -752,8 +760,6 @@ bool builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o)
        if (valuevftbl == elementvftbl)
                return 1;
 
-       linker_classrenumber_mutex->lock();
-
        baseval = elementvftbl->baseval;
 
        if (baseval <= 0) {
@@ -762,12 +768,9 @@ bool builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o)
                                  (valuevftbl->interfacetable[baseval] != NULL));
        }
        else {
-               diffval = valuevftbl->baseval - elementvftbl->baseval;
-               result  = diffval <= (uint32_t) elementvftbl->diffval;
+               result = fast_subtype_check(valuevftbl, elementvftbl);
        }
 
-       linker_classrenumber_mutex->unlock();
-
        return result;
 }
 
@@ -801,12 +804,7 @@ bool builtin_fast_canstore_onedim_class(java_objectarray_t *a, java_object_t *o)
        if (valuevftbl == elementvftbl)
                return 1;
 
-       linker_classrenumber_mutex->lock();
-
-       diffval = valuevftbl->baseval - elementvftbl->baseval;
-       result  = diffval <= (uint32_t) elementvftbl->diffval;
-
-       linker_classrenumber_mutex->unlock();
+       result = fast_subtype_check(valuevftbl, elementvftbl);
 
        return result;
 }