* src/native/localref.cpp: Using free list instead of array scanning.
authorStefan Ring <stefan@complang.tuwien.ac.at>
Wed, 29 Sep 2010 08:47:29 +0000 (10:47 +0200)
committerStefan Ring <stefan@complang.tuwien.ac.at>
Wed, 29 Sep 2010 08:47:29 +0000 (10:47 +0200)
* src/native/localref.hpp: Adapted localref_table to use a free list.

src/native/localref.cpp
src/native/localref.hpp

index bec9bfe0208f90a9b0079670ae254593d370397f..e7112c6c48439e796e36b2c152fe87091b30c2db 100644 (file)
@@ -1,6 +1,6 @@
 /* src/native/localref.cpp - Management of local reference tables
 
 /* src/native/localref.cpp - Management of local reference tables
 
-   Copyright (C) 1996-2005, 2006, 2007, 2008
+   Copyright (C) 1996-2005, 2006, 2007, 2008, 2010
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
@@ -50,7 +50,7 @@
                if (opt_DebugLocalReferences) { \
                        localref_table *dlrt = LOCALREFTABLE; \
                        log_start(); \
                if (opt_DebugLocalReferences) { \
                        localref_table *dlrt = LOCALREFTABLE; \
                        log_start(); \
-                       log_print("[local reference %-12s: lrt=%016p frame=%d capacity=%d used=%d", message, dlrt, dlrt->localframes, dlrt->capacity, dlrt->used); \
+                       log_print("[local reference %-12s: lrt=%016p frame=%d capacity=%d used=%d hwm=%d", message, dlrt, dlrt->localframes, dlrt->capacity, dlrt->used, dlrt->hwm); \
                        if (index >= 0) \
                                log_print(" localref=%p object=%p", &(dlrt->refs[index]), dlrt->refs[index]); \
                        log_print("]"); \
                        if (index >= 0) \
                                log_print(" localref=%p object=%p", &(dlrt->refs[index]), dlrt->refs[index]); \
                        log_print("]"); \
@@ -150,9 +150,8 @@ void localref_table_add(localref_table *lrt)
        lrt->localframes = 1;
        lrt->prev        = LOCALREFTABLE;
 
        lrt->localframes = 1;
        lrt->prev        = LOCALREFTABLE;
 
-       /* clear the references array (memset is faster the a for-loop) */
-
-       MSET(lrt->refs, 0, void*, LOCALREFTABLE_CAPACITY);
+       lrt->hwm = 0;
+       lrt->firstfree = -1;
 
        /* add given local references table to this thread */
 
 
        /* add given local references table to this thread */
 
@@ -286,10 +285,6 @@ void localref_frame_pop_all(void)
 
                DEBUGLOCALREF("frame pop", -1);
 
 
                DEBUGLOCALREF("frame pop", -1);
 
-               /* clear all reference entries */
-
-               MSET(lrt->refs, 0, void*, lrt->capacity);
-
                lrt->prev = NULL;
 
 #if !defined(ENABLE_GC_BOEHM)
                lrt->prev = NULL;
 
 #if !defined(ENABLE_GC_BOEHM)
@@ -350,28 +345,34 @@ java_handle_t *localref_add(java_object_t *o)
 
        /* insert the reference into the local reference table */
 
 
        /* insert the reference into the local reference table */
 
-       for (i = 0; i < lrt->capacity; i++) {
-               if (lrt->refs[i] == NULL) {
-                       lrt->refs[i] = o;
-                       lrt->used++;
-
-#if defined(ENABLE_HANDLES)
-                       h = (java_handle_t *) &(lrt->refs[i]);
-#else
-                       h = (java_handle_t *) o;
-#endif
+       i = lrt->hwm;
+       if (i == lrt->capacity) {
+               if (lrt->firstfree >= 0) {
+                       i = lrt->firstfree;
+                       lrt->firstfree = lrt->refs[i].nextfree;
+               }
+               else {
+                       /* this should not happen */
 
 
-                       /*DEBUGLOCALREF("entry add", i);*/
+                       log_println("localref_add: WARNING: unable to add localref for %p", o);
 
 
-                       return h;
+                       return NULL;
                }
                }
-       }
+       } else
+               lrt->hwm++;
 
 
-       /* this should not happen */
+       lrt->refs[i].ptr = o;
+       lrt->used++;
+
+#if defined(ENABLE_HANDLES)
+       h = (java_handle_t *) &(lrt->refs[i].ptr);
+#else
+       h = (java_handle_t *) o;
+#endif
 
 
-       log_println("localref_add: WARNING: unable to add localref for %p", o);
+       /*DEBUGLOCALREF("entry add", i);*/
 
 
-       return NULL;
+       return h;
 }
 
 
 }
 
 
@@ -403,17 +404,18 @@ void localref_del(java_handle_t *localref)
 
                /* and try to remove the reference */
     
 
                /* and try to remove the reference */
     
-               for (i = 0; i < lrt->capacity; i++) {
+               for (i = 0; i < lrt->hwm; i++) {
 #if defined(ENABLE_HANDLES)
 #if defined(ENABLE_HANDLES)
-                       h = (java_handle_t *) &(lrt->refs[i]);
+                       h = (java_handle_t *) &(lrt->refs[i].ptr);
 #else
 #else
-                       h = (java_handle_t *) lrt->refs[i];
+                       h = (java_handle_t *) lrt->refs[i].ptr;
 #endif
 
                        if (h == localref) {
                                DEBUGLOCALREF("entry delete", i);
 
 #endif
 
                        if (h == localref) {
                                DEBUGLOCALREF("entry delete", i);
 
-                               lrt->refs[i] = NULL;
+                               lrt->refs[i].nextfree = lrt->firstfree;
+                               lrt->firstfree = i;
                                lrt->used--;
 
                                return;
                                lrt->used--;
 
                                return;
@@ -539,7 +541,7 @@ void localref_native_exit(methodinfo *m, uint64_t *return_regs)
 # define LOCALREF_DUMP_REFS_PER_LINE 4
 void localref_dump()
 {
 # define LOCALREF_DUMP_REFS_PER_LINE 4
 void localref_dump()
 {
-       localref_table *lrt;
+       localref_table *lrt, dlrt;
        int i, j;
 
        /* get current local reference table from thread */
        int i, j;
 
        /* get current local reference table from thread */
@@ -549,21 +551,27 @@ void localref_dump()
        log_println("--------- Local Reference Tables Dump ---------");
 
        while (lrt != NULL) {
        log_println("--------- Local Reference Tables Dump ---------");
 
        while (lrt != NULL) {
-               log_println("Frame #%d, Used=%d, Capacity=%d, Addr=%p:", lrt->localframes, lrt->used, lrt->capacity, (void *) lrt);
+               log_println("Frame #%d, Used=%d, Capacity=%d, Hwm=%d, Addr=%p:", lrt->localframes, lrt->used, lrt->capacity, lrt->hwm, (void *) lrt);
 
                        if (lrt->used != 0) {
 
 
                        if (lrt->used != 0) {
 
+                               dlrt = *lrt;                    // copy it for dumping
+                               for (i = dlrt.firstfree; i >= 0; i = j) {
+                                       j = dlrt.refs[i].nextfree;
+                                       dlrt.refs[i].ptr = NULL;
+                               }
+
                                log_start();
 
                                j = 0;
                                log_start();
 
                                j = 0;
-                               for (i = 0; i < lrt->capacity; i++) {
-                                       if (lrt->refs[i] != NULL) {
+                               for (i = 0; i < dlrt.hwm; i++) {
+                                       if (dlrt.refs[i].ptr != NULL) {
                                                if (j != 0 && j % LOCALREF_DUMP_REFS_PER_LINE == 0) {
                                                        log_finish();
                                                        log_start();
                                                }
                                                j++;
                                                if (j != 0 && j % LOCALREF_DUMP_REFS_PER_LINE == 0) {
                                                        log_finish();
                                                        log_start();
                                                }
                                                j++;
-                                               log_print("\t0x%016lx ", (intptr_t) lrt->refs[i]);
+                                               log_print("\t0x%016lx ", (intptr_t) dlrt.refs[i].ptr);
                                        }
                                }
 
                                        }
                                }
 
@@ -604,10 +612,9 @@ static bool localref_check_uncleared()
        for (; localframes > 0; localframes--) {
                lrt_used += lrt->used;
 
        for (; localframes > 0; localframes--) {
                lrt_used += lrt->used;
 
-               for (i = 0; i < lrt->capacity; i++) {
-                       if (lrt->refs[i] != NULL)
-                               lrt_uncleared++;
-               }
+               lrt_uncleared += lrt->hwm;
+               for (i = lrt->firstfree; i >= 0; i = lrt->refs[i].nextfree)
+                       lrt_uncleared--;
 
                lrt = lrt->prev;
        }
 
                lrt = lrt->prev;
        }
index 11e212e38f22995a4ab90118d8133c40e06ed821..9e8fb394dfa3a7a40f1e24f1718c4ac9e035e229 100644 (file)
@@ -1,6 +1,6 @@
 /* src/native/localref.hpp - Management of local reference tables
 
 /* src/native/localref.hpp - Management of local reference tables
 
-   Copyright (C) 1996-2005, 2006, 2007, 2008
+   Copyright (C) 1996-2005, 2006, 2007, 2008, 2010
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
@@ -50,10 +50,15 @@ typedef struct localref_table localref_table;
 struct localref_table {
        s4                 capacity;        /* table size                         */
        s4                 used;            /* currently used references          */
 struct localref_table {
        s4                 capacity;        /* table size                         */
        s4                 used;            /* currently used references          */
+       s4                 firstfree;       /* head of the free list              */
+       s4                 hwm;             /* high water mark                    */
        s4                 localframes;     /* number of current frames           */
        s4                 PADDING;         /* 8-byte padding                     */
        localref_table    *prev;            /* link to prev table (LocalFrame)    */
        s4                 localframes;     /* number of current frames           */
        s4                 PADDING;         /* 8-byte padding                     */
        localref_table    *prev;            /* link to prev table (LocalFrame)    */
-       java_object_t     *refs[LOCALREFTABLE_CAPACITY]; /* references            */
+       union {
+               java_object_t *ptr;
+               s4 nextfree;
+       } refs[LOCALREFTABLE_CAPACITY];     /* references            */
 };
 
 
 };