Merged new changes from default (manually: src/vm/jit/i386/codegen.c).
[cacao.git] / src / vm / jit / builtin.cpp
index f3ebf0ad7c96900f5821b47c8f770c9885a6300e..06e2d2626779a359e7786a6dbf9adaf0115a37c7 100644 (file)
@@ -728,6 +728,15 @@ bool builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o)
 
 *******************************************************************************/
 
+bool fast_subtype_check(struct _vftbl *s, struct _vftbl *t)
+{
+       if (s->subtype_display[t->subtype_depth] == t)
+               return true;
+       if (t->subtype_offset != OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]))
+               return false;
+       return s->subtype_depth >= t->subtype_depth && s->subtype_overflow[t->subtype_depth - DISPLAY_SIZE] == t;
+}
+
 bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
 {
        arraydescriptor *desc;
@@ -760,8 +769,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) {
@@ -771,11 +778,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} */
@@ -827,8 +831,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) {
@@ -837,12 +839,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;
 }
 
@@ -876,12 +875,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;
 }