Merged new changes from default (manually: src/vm/jit/i386/codegen.c).
[cacao.git] / src / vm / jit / builtin.cpp
index c735a277c54f1b14aee2f8a5d3de7638f15cd50e..06e2d2626779a359e7786a6dbf9adaf0115a37c7 100644 (file)
 
 #include "vm/array.hpp"
 #include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
 #include "vm/cycles-stats.h"
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
 #include "vm/globals.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/linker.h"
 #include "vm/loader.hpp"
 #include "vm/options.h"
@@ -267,6 +267,81 @@ bool builtin_init(void)
 }
 
 
+/* builtintable_get_by_key *****************************************************
+
+   Returns a key for the given builtintable_entry object which is suitable
+   for retrieving the instance again by calling builtintable_get_by_key.
+
+   The key can be regarded fixed between multiple runs of the JVM.
+
+*******************************************************************************/
+
+s4 builtintable_get_key(builtintable_entry *bte)
+{
+       s4 entries;
+/*
+       int i;
+       entries = sizeof(builtintable_internal) / sizeof(builtintable_entry) - 1;
+       for (i = 0; i < entries; i++)
+               if (&builtintable_internal[i] == bte)
+                       return i + 1;
+
+       entries = sizeof(builtintable_automatic) / sizeof(builtintable_entry) - 1;
+       for (i = 0; i < entries; i++)
+               if (&builtintable_automatic[i] == bte)
+                       return -i;
+
+       entries = sizeof(builtintable_function) / sizeof(builtintable_entry) - 1;
+       for (i = 0; i < entries; i++)
+               if (&builtintable_function[i] == bte)
+                       return -1000 - i;
+*/
+
+       entries = sizeof(builtintable_internal) / sizeof(builtintable_entry) - 1;
+       if (&builtintable_internal[0] <= bte
+               && &builtintable_internal[entries - 1] >= bte)
+       {
+               return (s4) (bte - &builtintable_internal[0]) + 1;
+       }
+
+       entries = sizeof(builtintable_automatic) / sizeof(builtintable_entry) - 1;
+       if (&builtintable_automatic[0] <= bte
+               && &builtintable_automatic[entries - 1] >= bte)
+       {
+               return -(s4) (bte - &builtintable_automatic[0]);
+       }
+
+       entries = sizeof(builtintable_function) / sizeof(builtintable_entry) - 1;
+       if (&builtintable_function[0] <= bte
+               && &builtintable_function[entries - 1] >= bte)
+       {
+               return -1000 - (s4) (bte - &builtintable_function[0]);
+       }
+
+       /* builtintable_entry is not in our tables. */
+       assert (0);
+
+       return 0;
+}
+
+/* builtintable_get_by_key *****************************************************
+
+   Retrieves an entry in the internal and automatic builtin functions tables
+   using a key that was retrived previously with builtintable_get_key()
+
+*******************************************************************************/
+
+builtintable_entry *builtintable_get_by_key(s4 key)
+{
+       /* If key is positive it is the index into builtintable_internal. If it is
+        * negative it is the index into builtintable_automatic. If it is <= -1000
+     * it is the index into builtintable_function.
+     */
+       return (key > 0)
+               ? &builtintable_internal[key - 1]
+               : (key > -1000 ? &builtintable_automatic[-key] : &builtintable_function[-(1000 + key)]);
+}
+
 /* builtintable_get_internal ***************************************************
 
    Finds an entry in the builtintable for internal functions and
@@ -653,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;
@@ -685,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) {
@@ -696,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} */
@@ -752,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) {
@@ -762,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;
 }
 
@@ -801,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;
 }