1 /* src/native/localref.c - Management of local reference tables
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
33 #include "mm/memory.h"
35 #include "native/localref.h"
37 #include "threads/threads-common.h"
39 #include "toolbox/logging.h"
42 /* debug **********************************************************************/
44 #if !defined(NDEBUG) && 0
45 # define TRACELOCALREF(message) log_println("%s", message)
47 # define TRACELOCALREF(message)
51 /* global variables ***********************************************************/
53 #if !defined(ENABLE_THREADS)
54 localref_table *_no_threads_localref_table;
58 /* localref_table_init *********************************************************
60 Initializes the local references table of the current thread.
62 *******************************************************************************/
64 bool localref_table_init(void)
68 TRACELOCALREF("table init");
70 assert(LOCALREFTABLE == NULL);
72 #if defined(ENABLE_GC_CACAO)
73 /* this is freed by localref_table_destroy */
74 lrt = NEW(localref_table);
76 /* this does not need to be freed again */
77 lrt = GCNEW(localref_table);
83 localref_table_add(lrt);
89 /* localref_table_destroy ******************************************************
91 Destroys the complete local references table of the current thread.
93 *******************************************************************************/
95 bool localref_table_destroy(void)
99 TRACELOCALREF("table destroy");
104 assert(lrt->prev == NULL);
106 #if defined(ENABLE_GC_CACAO)
107 FREE(lrt, localref_table);
110 LOCALREFTABLE = NULL;
116 /* localref_table_add **********************************************************
118 Adds a new local references table to the current thread.
120 *******************************************************************************/
122 void localref_table_add(localref_table *lrt)
124 /* initialize the local reference table */
126 lrt->capacity = LOCALREFTABLE_CAPACITY;
128 lrt->localframes = 1;
129 lrt->prev = LOCALREFTABLE;
131 /* clear the references array (memset is faster the a for-loop) */
133 MSET(lrt->refs, 0, void*, LOCALREFTABLE_CAPACITY);
135 /* add given local references table to this thread */
141 /* localref_table_remove *******************************************************
143 Removes the topmost local references table from the current thread.
145 *******************************************************************************/
147 void localref_table_remove()
151 /* get current local reference table from thread */
156 assert(lrt->localframes == 1);
164 /* localref_frame_push *********************************************************
166 Creates a new local reference frame, in which at least a given
167 number of local references can be created.
169 *******************************************************************************/
171 bool localref_frame_push(int32_t capacity)
174 localref_table *nlrt;
175 int32_t additionalrefs;
177 TRACELOCALREF("frame push");
179 /* get current local reference table from thread */
184 assert(capacity > 0);
186 /* Allocate new local reference table on Java heap. Calculate the
187 additional memory we have to allocate. */
189 if (capacity > LOCALREFTABLE_CAPACITY)
190 additionalrefs = capacity - LOCALREFTABLE_CAPACITY;
194 #if defined(ENABLE_GC_CACAO)
195 nlrt = MNEW(u1, sizeof(localref_table) + additionalrefs * SIZEOF_VOID_P);
197 nlrt = GCMNEW(u1, sizeof(localref_table) + additionalrefs * SIZEOF_VOID_P);
203 /* Set up the new local reference table and add it to the local
206 nlrt->capacity = capacity;
208 nlrt->localframes = lrt->localframes + 1;
211 /* store new local reference table in thread */
213 LOCALREFTABLE = nlrt;
219 /* localref_frame_pop_all ******************************************************
221 Pops off all the local reference frames of the current table.
223 *******************************************************************************/
225 void localref_frame_pop_all(void)
228 localref_table *plrt;
230 #if defined(ENABLE_GC_CACAO)
231 int32_t additionalrefs;
234 TRACELOCALREF("frame pop all");
236 /* get current local reference table from thread */
242 localframes = lrt->localframes;
244 /* Don't delete the top local frame, as this one is allocated in
245 the native stub on the stack and is freed automagically on
248 if (localframes == 1)
251 /* release all current local frames */
253 for (; localframes > 1; localframes--) {
254 /* get previous frame */
258 /* clear all reference entries */
260 MSET(lrt->refs, 0, void*, lrt->capacity);
264 #if defined(ENABLE_GC_CACAO)
265 /* for the exact GC local reference tables are not on the heap,
266 so we need to free them explicitly here. */
268 if (lrt->capacity > LOCALREFTABLE_CAPACITY)
269 additionalrefs = lrt->capacity - LOCALREFTABLE_CAPACITY;
273 MFREE(lrt, u1, sizeof(localref_table) + additionalrefs * SIZEOF_VOID_P);
276 /* set new local references table */
281 /* store new local reference table in thread */
287 /* localref_add ****************************************************************
289 Adds a new entry into the local reference table and returns the
292 *******************************************************************************/
294 java_handle_t *localref_add(java_object_t *o)
302 log_println("localref_add: WARNING: trying to add localref for (NIL)!");
307 /* XXX: assert that we are in a GC critical section! */
309 /* XXX: this is only an ugly hack */
310 #if defined(ENABLE_HANDLES)
311 if (LOCALREFTABLE == NULL) {
312 h = NEW(java_handle_t);
314 log_println("localref_add: WARNING: added preliminary localref %p for %p", h, o);
319 /* get current local reference table from thread */
325 /* Check if we have space for the requested reference? No,
326 allocate a new frame. This is actually not what the spec says,
327 but for compatibility reasons... */
329 if (lrt->used == lrt->capacity) {
330 if (!localref_frame_push(16))
333 /* get the new local reference table */
338 /* insert the reference into the local reference table */
340 for (i = 0; i < lrt->capacity; i++) {
341 if (lrt->refs[i] == NULL) {
345 #if defined(ENABLE_HANDLES)
346 h = (java_handle_t *) &(lrt->refs[i]);
348 h = (java_handle_t *) o;
354 for (lrt = LOCALREFTABLE; lrt != NULL; lrt = lrt->prev)
356 log_println("added localref %p for %p (total count %d)", h, o, count);
365 /* this should not happen */
367 log_println("localref_add: WARNING: unable to add localref for %p", o);
373 /* localref_del ****************************************************************
375 Deletes an entry from the local reference table.
377 *******************************************************************************/
379 void localref_del(java_handle_t *localref)
385 /* get local reference table from thread */
391 /* go through all local frames */
393 /* XXX: this is definitely not what the spec wants! */
394 /*for (; lrt != NULL; lrt = lrt->prev) {*/
396 /* and try to remove the reference */
398 for (i = 0; i < lrt->capacity; i++) {
399 #if defined(ENABLE_HANDLES)
400 h = (java_handle_t *) &(lrt->refs[i]);
402 h = (java_handle_t *) lrt->refs[i];
414 /* this should not happen */
416 log_println("localref_del: WARNING: unable to find localref %p", localref);
420 /* localref_dump ***************************************************************
422 Dumps all local reference tables, including all frames.
424 *******************************************************************************/
427 # define LOCALREF_DUMP_REFS_PER_LINE 4
433 /* get current local reference table from thread */
437 log_println("--------- Local Reference Tables Dump ---------");
439 while (lrt != NULL) {
440 log_println("Frame #%d, Used=%d, Capacity=%d, Addr=%p:", lrt->localframes, lrt->used, lrt->capacity, (void *) lrt);
442 if (lrt->used != 0) {
447 for (i = 0; i < lrt->capacity; i++) {
448 if (lrt->refs[i] != NULL) {
449 if (j != 0 && j % LOCALREF_DUMP_REFS_PER_LINE == 0) {
454 log_print("\t0x%016lx ", (intptr_t) lrt->refs[i]);
464 #endif /* !defined(NDEBUG) */
468 * These are local overrides for various environment variables in Emacs.
469 * Please do not remove this and leave it at the end of the file, where
470 * Emacs will automagically detect them.
471 * ---------------------------------------------------------------------
474 * indent-tabs-mode: t
478 * vim:noexpandtab:sw=4:ts=4: