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
25 $Id: localref.c 8364 2007-08-20 19:52:00Z michi $
35 #include "mm/memory.h"
37 #include "native/localref.h"
39 #include "threads/threads-common.h"
41 #include "toolbox/logging.h"
44 /* debug **********************************************************************/
46 #if !defined(NDEBUG) && 0
47 # define TRACELOCALREF(message) log_println("%s", message)
49 # define TRACELOCALREF(message)
53 /* global variables ***********************************************************/
55 #if !defined(ENABLE_THREADS)
56 localref_table *_no_threads_localref_table;
60 /* localref_table_init *********************************************************
62 Initializes the local references table of the current thread.
64 *******************************************************************************/
66 bool localref_table_init(void)
70 TRACELOCALREF("table init");
72 assert(LOCALREFTABLE == NULL);
74 #if defined(ENABLE_GC_CACAO)
75 /* this is freed by localref_table_destroy */
76 lrt = NEW(localref_table);
78 /* this does not need to be freed again */
79 lrt = GCNEW(localref_table);
85 localref_table_add(lrt);
91 /* localref_table_destroy ******************************************************
93 Destroys the complete local references table of the current thread.
95 *******************************************************************************/
97 bool localref_table_destroy(void)
101 TRACELOCALREF("table destroy");
106 assert(lrt->prev == NULL);
108 #if defined(ENABLE_GC_CACAO)
109 FREE(lrt, localref_table);
112 LOCALREFTABLE = NULL;
118 /* localref_table_add **********************************************************
120 Adds a new local references table to the current thread.
122 *******************************************************************************/
124 void localref_table_add(localref_table *lrt)
126 /* initialize the local reference table */
128 lrt->capacity = LOCALREFTABLE_CAPACITY;
130 lrt->localframes = 1;
131 lrt->prev = LOCALREFTABLE;
133 /* clear the references array (memset is faster the a for-loop) */
135 MSET(lrt->refs, 0, void*, LOCALREFTABLE_CAPACITY);
137 /* add given local references table to this thread */
143 /* localref_table_remove *******************************************************
145 Removes the topmost local references table from the current thread.
147 *******************************************************************************/
149 void localref_table_remove()
153 /* get current local reference table from thread */
158 assert(lrt->localframes == 1);
166 /* localref_frame_push *********************************************************
168 Creates a new local reference frame, in which at least a given
169 number of local references can be created.
171 *******************************************************************************/
173 bool localref_frame_push(int32_t capacity)
176 localref_table *nlrt;
177 int32_t additionalrefs;
179 TRACELOCALREF("frame push");
181 /* get current local reference table from thread */
186 assert(capacity > 0);
188 /* Allocate new local reference table on Java heap. Calculate the
189 additional memory we have to allocate. */
191 if (capacity > LOCALREFTABLE_CAPACITY)
192 additionalrefs = capacity - LOCALREFTABLE_CAPACITY;
196 #if defined(ENABLE_GC_CACAO)
197 nlrt = MNEW(u1, sizeof(localref_table) + additionalrefs * SIZEOF_VOID_P);
199 nlrt = GCMNEW(u1, sizeof(localref_table) + additionalrefs * SIZEOF_VOID_P);
205 /* Set up the new local reference table and add it to the local
208 nlrt->capacity = capacity;
210 nlrt->localframes = lrt->localframes + 1;
213 /* store new local reference table in thread */
215 LOCALREFTABLE = nlrt;
221 /* localref_frame_pop_all ******************************************************
223 Pops off all the local reference frames of the current table.
225 *******************************************************************************/
227 void localref_frame_pop_all(void)
230 localref_table *plrt;
232 #if defined(ENABLE_GC_CACAO)
233 int32_t additionalrefs;
236 TRACELOCALREF("frame pop all");
238 /* get current local reference table from thread */
244 localframes = lrt->localframes;
246 /* Don't delete the top local frame, as this one is allocated in
247 the native stub on the stack and is freed automagically on
250 if (localframes == 1)
253 /* release all current local frames */
255 for (; localframes > 1; localframes--) {
256 /* get previous frame */
260 /* clear all reference entries */
262 MSET(lrt->refs, 0, void*, lrt->capacity);
266 #if defined(ENABLE_GC_CACAO)
267 /* for the exact GC local reference tables are not on the heap,
268 so we need to free them explicitly here. */
270 if (lrt->capacity > LOCALREFTABLE_CAPACITY)
271 additionalrefs = lrt->capacity - LOCALREFTABLE_CAPACITY;
275 MFREE(lrt, u1, sizeof(localref_table) + additionalrefs * SIZEOF_VOID_P);
278 /* set new local references table */
283 /* store new local reference table in thread */
289 /* localref_add ****************************************************************
291 Adds a new entry into the local reference table and returns the
294 *******************************************************************************/
296 java_handle_t *localref_add(java_object_t *o)
304 log_println("localref_add: WARNING: trying to add localref for (NIL)!");
309 /* XXX: assert that we are in a GC critical section! */
311 /* XXX: this is only an ugly hack */
312 #if defined(ENABLE_HANDLES)
313 if (LOCALREFTABLE == NULL) {
314 h = NEW(java_handle_t);
316 log_println("localref_add: WARNING: added preliminary localref %p for %p", h, o);
321 /* get current local reference table from thread */
327 /* Check if we have space for the requested reference? No,
328 allocate a new frame. This is actually not what the spec says,
329 but for compatibility reasons... */
331 if (lrt->used == lrt->capacity) {
332 if (!localref_frame_push(16))
335 /* get the new local reference table */
340 /* insert the reference into the local reference table */
344 for (i = 0; i < lrt->capacity; i++) {
345 if (lrt->refs[i] == NULL) {
349 #if defined(ENABLE_HANDLES)
350 h = (java_handle_t *) &(lrt->refs[i]);
352 h = (java_handle_t *) o;
359 /* this should not happen */
367 for (lrt = LOCALREFTABLE; lrt != NULL; lrt = lrt->prev)
369 log_println("added localref %p for %p (total count %d)", h, o, count);
378 /* localref_dump ***************************************************************
380 Dumps all local reference tables, including all frames.
382 *******************************************************************************/
385 # define LOCALREF_DUMP_REFS_PER_LINE 4
391 /* get current local reference table from thread */
395 log_println("--------- Local Reference Tables Dump ---------");
397 while (lrt != NULL) {
398 log_println("Frame #%d, Used=%d, Capacity=%d, Addr=%p:", lrt->localframes, lrt->used, lrt->capacity, (void *) lrt);
400 if (lrt->used != 0) {
405 for (i = 0; i < lrt->capacity; i++) {
406 if (lrt->refs[i] != NULL) {
407 if (j != 0 && j % LOCALREF_DUMP_REFS_PER_LINE == 0) {
412 log_print("\t0x%016lx ", (intptr_t) lrt->refs[i]);
422 #endif /* !defined(NDEBUG) */
426 * These are local overrides for various environment variables in Emacs.
427 * Please do not remove this and leave it at the end of the file, where
428 * Emacs will automagically detect them.
429 * ---------------------------------------------------------------------
432 * indent-tabs-mode: t
436 * vim:noexpandtab:sw=4:ts=4: