* src/native/localref.h: Likewise.
* src/vm/jit/argument.c: Likewise.
* src/vm/jit/argument.h: Likewise.
* src/native/localref.cpp: New file.
* src/native/localref.hpp: Likewise.
* src/vm/jit/argument.cpp: Likewise.
* src/vm/jit/argument.hpp: Likewise.
* src/native/Makefile.am,
src/native/jni.cpp,
src/native/llni.h,
src/threads/posix/thread-posix.hpp,
src/vm/jit/Makefile.am,
src/vm/jit/alpha/codegen.c,
src/vm/jit/arm/codegen.c,
src/vm/jit/codegen-common.cpp,
src/vm/jit/i386/codegen.c,
src/vm/jit/m68k/codegen.c,
src/vm/jit/mips/codegen.c,
src/vm/jit/powerpc/codegen.c,
src/vm/jit/powerpc64/codegen.c,
src/vm/jit/s390/codegen.c,
src/vm/jit/sparc64/codegen.c,
src/vm/jit/trace.cpp,
src/vm/jit/x86_64/codegen.c,
src/vm/primitive.cpp,
src/vm/primitive.hpp,
src/vm/vm.cpp: Related changes.
--HG--
rename : src/native/localref.c => src/native/localref.cpp
rename : src/native/localref.h => src/native/localref.hpp
rename : src/vm/jit/argument.c => src/vm/jit/argument.cpp
rename : src/vm/jit/argument.h => src/vm/jit/argument.hpp
JNI_SOURCES = \
jni.cpp \
jni.hpp \
- localref.c \
- localref.h
+ localref.cpp \
+ localref.hpp
endif
libnative_la_SOURCES = \
#include "native/jni.hpp"
#include "native/llni.h"
-#include "native/localref.h"
+#include "native/localref.hpp"
#include "native/native.hpp"
#if defined(ENABLE_JVMTI)
#include "vm/string.hpp"
#include "vm/vm.hpp"
-#include "vm/jit/argument.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/jit.hpp"
#include "vm/jit/stacktrace.hpp"
#endif
-#include "native/localref.h"
+#include "native/localref.hpp"
#include "threads/thread.hpp"
+++ /dev/null
-/* src/native/localref.c - Management of local reference tables
-
- Copyright (C) 1996-2005, 2006, 2007, 2008
- CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
- This file is part of CACAO.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdint.h>
-
-#include "mm/memory.h"
-
-#include "native/localref.h"
-
-#include "threads/thread.hpp"
-
-#include "toolbox/logging.h"
-
-#include "vm/options.h"
-#include "vm/vm.hpp"
-
-#include "vm/jit/argument.h"
-
-
-/* debug **********************************************************************/
-
-#if !defined(NDEBUG)
-# define DEBUGLOCALREF(message, index) \
- do { \
- 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); \
- if (index >= 0) \
- log_print(" localref=%p object=%p", &(dlrt->refs[index]), dlrt->refs[index]); \
- log_print("]"); \
- log_finish(); \
- } \
- } while (0)
-#else
-# define DEBUGLOCALREF(message, index)
-#endif
-
-
-/* global variables ***********************************************************/
-
-#if !defined(ENABLE_THREADS)
-localref_table *_no_threads_localref_table;
-#endif
-
-
-/* some forward declarations **************************************************/
-
-#if !defined(NDEBUG)
-static bool localref_check_uncleared();
-#endif
-
-
-/* localref_table_init *********************************************************
-
- Initializes the local references table of the current thread.
-
-*******************************************************************************/
-
-bool localref_table_init(void)
-{
- localref_table *lrt;
-
- TRACESUBSYSTEMINITIALIZATION("localref_table_init");
-
- assert(LOCALREFTABLE == NULL);
-
-#if !defined(ENABLE_GC_BOEHM)
- /* this is freed by localref_table_destroy */
- lrt = NEW(localref_table);
-#else
- /* this does not need to be freed again */
- lrt = GCNEW(localref_table);
-#endif
-
- if (lrt == NULL)
- return false;
-
- localref_table_add(lrt);
-
- DEBUGLOCALREF("table init", -1);
-
- return true;
-}
-
-
-/* localref_table_destroy ******************************************************
-
- Destroys the complete local references table of the current thread.
-
-*******************************************************************************/
-
-bool localref_table_destroy(void)
-{
- localref_table *lrt;
-
- lrt = LOCALREFTABLE;
- assert(lrt != NULL);
- assert(lrt->prev == NULL);
-
- DEBUGLOCALREF("table destroy", -1);
-
-#if !defined(ENABLE_GC_BOEHM)
- FREE(lrt, localref_table);
-#endif
-
- LOCALREFTABLE = NULL;
-
- return true;
-}
-
-
-/* localref_table_add **********************************************************
-
- Adds a new local references table to the current thread.
-
-*******************************************************************************/
-
-void localref_table_add(localref_table *lrt)
-{
- /* initialize the local reference table */
-
- lrt->capacity = LOCALREFTABLE_CAPACITY;
- lrt->used = 0;
- lrt->localframes = 1;
- lrt->prev = LOCALREFTABLE;
-
- /* clear the references array (memset is faster the a for-loop) */
-
- MSET(lrt->refs, 0, void*, LOCALREFTABLE_CAPACITY);
-
- /* add given local references table to this thread */
-
- LOCALREFTABLE = lrt;
-
- /*DEBUGLOCALREF("table add", -1);*/
-}
-
-
-/* localref_table_remove *******************************************************
-
- Removes the topmost local references table from the current thread.
-
-*******************************************************************************/
-
-void localref_table_remove()
-{
- localref_table *lrt;
-
-#if !defined(NDEBUG)
- /* check for uncleared local references */
-
- localref_check_uncleared();
-#endif
-
- /* get current local reference table from thread */
-
- lrt = LOCALREFTABLE;
- assert(lrt != NULL);
- assert(lrt->localframes == 1);
-
- /*DEBUGLOCALREF("table remove", -1);*/
-
- lrt = lrt->prev;
-
- LOCALREFTABLE = lrt;
-}
-
-
-/* localref_frame_push *********************************************************
-
- Creates a new local reference frame, in which at least a given
- number of local references can be created.
-
-*******************************************************************************/
-
-bool localref_frame_push(int32_t capacity)
-{
- localref_table *lrt;
- localref_table *nlrt;
- int32_t additionalrefs;
-
- /* get current local reference table from thread */
-
- lrt = LOCALREFTABLE;
- assert(lrt != NULL);
- assert(capacity > 0);
-
- /* Allocate new local reference table on Java heap. Calculate the
- additional memory we have to allocate. */
-
- if (capacity > LOCALREFTABLE_CAPACITY)
- additionalrefs = capacity - LOCALREFTABLE_CAPACITY;
- else
- additionalrefs = 0;
-
-#if !defined(ENABLE_GC_BOEHM)
- nlrt = (localref_table *)
- MNEW(u1, sizeof(localref_table) + additionalrefs * SIZEOF_VOID_P);
-#else
- nlrt = (localref_table *)
- GCMNEW(u1, sizeof(localref_table) + additionalrefs * SIZEOF_VOID_P);
-#endif
-
- if (nlrt == NULL)
- return false;
-
- /* Set up the new local reference table and add it to the local
- frames chain. */
-
- nlrt->capacity = capacity;
- nlrt->used = 0;
- nlrt->localframes = lrt->localframes + 1;
- nlrt->prev = lrt;
-
- /* store new local reference table in thread */
-
- LOCALREFTABLE = nlrt;
-
- DEBUGLOCALREF("frame push", -1);
-
- return true;
-}
-
-
-/* localref_frame_pop_all ******************************************************
-
- Pops off all the local reference frames of the current table.
-
-*******************************************************************************/
-
-void localref_frame_pop_all(void)
-{
- localref_table *lrt;
- localref_table *plrt;
- int32_t localframes;
-#if !defined(ENABLE_GC_BOEHM)
- int32_t additionalrefs;
-#endif
-
- /* get current local reference table from thread */
-
- lrt = LOCALREFTABLE;
- assert(lrt != NULL);
-
- localframes = lrt->localframes;
-
- /* Don't delete the top local frame, as this one is allocated in
- the native stub on the stack and is freed automagically on
- return. */
-
- if (localframes == 1)
- return;
-
- /* release all current local frames */
-
- for (; localframes > 1; localframes--) {
- /* get previous frame */
-
- plrt = lrt->prev;
-
- DEBUGLOCALREF("frame pop", -1);
-
- /* clear all reference entries */
-
- MSET(lrt->refs, 0, void*, lrt->capacity);
-
- lrt->prev = NULL;
-
-#if !defined(ENABLE_GC_BOEHM)
- /* for the exact GC local reference tables are not on the heap,
- so we need to free them explicitly here. */
-
- if (lrt->capacity > LOCALREFTABLE_CAPACITY)
- additionalrefs = lrt->capacity - LOCALREFTABLE_CAPACITY;
- else
- additionalrefs = 0;
-
- MFREE(lrt, u1, sizeof(localref_table) + additionalrefs * SIZEOF_VOID_P);
-#endif
-
- /* set new local references table */
-
- lrt = plrt;
- }
-
- /* store new local reference table in thread */
-
- LOCALREFTABLE = lrt;
-}
-
-
-/* localref_add ****************************************************************
-
- Adds a new entry into the local reference table and returns the
- new local reference.
-
-*******************************************************************************/
-
-java_handle_t *localref_add(java_object_t *o)
-{
- localref_table *lrt;
- java_handle_t *h;
- int32_t i;
-
- /* get current local reference table from thread */
-
- lrt = LOCALREFTABLE;
- assert(lrt != NULL);
- assert(o != NULL);
- /* XXX: assert that we are in a GC critical section! */
-
- /* Check if we have space for the requested reference? No,
- allocate a new frame. This is actually not what the spec says,
- but for compatibility reasons... */
-
- if (lrt->used == lrt->capacity) {
- if (!localref_frame_push(64))
- assert(0);
-
- /* get the new local reference table */
-
- lrt = LOCALREFTABLE;
- }
-
- /* 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
-
- /*DEBUGLOCALREF("entry add", i);*/
-
- return h;
- }
- }
-
- /* this should not happen */
-
- log_println("localref_add: WARNING: unable to add localref for %p", o);
-
- return NULL;
-}
-
-
-/* localref_del ****************************************************************
-
- Deletes an entry from the local reference table.
-
-*******************************************************************************/
-
-void localref_del(java_handle_t *localref)
-{
- localref_table *lrt;
- java_handle_t *h;
- int32_t localframes;
- int32_t i;
-
- /* get local reference table from thread */
-
- lrt = LOCALREFTABLE;
- assert(lrt != NULL);
- assert(localref != NULL);
-
- localframes = lrt->localframes;
-
- /* go through all local frames of the current table */
- /* XXX: this is propably not what the spec wants! */
-
- for (; localframes > 0; localframes--) {
-
- /* and try to remove the reference */
-
- for (i = 0; i < lrt->capacity; i++) {
-#if defined(ENABLE_HANDLES)
- h = (java_handle_t *) &(lrt->refs[i]);
-#else
- h = (java_handle_t *) lrt->refs[i];
-#endif
-
- if (h == localref) {
- DEBUGLOCALREF("entry delete", i);
-
- lrt->refs[i] = NULL;
- lrt->used--;
-
- return;
- }
- }
-
- lrt = lrt->prev;
- }
-
- /* this should not happen */
-
- log_println("localref_del: WARNING: unable to find localref %p", localref);
-}
-
-
-/* localref_native_enter *******************************************************
-
- Insert arguments to a native method into the local reference table.
- This is done by the native stub through codegen_start_native_call.
-
-*******************************************************************************/
-
-void localref_native_enter(methodinfo *m, uint64_t *argument_regs, uint64_t *argument_stack)
-{
- localref_table *lrt;
- methoddesc *md;
- imm_union arg;
- java_handle_t *h;
- int i;
-
- /* get local reference table from thread */
-
- lrt = LOCALREFTABLE;
- assert(lrt != NULL);
- assert(m != NULL);
-
- md = m->parseddesc;
-
- /* walk through all parameters to the method */
-
- for (i = 0; i < md->paramcount; ++i) {
- /* load TYPE_ADR parameters ... */
-
- if (md->paramtypes[i].type == TYPE_ADR) {
- arg = argument_jitarray_load(md, i, argument_regs, argument_stack);
-
- if (arg.a == NULL)
- continue;
-
- /* ... and insert them into the table */
-
- h = localref_add((java_object_t *) arg.a);
-
-#if defined(ENABLE_HANDLES)
- /* update the modified parameter if necesarry */
-
- arg.a = (void *) h;
- argument_jitarray_store(md, i, argument_regs, argument_stack, arg);
-#endif
- }
- }
-}
-
-
-/* localref_native_exit ********************************************************
-
- Undo the wrapping of the return value of a native method. This is
- done by the native stub through codegen_finish_native_call.
-
- NOTE: This function is only useful if handles are enabled.
-
-*******************************************************************************/
-
-#if defined(ENABLE_HANDLES)
-void localref_native_exit(methodinfo *m, uint64_t *return_regs)
-{
- localref_table *lrt;
- methoddesc *md;
- imm_union ret;
- java_handle_t *h;
-
- /* get local reference table from thread */
-
- lrt = LOCALREFTABLE;
- assert(lrt != NULL);
- assert(m != NULL);
-
- md = m->parseddesc;
-
- /* load TYPE_ADR return values ... */
-
- if (md->returntype.type == TYPE_ADR) {
- ret = argument_jitreturn_load(md, return_regs);
-
- if (ret.a == NULL)
- return;
-
- h = (java_handle_t *) ret.a;
-
- /* update the modified return valie */
-
- ret.a = (void *) h->heap_object;
- argument_jitreturn_store(md, return_regs, ret);
-
-#if !defined(NDEBUG) && 0
- /* removing the entry from the local reference table is not really
- necesarry, but gives us warnings if the entry does not exist. */
-
- localref_del(h);
-#endif
- }
-}
-#endif /* defined(ENABLE_HANDLES) */
-
-
-/* localref_dump ***************************************************************
-
- Dumps all local reference tables, including all frames.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-# define LOCALREF_DUMP_REFS_PER_LINE 4
-void localref_dump()
-{
- localref_table *lrt;
- int i, j;
-
- /* get current local reference table from thread */
-
- lrt = LOCALREFTABLE;
-
- 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);
-
- if (lrt->used != 0) {
-
- log_start();
-
- j = 0;
- for (i = 0; i < lrt->capacity; i++) {
- if (lrt->refs[i] != NULL) {
- 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_finish();
- }
-
- lrt = lrt->prev;
- }
-}
-#endif /* !defined(NDEBUG) */
-
-
-/* localref_check_uncleared ****************************************************
-
- Checks the topmost local reference table for uncleared references.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-static bool localref_check_uncleared()
-{
- localref_table *lrt;
- int32_t localframes;
- int32_t lrt_uncleared;
- int32_t lrt_used;
- int i;
-
- /* get current local reference table from thread */
-
- lrt = LOCALREFTABLE;
- assert(lrt != NULL);
- assert(lrt->localframes > 0);
-
- localframes = lrt->localframes;
- lrt_uncleared = 0;
- lrt_used = 0;
-
- for (; localframes > 0; localframes--) {
- lrt_used += lrt->used;
-
- for (i = 0; i < lrt->capacity; i++) {
- if (lrt->refs[i] != NULL)
- lrt_uncleared++;
- }
-
- lrt = lrt->prev;
- }
-
- if (lrt_uncleared != lrt_used) {
- localref_dump();
- vm_abort("localref_check_uncleared: (uncleared=%d) != (used=%d)", lrt_uncleared, lrt_used);
- }
-
- if (lrt_uncleared <= 1)
- return true;
- else {
- /*log_println("localref_check_uncleared: %d uncleared local references", lrt_uncleared);*/
- return false;
- }
-}
-#endif
-
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of the file, where
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- * vim:noexpandtab:sw=4:ts=4:
- */
--- /dev/null
+/* src/native/localref.cpp - Management of local reference tables
+
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+ This file is part of CACAO.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "mm/memory.h"
+
+#include "native/localref.hpp"
+
+#include "threads/thread.hpp"
+
+#include "toolbox/logging.h"
+
+#include "vm/options.h"
+#include "vm/vm.hpp"
+
+#include "vm/jit/argument.hpp"
+
+
+/* debug **********************************************************************/
+
+#if !defined(NDEBUG)
+# define DEBUGLOCALREF(message, index) \
+ do { \
+ 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); \
+ if (index >= 0) \
+ log_print(" localref=%p object=%p", &(dlrt->refs[index]), dlrt->refs[index]); \
+ log_print("]"); \
+ log_finish(); \
+ } \
+ } while (0)
+#else
+# define DEBUGLOCALREF(message, index)
+#endif
+
+
+/* global variables ***********************************************************/
+
+#if !defined(ENABLE_THREADS)
+localref_table *_no_threads_localref_table;
+#endif
+
+
+/* some forward declarations **************************************************/
+
+#if !defined(NDEBUG)
+static bool localref_check_uncleared();
+#endif
+
+
+/* localref_table_init *********************************************************
+
+ Initializes the local references table of the current thread.
+
+*******************************************************************************/
+
+bool localref_table_init(void)
+{
+ localref_table *lrt;
+
+ TRACESUBSYSTEMINITIALIZATION("localref_table_init");
+
+ assert(LOCALREFTABLE == NULL);
+
+#if !defined(ENABLE_GC_BOEHM)
+ /* this is freed by localref_table_destroy */
+ lrt = (localref_table*) NEW(localref_table);
+#else
+ /* this does not need to be freed again */
+ lrt = (localref_table*) GCNEW(localref_table);
+#endif
+
+ if (lrt == NULL)
+ return false;
+
+ localref_table_add(lrt);
+
+ DEBUGLOCALREF("table init", -1);
+
+ return true;
+}
+
+
+/* localref_table_destroy ******************************************************
+
+ Destroys the complete local references table of the current thread.
+
+*******************************************************************************/
+
+bool localref_table_destroy(void)
+{
+ localref_table *lrt;
+
+ lrt = LOCALREFTABLE;
+ assert(lrt != NULL);
+ assert(lrt->prev == NULL);
+
+ DEBUGLOCALREF("table destroy", -1);
+
+#if !defined(ENABLE_GC_BOEHM)
+ FREE(lrt, localref_table);
+#endif
+
+ LOCALREFTABLE = NULL;
+
+ return true;
+}
+
+
+/* localref_table_add **********************************************************
+
+ Adds a new local references table to the current thread.
+
+*******************************************************************************/
+
+void localref_table_add(localref_table *lrt)
+{
+ /* initialize the local reference table */
+
+ lrt->capacity = LOCALREFTABLE_CAPACITY;
+ lrt->used = 0;
+ lrt->localframes = 1;
+ lrt->prev = LOCALREFTABLE;
+
+ /* clear the references array (memset is faster the a for-loop) */
+
+ MSET(lrt->refs, 0, void*, LOCALREFTABLE_CAPACITY);
+
+ /* add given local references table to this thread */
+
+ LOCALREFTABLE = lrt;
+
+ /*DEBUGLOCALREF("table add", -1);*/
+}
+
+
+/* localref_table_remove *******************************************************
+
+ Removes the topmost local references table from the current thread.
+
+*******************************************************************************/
+
+void localref_table_remove()
+{
+ localref_table *lrt;
+
+#if !defined(NDEBUG)
+ /* check for uncleared local references */
+
+ localref_check_uncleared();
+#endif
+
+ /* get current local reference table from thread */
+
+ lrt = LOCALREFTABLE;
+ assert(lrt != NULL);
+ assert(lrt->localframes == 1);
+
+ /*DEBUGLOCALREF("table remove", -1);*/
+
+ lrt = lrt->prev;
+
+ LOCALREFTABLE = lrt;
+}
+
+
+/* localref_frame_push *********************************************************
+
+ Creates a new local reference frame, in which at least a given
+ number of local references can be created.
+
+*******************************************************************************/
+
+bool localref_frame_push(int32_t capacity)
+{
+ localref_table *lrt;
+ localref_table *nlrt;
+ int32_t additionalrefs;
+
+ /* get current local reference table from thread */
+
+ lrt = LOCALREFTABLE;
+ assert(lrt != NULL);
+ assert(capacity > 0);
+
+ /* Allocate new local reference table on Java heap. Calculate the
+ additional memory we have to allocate. */
+
+ if (capacity > LOCALREFTABLE_CAPACITY)
+ additionalrefs = capacity - LOCALREFTABLE_CAPACITY;
+ else
+ additionalrefs = 0;
+
+#if !defined(ENABLE_GC_BOEHM)
+ nlrt = (localref_table *)
+ MNEW(u1, sizeof(localref_table) + additionalrefs * SIZEOF_VOID_P);
+#else
+ nlrt = (localref_table *)
+ GCMNEW(u1, sizeof(localref_table) + additionalrefs * SIZEOF_VOID_P);
+#endif
+
+ if (nlrt == NULL)
+ return false;
+
+ /* Set up the new local reference table and add it to the local
+ frames chain. */
+
+ nlrt->capacity = capacity;
+ nlrt->used = 0;
+ nlrt->localframes = lrt->localframes + 1;
+ nlrt->prev = lrt;
+
+ /* store new local reference table in thread */
+
+ LOCALREFTABLE = nlrt;
+
+ DEBUGLOCALREF("frame push", -1);
+
+ return true;
+}
+
+
+/* localref_frame_pop_all ******************************************************
+
+ Pops off all the local reference frames of the current table.
+
+*******************************************************************************/
+
+void localref_frame_pop_all(void)
+{
+ localref_table *lrt;
+ localref_table *plrt;
+ int32_t localframes;
+#if !defined(ENABLE_GC_BOEHM)
+ int32_t additionalrefs;
+#endif
+
+ /* get current local reference table from thread */
+
+ lrt = LOCALREFTABLE;
+ assert(lrt != NULL);
+
+ localframes = lrt->localframes;
+
+ /* Don't delete the top local frame, as this one is allocated in
+ the native stub on the stack and is freed automagically on
+ return. */
+
+ if (localframes == 1)
+ return;
+
+ /* release all current local frames */
+
+ for (; localframes > 1; localframes--) {
+ /* get previous frame */
+
+ plrt = lrt->prev;
+
+ DEBUGLOCALREF("frame pop", -1);
+
+ /* clear all reference entries */
+
+ MSET(lrt->refs, 0, void*, lrt->capacity);
+
+ lrt->prev = NULL;
+
+#if !defined(ENABLE_GC_BOEHM)
+ /* for the exact GC local reference tables are not on the heap,
+ so we need to free them explicitly here. */
+
+ if (lrt->capacity > LOCALREFTABLE_CAPACITY)
+ additionalrefs = lrt->capacity - LOCALREFTABLE_CAPACITY;
+ else
+ additionalrefs = 0;
+
+ MFREE(lrt, u1, sizeof(localref_table) + additionalrefs * SIZEOF_VOID_P);
+#endif
+
+ /* set new local references table */
+
+ lrt = plrt;
+ }
+
+ /* store new local reference table in thread */
+
+ LOCALREFTABLE = lrt;
+}
+
+
+/* localref_add ****************************************************************
+
+ Adds a new entry into the local reference table and returns the
+ new local reference.
+
+*******************************************************************************/
+
+java_handle_t *localref_add(java_object_t *o)
+{
+ localref_table *lrt;
+ java_handle_t *h;
+ int32_t i;
+
+ /* get current local reference table from thread */
+
+ lrt = LOCALREFTABLE;
+ assert(lrt != NULL);
+ assert(o != NULL);
+ /* XXX: assert that we are in a GC critical section! */
+
+ /* Check if we have space for the requested reference? No,
+ allocate a new frame. This is actually not what the spec says,
+ but for compatibility reasons... */
+
+ if (lrt->used == lrt->capacity) {
+ if (!localref_frame_push(64))
+ assert(0);
+
+ /* get the new local reference table */
+
+ lrt = LOCALREFTABLE;
+ }
+
+ /* 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
+
+ /*DEBUGLOCALREF("entry add", i);*/
+
+ return h;
+ }
+ }
+
+ /* this should not happen */
+
+ log_println("localref_add: WARNING: unable to add localref for %p", o);
+
+ return NULL;
+}
+
+
+/* localref_del ****************************************************************
+
+ Deletes an entry from the local reference table.
+
+*******************************************************************************/
+
+void localref_del(java_handle_t *localref)
+{
+ localref_table *lrt;
+ java_handle_t *h;
+ int32_t localframes;
+ int32_t i;
+
+ /* get local reference table from thread */
+
+ lrt = LOCALREFTABLE;
+ assert(lrt != NULL);
+ assert(localref != NULL);
+
+ localframes = lrt->localframes;
+
+ /* go through all local frames of the current table */
+ /* XXX: this is propably not what the spec wants! */
+
+ for (; localframes > 0; localframes--) {
+
+ /* and try to remove the reference */
+
+ for (i = 0; i < lrt->capacity; i++) {
+#if defined(ENABLE_HANDLES)
+ h = (java_handle_t *) &(lrt->refs[i]);
+#else
+ h = (java_handle_t *) lrt->refs[i];
+#endif
+
+ if (h == localref) {
+ DEBUGLOCALREF("entry delete", i);
+
+ lrt->refs[i] = NULL;
+ lrt->used--;
+
+ return;
+ }
+ }
+
+ lrt = lrt->prev;
+ }
+
+ /* this should not happen */
+
+ log_println("localref_del: WARNING: unable to find localref %p", localref);
+}
+
+
+/* localref_native_enter *******************************************************
+
+ Insert arguments to a native method into the local reference table.
+ This is done by the native stub through codegen_start_native_call.
+
+*******************************************************************************/
+
+void localref_native_enter(methodinfo *m, uint64_t *argument_regs, uint64_t *argument_stack)
+{
+ localref_table *lrt;
+ methoddesc *md;
+ imm_union arg;
+ java_handle_t *h;
+ int i;
+
+ /* get local reference table from thread */
+
+ lrt = LOCALREFTABLE;
+ assert(lrt != NULL);
+ assert(m != NULL);
+
+ md = m->parseddesc;
+
+ /* walk through all parameters to the method */
+
+ for (i = 0; i < md->paramcount; ++i) {
+ /* load TYPE_ADR parameters ... */
+
+ if (md->paramtypes[i].type == TYPE_ADR) {
+ arg = argument_jitarray_load(md, i, argument_regs, argument_stack);
+
+ if (arg.a == NULL)
+ continue;
+
+ /* ... and insert them into the table */
+
+ h = localref_add((java_object_t *) arg.a);
+
+#if defined(ENABLE_HANDLES)
+ /* update the modified parameter if necesarry */
+
+ arg.a = (void *) h;
+ argument_jitarray_store(md, i, argument_regs, argument_stack, arg);
+#endif
+ }
+ }
+}
+
+
+/* localref_native_exit ********************************************************
+
+ Undo the wrapping of the return value of a native method. This is
+ done by the native stub through codegen_finish_native_call.
+
+ NOTE: This function is only useful if handles are enabled.
+
+*******************************************************************************/
+
+#if defined(ENABLE_HANDLES)
+void localref_native_exit(methodinfo *m, uint64_t *return_regs)
+{
+ localref_table *lrt;
+ methoddesc *md;
+ imm_union ret;
+ java_handle_t *h;
+
+ /* get local reference table from thread */
+
+ lrt = LOCALREFTABLE;
+ assert(lrt != NULL);
+ assert(m != NULL);
+
+ md = m->parseddesc;
+
+ /* load TYPE_ADR return values ... */
+
+ if (md->returntype.type == TYPE_ADR) {
+ ret = argument_jitreturn_load(md, return_regs);
+
+ if (ret.a == NULL)
+ return;
+
+ h = (java_handle_t *) ret.a;
+
+ /* update the modified return valie */
+
+ ret.a = (void *) h->heap_object;
+ argument_jitreturn_store(md, return_regs, ret);
+
+#if !defined(NDEBUG) && 0
+ /* removing the entry from the local reference table is not really
+ necesarry, but gives us warnings if the entry does not exist. */
+
+ localref_del(h);
+#endif
+ }
+}
+#endif /* defined(ENABLE_HANDLES) */
+
+
+/* localref_dump ***************************************************************
+
+ Dumps all local reference tables, including all frames.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+# define LOCALREF_DUMP_REFS_PER_LINE 4
+void localref_dump()
+{
+ localref_table *lrt;
+ int i, j;
+
+ /* get current local reference table from thread */
+
+ lrt = LOCALREFTABLE;
+
+ 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);
+
+ if (lrt->used != 0) {
+
+ log_start();
+
+ j = 0;
+ for (i = 0; i < lrt->capacity; i++) {
+ if (lrt->refs[i] != NULL) {
+ 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_finish();
+ }
+
+ lrt = lrt->prev;
+ }
+}
+#endif /* !defined(NDEBUG) */
+
+
+/* localref_check_uncleared ****************************************************
+
+ Checks the topmost local reference table for uncleared references.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+static bool localref_check_uncleared()
+{
+ localref_table *lrt;
+ int32_t localframes;
+ int32_t lrt_uncleared;
+ int32_t lrt_used;
+ int i;
+
+ /* get current local reference table from thread */
+
+ lrt = LOCALREFTABLE;
+ assert(lrt != NULL);
+ assert(lrt->localframes > 0);
+
+ localframes = lrt->localframes;
+ lrt_uncleared = 0;
+ lrt_used = 0;
+
+ for (; localframes > 0; localframes--) {
+ lrt_used += lrt->used;
+
+ for (i = 0; i < lrt->capacity; i++) {
+ if (lrt->refs[i] != NULL)
+ lrt_uncleared++;
+ }
+
+ lrt = lrt->prev;
+ }
+
+ if (lrt_uncleared != lrt_used) {
+ localref_dump();
+ vm_abort("localref_check_uncleared: (uncleared=%d) != (used=%d)", lrt_uncleared, lrt_used);
+ }
+
+ if (lrt_uncleared <= 1)
+ return true;
+ else {
+ /*log_println("localref_check_uncleared: %d uncleared local references", lrt_uncleared);*/
+ return false;
+ }
+}
+#endif
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c++
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
+++ /dev/null
-/* src/native/localref.h - Management of local reference tables
-
- Copyright (C) 1996-2005, 2006, 2007, 2008
- CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
- This file is part of CACAO.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
-*/
-
-
-#ifndef _LOCALREF_H
-#define _LOCALREF_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct localref_table localref_table;
-
-#include "config.h"
-
-#include "vm/types.h"
-
-#include "vm/global.h"
-#include "vm/method.h"
-
-
-/* localref_table **************************************************************
-
- ATTENTION: keep this structure a multiple of 8-bytes!!! This is
- essential for the native stub on 64-bit architectures.
-
-*******************************************************************************/
-
-#define LOCALREFTABLE_CAPACITY 16
-
-struct localref_table {
- s4 capacity; /* table size */
- s4 used; /* currently used references */
- 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 */
-};
-
-
-#if defined(ENABLE_THREADS)
-#define LOCALREFTABLE (THREADOBJECT->_localref_table)
-#else
-extern localref_table *_no_threads_localref_table;
-
-#define LOCALREFTABLE (_no_threads_localref_table)
-#endif
-
-
-/* function prototypes ********************************************************/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-bool localref_table_init(void);
-bool localref_table_destroy(void);
-void localref_table_add(localref_table *lrt);
-void localref_table_remove();
-
-bool localref_frame_push(int32_t capacity);
-void localref_frame_pop_all(void);
-
-java_handle_t *localref_add(java_object_t *o);
-void localref_del(java_handle_t *localref);
-
-void localref_native_enter(methodinfo *m, uint64_t *argument_regs, uint64_t *argument_stack);
-void localref_native_exit(methodinfo *m, uint64_t *return_regs);
-
-#if !defined(NDEBUG)
-void localref_dump(void);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _LOCALREF_H */
-
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of the file, where
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- */
--- /dev/null
+/* src/native/localref.hpp - Management of local reference tables
+
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+ This file is part of CACAO.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+*/
+
+
+#ifndef _LOCALREF_HPP
+#define _LOCALREF_HPP
+
+/* forward typedefs ***********************************************************/
+
+typedef struct localref_table localref_table;
+
+#include "config.h"
+
+#include "vm/types.h"
+
+#include "vm/global.h"
+#include "vm/method.h"
+
+
+/* localref_table **************************************************************
+
+ ATTENTION: keep this structure a multiple of 8-bytes!!! This is
+ essential for the native stub on 64-bit architectures.
+
+*******************************************************************************/
+
+#define LOCALREFTABLE_CAPACITY 16
+
+struct localref_table {
+ s4 capacity; /* table size */
+ s4 used; /* currently used references */
+ 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 */
+};
+
+
+#if defined(ENABLE_THREADS)
+#define LOCALREFTABLE (THREADOBJECT->_localref_table)
+#else
+extern localref_table *_no_threads_localref_table;
+
+#define LOCALREFTABLE (_no_threads_localref_table)
+#endif
+
+
+/* function prototypes ********************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool localref_table_init(void);
+bool localref_table_destroy(void);
+void localref_table_add(localref_table *lrt);
+void localref_table_remove();
+
+bool localref_frame_push(int32_t capacity);
+void localref_frame_pop_all(void);
+
+java_handle_t *localref_add(java_object_t *o);
+void localref_del(java_handle_t *localref);
+
+void localref_native_enter(methodinfo *m, uint64_t *argument_regs, uint64_t *argument_stack);
+void localref_native_exit(methodinfo *m, uint64_t *return_regs);
+
+#if !defined(NDEBUG)
+void localref_dump(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _LOCALREF_HPP
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c++
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
// Includes.
#include "mm/memory.h"
-#include "native/localref.h"
+#include "native/localref.hpp"
#include "threads/lock.hpp"
libjit.la
libjit_la_SOURCES = \
- argument.c \
- argument.h \
+ argument.cpp \
+ argument.hpp \
builtin.cpp \
builtin.hpp \
builtintable.inc \
#include "mm/memory.h"
-#include "native/localref.h"
+#include "native/localref.hpp"
#include "native/native.hpp"
#include "threads/lock.hpp"
+++ /dev/null
-/* src/vm/jit/argument.c - argument passing from and to JIT methods
-
- Copyright (C) 2007, 2008
- CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
- This file is part of CACAO.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdint.h>
-
-#include "arch.h"
-
-#include "mm/memory.h"
-
-#include "native/llni.h"
-
-#include "vm/array.h"
-#include "vm/descriptor.h"
-#include "vm/global.h"
-#include "vm/method.h"
-#include "vm/primitive.hpp"
-#include "vm/resolve.h"
-#include "vm/vm.hpp"
-
-#include "vm/jit/abi-asm.h"
-
-
-/* argument_jitarray_load ******************************************************
-
- Returns the argument specified by index from one of the passed arrays
- and returns it.
-
-*******************************************************************************/
-
-imm_union argument_jitarray_load(methoddesc *md, int32_t index,
- uint64_t *arg_regs, uint64_t *stack)
-{
- imm_union ret;
- paramdesc *pd;
-
- pd = &md->params[index];
-
- switch (md->paramtypes[index].type) {
- case TYPE_INT:
- case TYPE_ADR:
- if (pd->inmemory) {
-#if (SIZEOF_VOID_P == 8)
- ret.l = (int64_t)stack[pd->index];
-#else
- ret.l = *(int32_t *)(stack + pd->index);
-#endif
- } else {
-#if (SIZEOF_VOID_P == 8)
- ret.l = arg_regs[index];
-#else
- ret.l = *(int32_t *)(arg_regs + index);
-#endif
- }
- break;
- case TYPE_LNG:
- if (pd->inmemory) {
- ret.l = (int64_t)stack[pd->index];
- } else {
- ret.l = (int64_t)arg_regs[index];
- }
- break;
- case TYPE_FLT:
- if (pd->inmemory) {
- ret.l = (int64_t)stack[pd->index];
- } else {
- ret.l = (int64_t)arg_regs[index];
- }
- break;
- case TYPE_DBL:
- if (pd->inmemory) {
- ret.l = (int64_t)stack[pd->index];
- } else {
- ret.l = (int64_t)arg_regs[index];
- }
- break;
- }
-
- return ret;
-}
-
-
-/* argument_jitarray_store *****************************************************
-
- Stores the argument into one of the passed arrays at a slot specified
- by index.
-
-*******************************************************************************/
-
-void argument_jitarray_store(methoddesc *md, int32_t index,
- uint64_t *arg_regs, uint64_t *stack,
- imm_union param)
-{
- paramdesc *pd;
-
- pd = &md->params[index];
-
- switch (md->paramtypes[index].type) {
- case TYPE_ADR:
- if (pd->inmemory) {
-#if (SIZEOF_VOID_P == 8)
- stack[pd->index] = param.l;
-#else
- assert(0);
-#endif
- } else {
- arg_regs[index] = param.l;
- }
- break;
- default:
- vm_abort("argument_jitarray_store: type not implemented");
- break;
- }
-}
-
-
-/* argument_jitreturn_load *****************************************************
-
- Loads the proper return value form the return register and returns it.
-
-*******************************************************************************/
-
-imm_union argument_jitreturn_load(methoddesc *md, uint64_t *return_regs)
-{
- imm_union ret;
-
- switch (md->returntype.type) {
- case TYPE_INT:
- case TYPE_ADR:
-#if (SIZEOF_VOID_P == 8)
- ret.l = return_regs[0];
-#else
- ret.l = *(int32_t *)return_regs;
-#endif
- break;
- case TYPE_LNG:
- ret.l = *(int64_t *)return_regs;
- break;
- case TYPE_FLT:
- ret.l = *(int64_t *)return_regs;
- break;
- case TYPE_DBL:
- ret.l = *(int64_t *)return_regs;
- break;
- }
-
- return ret;
-}
-
-
-/* argument_jitreturn_store ****************************************************
-
- Stores the proper return value into the return registers.
-
-*******************************************************************************/
-
-void argument_jitreturn_store(methoddesc *md, uint64_t *return_regs, imm_union ret)
-{
- switch (md->returntype.type) {
- case TYPE_ADR:
-#if (SIZEOF_VOID_P == 8)
- return_regs[0] = ret.l;
-#else
- assert(0);
-#endif
- break;
- default:
- vm_abort("argument_jitreturn_store: type not implemented");
- break;
- }
-}
-
-
-/* argument_vmarray_store_int **************************************************
-
- Helper function to store an integer into the argument array, taking
- care of architecture specific issues.
-
-*******************************************************************************/
-
-static void argument_vmarray_store_int(uint64_t *array, paramdesc *pd, int32_t value)
-{
- int32_t index;
-
- if (!pd->inmemory) {
- index = pd->index;
- array[index] = (int64_t) value;
- }
- else {
- index = ARG_CNT + pd->index;
-#if SIZEOF_VOID_P == 8
- array[index] = (int64_t) value;
-#else
-# if WORDS_BIGENDIAN == 1
- array[index] = ((int64_t) value) << 32;
-# else
- array[index] = (int64_t) value;
-# endif
-#endif
- }
-}
-
-
-/* argument_vmarray_store_lng **************************************************
-
- Helper function to store a long into the argument array, taking
- care of architecture specific issues.
-
-*******************************************************************************/
-
-static void argument_vmarray_store_lng(uint64_t *array, paramdesc *pd, int64_t value)
-{
- int32_t index;
-
-#if SIZEOF_VOID_P == 8
- if (!pd->inmemory)
- index = pd->index;
- else
- index = ARG_CNT + pd->index;
-
- array[index] = value;
-#else
- if (!pd->inmemory) {
- /* move low and high 32-bits into it's own argument slot */
-
- index = GET_LOW_REG(pd->index);
- array[index] = value & 0x00000000ffffffff;
-
- index = GET_HIGH_REG(pd->index);
- array[index] = value >> 32;
- }
- else {
- index = ARG_CNT + pd->index;
- array[index] = value;
- }
-#endif
-}
-
-
-/* argument_vmarray_store_flt **************************************************
-
- Helper function to store a float into the argument array, taking
- care of architecture specific issues.
-
-*******************************************************************************/
-
-static void argument_vmarray_store_flt(uint64_t *array, paramdesc *pd, uint64_t value)
-{
- int32_t index;
-
- if (!pd->inmemory) {
-#if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
- index = pd->index;
-#else
- index = INT_ARG_CNT + pd->index;
-#endif
-#if WORDS_BIGENDIAN == 1 && !defined(__POWERPC__) && !defined(__POWERPC64__) && !defined(__S390__)
- array[index] = value >> 32;
-#else
- array[index] = value;
-#endif
- }
- else {
- index = ARG_CNT + pd->index;
-#if defined(__SPARC_64__)
- array[index] = value >> 32;
-#else
- array[index] = value;
-#endif
- }
-}
-
-
-/* argument_vmarray_store_dbl **************************************************
-
- Helper function to store a double into the argument array, taking
- care of architecture specific issues.
-
-*******************************************************************************/
-
-static void argument_vmarray_store_dbl(uint64_t *array, paramdesc *pd, uint64_t value)
-{
- int32_t index;
-
- if (!pd->inmemory) {
-#if SIZEOF_VOID_P != 8 && defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
- index = GET_LOW_REG(pd->index);
- array[index] = value & 0x00000000ffffffff;
-
- index = GET_HIGH_REG(pd->index);
- array[index] = value >> 32;
-#else
- index = INT_ARG_CNT + pd->index;
- array[index] = value;
-#endif
- }
- else {
- index = ARG_CNT + pd->index;
- array[index] = value;
- }
-}
-
-
-/* argument_vmarray_store_adr **************************************************
-
- Helper function to store an address into the argument array, taking
- care of architecture specific issues.
-
- ATTENTION: This function has to be used outside the nativeworld.
-
-*******************************************************************************/
-
-static void argument_vmarray_store_adr(uint64_t *array, paramdesc *pd, java_handle_t *h)
-{
- void *value;
- int32_t index;
-
- /* Take the reference value out of the handle. */
-
- value = LLNI_UNWRAP(h);
-
- if (!pd->inmemory) {
-#if defined(HAS_ADDRESS_REGISTER_FILE)
- /* When the architecture has address registers, place them
- after integer and float registers. */
-
- index = INT_ARG_CNT + FLT_ARG_CNT + pd->index;
-#else
- index = pd->index;
-#endif
- array[index] = (uint64_t) (intptr_t) value;
- }
- else {
- index = ARG_CNT + pd->index;
-#if SIZEOF_VOID_P == 8
- array[index] = (uint64_t) (intptr_t) value;
-#else
-# if WORDS_BIGENDIAN == 1
- array[index] = ((uint64_t) (intptr_t) value) << 32;
-# else
- array[index] = (uint64_t) (intptr_t) value;
-# endif
-#endif
- }
-}
-
-
-/* argument_vmarray_from_valist ************************************************
-
- Creates an argument array which can be passed to asm_vm_call_method.
- The array is created from the passed valist.
-
- ATTENTION: This function has to be used outside the native world.
-
-*******************************************************************************/
-
-uint64_t *argument_vmarray_from_valist(methodinfo *m, java_handle_t *o, va_list ap)
-{
- methoddesc *md;
- paramdesc *pd;
- typedesc *td;
- uint64_t *array;
- int32_t i;
- imm_union value;
-
- /* get the descriptors */
-
- md = m->parseddesc;
- pd = md->params;
- td = md->paramtypes;
-
- /* allocate argument array */
-
- array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + md->memuse);
-
- /* if method is non-static fill first block and skip `this' pointer */
-
- i = 0;
-
- if (o != NULL) {
- /* the `this' pointer */
- argument_vmarray_store_adr(array, pd, o);
-
- pd++;
- td++;
- i++;
- }
-
- for (; i < md->paramcount; i++, pd++, td++) {
- switch (td->type) {
- case TYPE_INT:
- value.i = va_arg(ap, int32_t);
- argument_vmarray_store_int(array, pd, value.i);
- break;
-
- case TYPE_LNG:
- value.l = va_arg(ap, int64_t);
- argument_vmarray_store_lng(array, pd, value.l);
- break;
-
- case TYPE_FLT:
-#if defined(__ALPHA__) || defined(__POWERPC__) || defined(__POWERPC64__)
- /* This is required to load the correct float value in
- assembler code. */
-
- value.d = (double) va_arg(ap, double);
-#else
- value.f = (float) va_arg(ap, double);
-#endif
- argument_vmarray_store_flt(array, pd, value.l);
- break;
-
- case TYPE_DBL:
- value.d = va_arg(ap, double);
- argument_vmarray_store_dbl(array, pd, value.l);
- break;
-
- case TYPE_ADR:
- value.a = va_arg(ap, void*);
- argument_vmarray_store_adr(array, pd, value.a);
- break;
- }
- }
-
- return array;
-}
-
-
-/* argument_vmarray_from_jvalue ************************************************
-
- Creates an argument array which can be passed to asm_vm_call_method.
- The array is created from the passed jvalue array.
-
- ATTENTION: This function has to be used outside the native world.
-
-*******************************************************************************/
-
-uint64_t *argument_vmarray_from_jvalue(methodinfo *m, java_handle_t *o,
- const jvalue *args)
-{
- methoddesc *md;
- paramdesc *pd;
- typedesc *td;
- uint64_t *array;
- int32_t i;
- int32_t j;
-
- /* get the descriptors */
-
- md = m->parseddesc;
- pd = md->params;
- td = md->paramtypes;
-
- /* allocate argument array */
-
-#if defined(HAS_ADDRESS_REGISTER_FILE)
- array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + ADR_ARG_CNT + md->memuse);
-#else
- array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + md->memuse);
-#endif
-
- /* if method is non-static fill first block and skip `this' pointer */
-
- i = 0;
-
- if (o != NULL) {
- /* the `this' pointer */
- argument_vmarray_store_adr(array, pd, o);
-
- pd++;
- td++;
- i++;
- }
-
- for (j = 0; i < md->paramcount; i++, j++, pd++, td++) {
- switch (td->primitivetype) {
- case TYPE_INT:
- argument_vmarray_store_int(array, pd, args[j].i);
- break;
-
- case TYPE_LNG:
- argument_vmarray_store_lng(array, pd, args[j].j);
- break;
-
- case TYPE_FLT:
- argument_vmarray_store_flt(array, pd, args[j].j);
- break;
-
- case TYPE_DBL:
- argument_vmarray_store_dbl(array, pd, args[j].j);
- break;
-
- case TYPE_ADR:
- argument_vmarray_store_adr(array, pd, (java_handle_t *) args[j].l);
- break;
- }
- }
-
- return array;
-}
-
-
-/* argument_vmarray_from_objectarray *******************************************
-
- Creates an argument array which can be passed to asm_vm_call_method.
- The array is created from the passed objectarray of boxed values.
-
- ATTENTION: This function has to be used outside the native world.
-
- RETURN VALUE:
- NULL.........indicates an error while creating the array
- (-1).........no error, but an empty array
- otherwise....array containing the argument values
-
-*******************************************************************************/
-
-uint64_t *argument_vmarray_from_objectarray(methodinfo *m, java_handle_t *o,
- java_handle_objectarray_t *params)
-{
- methoddesc *md;
- paramdesc *pd;
- typedesc *td;
- uint64_t *array;
- java_handle_t *param;
- classinfo *c;
- int type;
- int32_t i;
- int32_t j;
- imm_union value;
-
- /* get the descriptors */
-
- md = m->parseddesc;
- pd = md->params;
- td = md->paramtypes;
-
- /* allocate argument array */
-
- array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + md->memuse);
-
- /* The array can be NULL if we don't have any arguments to pass
- and the architecture does not have any argument registers
- (e.g. i386). In that case we return (-1) to indicate
- that no exception should be thrown */
-
- if (array == NULL)
- array = (uint64_t *)(-1);
-
- /* if method is non-static fill first block and skip `this' pointer */
-
- i = 0;
-
- if (o != NULL) {
- /* this pointer */
- argument_vmarray_store_adr(array, pd, o);
-
- pd++;
- td++;
- i++;
- }
-
- for (j = 0; i < md->paramcount; i++, j++, pd++, td++) {
- /* XXX This function can throw an exception, which should not happend
- here, since we are outside the nativeworld. */
- param = array_objectarray_element_get(params, j);
-
- switch (td->type) {
- case TYPE_INT:
- if (param == NULL)
- return NULL;
-
- /* convert the value according to its declared type */
-
- LLNI_class_get(param, c);
- type = Primitive_get_type_by_wrapperclass(c);
-
- switch (td->primitivetype) {
- case PRIMITIVETYPE_BOOLEAN:
- switch (type) {
- case PRIMITIVETYPE_BOOLEAN:
- /* This type is OK. */
- break;
- default:
- return NULL;
- }
- break;
-
- case PRIMITIVETYPE_BYTE:
- switch (type) {
- case PRIMITIVETYPE_BYTE:
- /* This type is OK. */
- break;
- default:
- return NULL;
- }
- break;
-
- case PRIMITIVETYPE_CHAR:
- switch (type) {
- case PRIMITIVETYPE_CHAR:
- /* This type is OK. */
- break;
- default:
- return NULL;
- }
- break;
-
- case PRIMITIVETYPE_SHORT:
- switch (type) {
- case PRIMITIVETYPE_BYTE:
- case PRIMITIVETYPE_SHORT:
- /* These types are OK. */
- break;
- default:
- return NULL;
- }
- break;
-
- case PRIMITIVETYPE_INT:
- switch (type) {
- case PRIMITIVETYPE_BYTE:
- case PRIMITIVETYPE_SHORT:
- case PRIMITIVETYPE_INT:
- /* These types are OK. */
- break;
- default:
- return NULL;
- }
- break;
-
- default:
- vm_abort("argument_vmarray_from_objectarray: invalid type %d",
- td->primitivetype);
- }
-
- value = Primitive_unbox(param);
- argument_vmarray_store_int(array, pd, value.i);
- break;
-
- case TYPE_LNG:
- if (param == NULL)
- return NULL;
-
- LLNI_class_get(param, c);
- type = Primitive_get_type_by_wrapperclass(c);
-
- assert(td->primitivetype == PRIMITIVETYPE_LONG);
-
- switch (type) {
- case PRIMITIVETYPE_BYTE:
- case PRIMITIVETYPE_SHORT:
- case PRIMITIVETYPE_INT:
- case PRIMITIVETYPE_LONG:
- /* These types are OK. */
- break;
- default:
- return NULL;
- }
-
- value = Primitive_unbox(param);
- argument_vmarray_store_lng(array, pd, value.l);
- break;
-
- case TYPE_FLT:
- if (param == NULL)
- return NULL;
-
- LLNI_class_get(param, c);
- type = Primitive_get_type_by_wrapperclass(c);
-
- assert(td->primitivetype == PRIMITIVETYPE_FLOAT);
-
- switch (type) {
- case PRIMITIVETYPE_FLOAT:
- /* This type is OK. */
- break;
- default:
- return NULL;
- }
-
- value = Primitive_unbox(param);
- argument_vmarray_store_flt(array, pd, value.l);
- break;
-
- case TYPE_DBL:
- if (param == NULL)
- return NULL;
-
- LLNI_class_get(param, c);
- type = Primitive_get_type_by_wrapperclass(c);
-
- assert(td->primitivetype == PRIMITIVETYPE_DOUBLE);
-
- switch (type) {
- case PRIMITIVETYPE_FLOAT:
- case PRIMITIVETYPE_DOUBLE:
- /* These types are OK. */
- break;
- default:
- return NULL;
- }
-
- value = Primitive_unbox(param);
- argument_vmarray_store_dbl(array, pd, value.l);
- break;
-
- case TYPE_ADR:
- if (!resolve_class_from_typedesc(td, true, true, &c))
- return NULL;
-
- if (param != NULL) {
- if (td->arraydim > 0) {
- if (!builtin_arrayinstanceof(param, c))
- return NULL;
- }
- else {
- if (!builtin_instanceof(param, c))
- return NULL;
- }
- }
-
- argument_vmarray_store_adr(array, pd, param);
- break;
-
- default:
- vm_abort("argument_vmarray_from_objectarray: invalid type %d", td->type);
- }
- }
-
- return array;
-}
-
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of the file, where
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- * vim:noexpandtab:sw=4:ts=4:
- */
--- /dev/null
+/* src/vm/jit/argument.cpp - argument passing from and to JIT methods
+
+ Copyright (C) 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+ This file is part of CACAO.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "arch.h"
+
+#include "mm/memory.h"
+
+#include "native/llni.h"
+
+#include "vm/array.h"
+#include "vm/descriptor.h"
+#include "vm/global.h"
+#include "vm/method.h"
+#include "vm/primitive.hpp"
+#include "vm/resolve.h"
+#include "vm/vm.hpp"
+
+#include "vm/jit/abi-asm.h"
+
+
+/* argument_jitarray_load ******************************************************
+
+ Returns the argument specified by index from one of the passed arrays
+ and returns it.
+
+*******************************************************************************/
+
+imm_union argument_jitarray_load(methoddesc *md, int32_t index,
+ uint64_t *arg_regs, uint64_t *stack)
+{
+ imm_union ret;
+ paramdesc *pd;
+
+ pd = &md->params[index];
+
+ switch (md->paramtypes[index].type) {
+ case TYPE_INT:
+ case TYPE_ADR:
+ if (pd->inmemory) {
+#if (SIZEOF_VOID_P == 8)
+ ret.l = (int64_t)stack[pd->index];
+#else
+ ret.l = *(int32_t *)(stack + pd->index);
+#endif
+ } else {
+#if (SIZEOF_VOID_P == 8)
+ ret.l = arg_regs[index];
+#else
+ ret.l = *(int32_t *)(arg_regs + index);
+#endif
+ }
+ break;
+ case TYPE_LNG:
+ if (pd->inmemory) {
+ ret.l = (int64_t)stack[pd->index];
+ } else {
+ ret.l = (int64_t)arg_regs[index];
+ }
+ break;
+ case TYPE_FLT:
+ if (pd->inmemory) {
+ ret.l = (int64_t)stack[pd->index];
+ } else {
+ ret.l = (int64_t)arg_regs[index];
+ }
+ break;
+ case TYPE_DBL:
+ if (pd->inmemory) {
+ ret.l = (int64_t)stack[pd->index];
+ } else {
+ ret.l = (int64_t)arg_regs[index];
+ }
+ break;
+ }
+
+ return ret;
+}
+
+
+/* argument_jitarray_store *****************************************************
+
+ Stores the argument into one of the passed arrays at a slot specified
+ by index.
+
+*******************************************************************************/
+
+void argument_jitarray_store(methoddesc *md, int32_t index,
+ uint64_t *arg_regs, uint64_t *stack,
+ imm_union param)
+{
+ paramdesc *pd;
+
+ pd = &md->params[index];
+
+ switch (md->paramtypes[index].type) {
+ case TYPE_ADR:
+ if (pd->inmemory) {
+#if (SIZEOF_VOID_P == 8)
+ stack[pd->index] = param.l;
+#else
+ assert(0);
+#endif
+ } else {
+ arg_regs[index] = param.l;
+ }
+ break;
+ default:
+ os::abort("argument_jitarray_store: type not implemented");
+ break;
+ }
+}
+
+
+/* argument_jitreturn_load *****************************************************
+
+ Loads the proper return value form the return register and returns it.
+
+*******************************************************************************/
+
+imm_union argument_jitreturn_load(methoddesc *md, uint64_t *return_regs)
+{
+ imm_union ret;
+
+ switch (md->returntype.type) {
+ case TYPE_INT:
+ case TYPE_ADR:
+#if (SIZEOF_VOID_P == 8)
+ ret.l = return_regs[0];
+#else
+ ret.l = *(int32_t *)return_regs;
+#endif
+ break;
+ case TYPE_LNG:
+ ret.l = *(int64_t *)return_regs;
+ break;
+ case TYPE_FLT:
+ ret.l = *(int64_t *)return_regs;
+ break;
+ case TYPE_DBL:
+ ret.l = *(int64_t *)return_regs;
+ break;
+ }
+
+ return ret;
+}
+
+
+/* argument_jitreturn_store ****************************************************
+
+ Stores the proper return value into the return registers.
+
+*******************************************************************************/
+
+void argument_jitreturn_store(methoddesc *md, uint64_t *return_regs, imm_union ret)
+{
+ switch (md->returntype.type) {
+ case TYPE_ADR:
+#if (SIZEOF_VOID_P == 8)
+ return_regs[0] = ret.l;
+#else
+ assert(0);
+#endif
+ break;
+ default:
+ os::abort("argument_jitreturn_store: type not implemented");
+ break;
+ }
+}
+
+
+/* argument_vmarray_store_int **************************************************
+
+ Helper function to store an integer into the argument array, taking
+ care of architecture specific issues.
+
+*******************************************************************************/
+
+static void argument_vmarray_store_int(uint64_t *array, paramdesc *pd, int32_t value)
+{
+ int32_t index;
+
+ if (!pd->inmemory) {
+ index = pd->index;
+ array[index] = (int64_t) value;
+ }
+ else {
+ index = ARG_CNT + pd->index;
+#if SIZEOF_VOID_P == 8
+ array[index] = (int64_t) value;
+#else
+# if WORDS_BIGENDIAN == 1
+ array[index] = ((int64_t) value) << 32;
+# else
+ array[index] = (int64_t) value;
+# endif
+#endif
+ }
+}
+
+
+/* argument_vmarray_store_lng **************************************************
+
+ Helper function to store a long into the argument array, taking
+ care of architecture specific issues.
+
+*******************************************************************************/
+
+static void argument_vmarray_store_lng(uint64_t *array, paramdesc *pd, int64_t value)
+{
+ int32_t index;
+
+#if SIZEOF_VOID_P == 8
+ if (!pd->inmemory)
+ index = pd->index;
+ else
+ index = ARG_CNT + pd->index;
+
+ array[index] = value;
+#else
+ if (!pd->inmemory) {
+ /* move low and high 32-bits into it's own argument slot */
+
+ index = GET_LOW_REG(pd->index);
+ array[index] = value & 0x00000000ffffffff;
+
+ index = GET_HIGH_REG(pd->index);
+ array[index] = value >> 32;
+ }
+ else {
+ index = ARG_CNT + pd->index;
+ array[index] = value;
+ }
+#endif
+}
+
+
+/* argument_vmarray_store_flt **************************************************
+
+ Helper function to store a float into the argument array, taking
+ care of architecture specific issues.
+
+*******************************************************************************/
+
+static void argument_vmarray_store_flt(uint64_t *array, paramdesc *pd, uint64_t value)
+{
+ int32_t index;
+
+ if (!pd->inmemory) {
+#if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
+ index = pd->index;
+#else
+ index = INT_ARG_CNT + pd->index;
+#endif
+#if WORDS_BIGENDIAN == 1 && !defined(__POWERPC__) && !defined(__POWERPC64__) && !defined(__S390__)
+ array[index] = value >> 32;
+#else
+ array[index] = value;
+#endif
+ }
+ else {
+ index = ARG_CNT + pd->index;
+#if defined(__SPARC_64__)
+ array[index] = value >> 32;
+#else
+ array[index] = value;
+#endif
+ }
+}
+
+
+/* argument_vmarray_store_dbl **************************************************
+
+ Helper function to store a double into the argument array, taking
+ care of architecture specific issues.
+
+*******************************************************************************/
+
+static void argument_vmarray_store_dbl(uint64_t *array, paramdesc *pd, uint64_t value)
+{
+ int32_t index;
+
+ if (!pd->inmemory) {
+#if SIZEOF_VOID_P != 8 && defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
+ index = GET_LOW_REG(pd->index);
+ array[index] = value & 0x00000000ffffffff;
+
+ index = GET_HIGH_REG(pd->index);
+ array[index] = value >> 32;
+#else
+ index = INT_ARG_CNT + pd->index;
+ array[index] = value;
+#endif
+ }
+ else {
+ index = ARG_CNT + pd->index;
+ array[index] = value;
+ }
+}
+
+
+/* argument_vmarray_store_adr **************************************************
+
+ Helper function to store an address into the argument array, taking
+ care of architecture specific issues.
+
+ ATTENTION: This function has to be used outside the nativeworld.
+
+*******************************************************************************/
+
+static void argument_vmarray_store_adr(uint64_t *array, paramdesc *pd, java_handle_t *h)
+{
+ void *value;
+ int32_t index;
+
+ /* Take the reference value out of the handle. */
+
+ value = LLNI_UNWRAP(h);
+
+ if (!pd->inmemory) {
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+ /* When the architecture has address registers, place them
+ after integer and float registers. */
+
+ index = INT_ARG_CNT + FLT_ARG_CNT + pd->index;
+#else
+ index = pd->index;
+#endif
+ array[index] = (uint64_t) (intptr_t) value;
+ }
+ else {
+ index = ARG_CNT + pd->index;
+#if SIZEOF_VOID_P == 8
+ array[index] = (uint64_t) (intptr_t) value;
+#else
+# if WORDS_BIGENDIAN == 1
+ array[index] = ((uint64_t) (intptr_t) value) << 32;
+# else
+ array[index] = (uint64_t) (intptr_t) value;
+# endif
+#endif
+ }
+}
+
+
+/* argument_vmarray_from_valist ************************************************
+
+ Creates an argument array which can be passed to asm_vm_call_method.
+ The array is created from the passed valist.
+
+ ATTENTION: This function has to be used outside the native world.
+
+*******************************************************************************/
+
+uint64_t *argument_vmarray_from_valist(methodinfo *m, java_handle_t *o, va_list ap)
+{
+ methoddesc *md;
+ paramdesc *pd;
+ typedesc *td;
+ uint64_t *array;
+ int32_t i;
+ imm_union value;
+
+ /* get the descriptors */
+
+ md = m->parseddesc;
+ pd = md->params;
+ td = md->paramtypes;
+
+ // Allocate argument array.
+ array = (uint64_t*) DumpMemory::allocate(sizeof(uint64_t) * (INT_ARG_CNT + FLT_ARG_CNT + md->memuse));
+
+ /* if method is non-static fill first block and skip `this' pointer */
+
+ i = 0;
+
+ if (o != NULL) {
+ /* the `this' pointer */
+ argument_vmarray_store_adr(array, pd, o);
+
+ pd++;
+ td++;
+ i++;
+ }
+
+ for (; i < md->paramcount; i++, pd++, td++) {
+ switch (td->type) {
+ case TYPE_INT:
+ value.i = va_arg(ap, int32_t);
+ argument_vmarray_store_int(array, pd, value.i);
+ break;
+
+ case TYPE_LNG:
+ value.l = va_arg(ap, int64_t);
+ argument_vmarray_store_lng(array, pd, value.l);
+ break;
+
+ case TYPE_FLT:
+#if defined(__ALPHA__) || defined(__POWERPC__) || defined(__POWERPC64__)
+ /* This is required to load the correct float value in
+ assembler code. */
+
+ value.d = (double) va_arg(ap, double);
+#else
+ value.f = (float) va_arg(ap, double);
+#endif
+ argument_vmarray_store_flt(array, pd, value.l);
+ break;
+
+ case TYPE_DBL:
+ value.d = va_arg(ap, double);
+ argument_vmarray_store_dbl(array, pd, value.l);
+ break;
+
+ case TYPE_ADR:
+ value.a = va_arg(ap, void*);
+ argument_vmarray_store_adr(array, pd, static_cast<java_handle_t*>(value.a));
+ break;
+ }
+ }
+
+ return array;
+}
+
+
+/* argument_vmarray_from_jvalue ************************************************
+
+ Creates an argument array which can be passed to asm_vm_call_method.
+ The array is created from the passed jvalue array.
+
+ ATTENTION: This function has to be used outside the native world.
+
+*******************************************************************************/
+
+uint64_t *argument_vmarray_from_jvalue(methodinfo *m, java_handle_t *o,
+ const jvalue *args)
+{
+ methoddesc *md;
+ paramdesc *pd;
+ typedesc *td;
+ uint64_t *array;
+ int32_t i;
+ int32_t j;
+
+ /* get the descriptors */
+
+ md = m->parseddesc;
+ pd = md->params;
+ td = md->paramtypes;
+
+ /* allocate argument array */
+
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+ array = (uint64_t*) DumpMemory::allocate(sizeof(uint64_t) * (INT_ARG_CNT + FLT_ARG_CNT + ADR_ARG_CNT + md->memuse));
+#else
+ array = (uint64_t*) DumpMemory::allocate(sizeof(uint64_t) * (INT_ARG_CNT + FLT_ARG_CNT + md->memuse));
+#endif
+
+ /* if method is non-static fill first block and skip `this' pointer */
+
+ i = 0;
+
+ if (o != NULL) {
+ /* the `this' pointer */
+ argument_vmarray_store_adr(array, pd, o);
+
+ pd++;
+ td++;
+ i++;
+ }
+
+ for (j = 0; i < md->paramcount; i++, j++, pd++, td++) {
+ switch (td->primitivetype) {
+ case TYPE_INT:
+ argument_vmarray_store_int(array, pd, args[j].i);
+ break;
+
+ case TYPE_LNG:
+ argument_vmarray_store_lng(array, pd, args[j].j);
+ break;
+
+ case TYPE_FLT:
+ argument_vmarray_store_flt(array, pd, args[j].j);
+ break;
+
+ case TYPE_DBL:
+ argument_vmarray_store_dbl(array, pd, args[j].j);
+ break;
+
+ case TYPE_ADR:
+ argument_vmarray_store_adr(array, pd, (java_handle_t *) args[j].l);
+ break;
+ }
+ }
+
+ return array;
+}
+
+
+/* argument_vmarray_from_objectarray *******************************************
+
+ Creates an argument array which can be passed to asm_vm_call_method.
+ The array is created from the passed objectarray of boxed values.
+
+ ATTENTION: This function has to be used outside the native world.
+
+ RETURN VALUE:
+ NULL.........indicates an error while creating the array
+ (-1).........no error, but an empty array
+ otherwise....array containing the argument values
+
+*******************************************************************************/
+
+uint64_t *argument_vmarray_from_objectarray(methodinfo *m, java_handle_t *o,
+ java_handle_objectarray_t *params)
+{
+ methoddesc *md;
+ paramdesc *pd;
+ typedesc *td;
+ uint64_t *array;
+ java_handle_t *param;
+ classinfo *c;
+ int type;
+ int32_t i;
+ int32_t j;
+ imm_union value;
+
+ /* get the descriptors */
+
+ md = m->parseddesc;
+ pd = md->params;
+ td = md->paramtypes;
+
+ /* allocate argument array */
+
+ array = (uint64_t*) DumpMemory::allocate(sizeof(uint64_t) * (INT_ARG_CNT + FLT_ARG_CNT + md->memuse));
+
+ /* The array can be NULL if we don't have any arguments to pass
+ and the architecture does not have any argument registers
+ (e.g. i386). In that case we return (-1) to indicate
+ that no exception should be thrown */
+
+ if (array == NULL)
+ array = (uint64_t *)(-1);
+
+ /* if method is non-static fill first block and skip `this' pointer */
+
+ i = 0;
+
+ if (o != NULL) {
+ /* this pointer */
+ argument_vmarray_store_adr(array, pd, o);
+
+ pd++;
+ td++;
+ i++;
+ }
+
+ for (j = 0; i < md->paramcount; i++, j++, pd++, td++) {
+ /* XXX This function can throw an exception, which should not happend
+ here, since we are outside the nativeworld. */
+ param = array_objectarray_element_get(params, j);
+
+ switch (td->type) {
+ case TYPE_INT:
+ if (param == NULL)
+ return NULL;
+
+ /* convert the value according to its declared type */
+
+ LLNI_class_get(param, c);
+ type = Primitive::get_type_by_wrapperclass(c);
+
+ switch (td->primitivetype) {
+ case PRIMITIVETYPE_BOOLEAN:
+ switch (type) {
+ case PRIMITIVETYPE_BOOLEAN:
+ /* This type is OK. */
+ break;
+ default:
+ return NULL;
+ }
+ break;
+
+ case PRIMITIVETYPE_BYTE:
+ switch (type) {
+ case PRIMITIVETYPE_BYTE:
+ /* This type is OK. */
+ break;
+ default:
+ return NULL;
+ }
+ break;
+
+ case PRIMITIVETYPE_CHAR:
+ switch (type) {
+ case PRIMITIVETYPE_CHAR:
+ /* This type is OK. */
+ break;
+ default:
+ return NULL;
+ }
+ break;
+
+ case PRIMITIVETYPE_SHORT:
+ switch (type) {
+ case PRIMITIVETYPE_BYTE:
+ case PRIMITIVETYPE_SHORT:
+ /* These types are OK. */
+ break;
+ default:
+ return NULL;
+ }
+ break;
+
+ case PRIMITIVETYPE_INT:
+ switch (type) {
+ case PRIMITIVETYPE_BYTE:
+ case PRIMITIVETYPE_SHORT:
+ case PRIMITIVETYPE_INT:
+ /* These types are OK. */
+ break;
+ default:
+ return NULL;
+ }
+ break;
+
+ default:
+ os::abort("argument_vmarray_from_objectarray: invalid type %d",
+ td->primitivetype);
+ }
+
+ value = Primitive::unbox(param);
+ argument_vmarray_store_int(array, pd, value.i);
+ break;
+
+ case TYPE_LNG:
+ if (param == NULL)
+ return NULL;
+
+ LLNI_class_get(param, c);
+ type = Primitive::get_type_by_wrapperclass(c);
+
+ assert(td->primitivetype == PRIMITIVETYPE_LONG);
+
+ switch (type) {
+ case PRIMITIVETYPE_BYTE:
+ case PRIMITIVETYPE_SHORT:
+ case PRIMITIVETYPE_INT:
+ case PRIMITIVETYPE_LONG:
+ /* These types are OK. */
+ break;
+ default:
+ return NULL;
+ }
+
+ value = Primitive::unbox(param);
+ argument_vmarray_store_lng(array, pd, value.l);
+ break;
+
+ case TYPE_FLT:
+ if (param == NULL)
+ return NULL;
+
+ LLNI_class_get(param, c);
+ type = Primitive::get_type_by_wrapperclass(c);
+
+ assert(td->primitivetype == PRIMITIVETYPE_FLOAT);
+
+ switch (type) {
+ case PRIMITIVETYPE_FLOAT:
+ /* This type is OK. */
+ break;
+ default:
+ return NULL;
+ }
+
+ value = Primitive::unbox(param);
+ argument_vmarray_store_flt(array, pd, value.l);
+ break;
+
+ case TYPE_DBL:
+ if (param == NULL)
+ return NULL;
+
+ LLNI_class_get(param, c);
+ type = Primitive::get_type_by_wrapperclass(c);
+
+ assert(td->primitivetype == PRIMITIVETYPE_DOUBLE);
+
+ switch (type) {
+ case PRIMITIVETYPE_FLOAT:
+ case PRIMITIVETYPE_DOUBLE:
+ /* These types are OK. */
+ break;
+ default:
+ return NULL;
+ }
+
+ value = Primitive::unbox(param);
+ argument_vmarray_store_dbl(array, pd, value.l);
+ break;
+
+ case TYPE_ADR:
+ if (!resolve_class_from_typedesc(td, true, true, &c))
+ return NULL;
+
+ if (param != NULL) {
+ if (td->arraydim > 0) {
+ if (!builtin_arrayinstanceof(param, c))
+ return NULL;
+ }
+ else {
+ if (!builtin_instanceof(param, c))
+ return NULL;
+ }
+ }
+
+ argument_vmarray_store_adr(array, pd, param);
+ break;
+
+ default:
+ os::abort("argument_vmarray_from_objectarray: invalid type %d", td->type);
+ }
+ }
+
+ return array;
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c++
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
+++ /dev/null
-/* src/vm/jit/argument.h - argument passing from and to JIT methods
-
- Copyright (C) 2007, 2008
- CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
- This file is part of CACAO.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
-*/
-
-
-#ifndef _VM_JIT_ARGUMENT_H
-#define _VM_JIT_ARGUMENT_H
-
-#include "config.h"
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "vm/global.h"
-
-
-/* function prototypes ********************************************************/
-
-imm_union argument_jitarray_load(methoddesc *md, int32_t index,
- uint64_t *arg_regs, uint64_t *stack);
-void argument_jitarray_store(methoddesc *md, int32_t index,
- uint64_t *arg_regs, uint64_t *stack,
- imm_union param);
-
-imm_union argument_jitreturn_load(methoddesc *md, uint64_t *return_regs);
-void argument_jitreturn_store(methoddesc *md, uint64_t *return_regs,
- imm_union ret);
-
-uint64_t *argument_vmarray_from_valist(methodinfo *m, java_handle_t *o,
- va_list ap);
-uint64_t *argument_vmarray_from_jvalue(methodinfo *m, java_handle_t *o,
- const jvalue *args);
-uint64_t *argument_vmarray_from_objectarray(methodinfo *m, java_handle_t *o,
- java_handle_objectarray_t *params);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _VM_JIT_ARGUMENT_H */
-
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of the file, where
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- * vim:noexpandtab:sw=4:ts=4:
- */
--- /dev/null
+/* src/vm/jit/argument.hpp - argument passing from and to JIT methods
+
+ Copyright (C) 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+ This file is part of CACAO.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+*/
+
+
+#ifndef _VM_JIT_ARGUMENT_HPP
+#define _VM_JIT_ARGUMENT_HPP
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "vm/global.h"
+#include "vm/method.h"
+
+
+/* function prototypes ********************************************************/
+
+imm_union argument_jitarray_load(methoddesc *md, int32_t index,
+ uint64_t *arg_regs, uint64_t *stack);
+void argument_jitarray_store(methoddesc *md, int32_t index,
+ uint64_t *arg_regs, uint64_t *stack,
+ imm_union param);
+
+imm_union argument_jitreturn_load(methoddesc *md, uint64_t *return_regs);
+void argument_jitreturn_store(methoddesc *md, uint64_t *return_regs,
+ imm_union ret);
+
+uint64_t *argument_vmarray_from_valist(methodinfo *m, java_handle_t *o,
+ va_list ap);
+uint64_t *argument_vmarray_from_jvalue(methodinfo *m, java_handle_t *o,
+ const jvalue *args);
+uint64_t *argument_vmarray_from_objectarray(methodinfo *m, java_handle_t *o,
+ java_handle_objectarray_t *params);
+
+#endif // _VM_JIT_ARGUMENT_HPP
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c++
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
#include "mm/memory.h"
-#include "native/localref.h"
+#include "native/localref.hpp"
#include "native/native.hpp"
#include "threads/lock.hpp"
#include "toolbox/logging.h"
#include "native/llni.h"
-#include "native/localref.h"
+#include "native/localref.hpp"
#include "native/native.hpp"
#include "threads/thread.hpp"
#include "mm/memory.h"
-#include "native/localref.h"
+#include "native/localref.hpp"
#include "native/native.hpp"
#include "threads/lock.hpp"
#include "mm/memory.h"
-#include "native/localref.h"
+#include "native/localref.hpp"
#include "native/native.hpp"
#include "threads/lock.hpp"
#include "mm/memory.h"
-#include "native/localref.h"
+#include "native/localref.hpp"
#include "native/native.hpp"
#include "threads/lock.hpp"
#include "mm/memory.h"
-#include "native/localref.h"
+#include "native/localref.hpp"
#include "native/native.hpp"
#include "threads/lock.hpp"
#include "mm/memory.h"
-#include "native/localref.h"
+#include "native/localref.hpp"
#include "native/native.hpp"
#include "threads/lock.hpp"
#include "vm/jit/s390/emit.h"
#include "vm/jit/s390/md-abi.h"
-#include "native/localref.h"
+#include "native/localref.hpp"
#include "native/native.hpp"
#include "mm/memory.h"
#include "mm/memory.h"
-#include "native/localref.h"
+#include "native/localref.hpp"
#include "native/native.hpp"
#include "vm/jit/builtin.hpp"
#include "vm/string.hpp"
#include "vm/utf8.h"
-#include "vm/jit/argument.h"
+#include "vm/jit/argument.hpp"
#include "vm/jit/codegen-common.hpp"
#include "vm/jit/trace.hpp"
#include "vm/jit/show.hpp"
#include "mm/memory.h"
-#include "native/localref.h"
+#include "native/localref.hpp"
#include "native/native.hpp"
#include "threads/lock.hpp"
classinfo* Primitive_get_class_by_name(utf *name) { return Primitive::get_class_by_name(name); }
classinfo* Primitive_get_class_by_type(int type) { return Primitive::get_class_by_type(type); }
-classinfo* Primitive_get_arrayclass_by_name(utf *name) { return Primitive::get_arrayclass_by_name(name); }
classinfo* Primitive_get_arrayclass_by_type(int type) { return Primitive::get_arrayclass_by_type(type); }
-int Primitive_get_type_by_wrapperclass(classinfo *c) { return Primitive::get_type_by_wrapperclass(c); }
java_handle_t* Primitive_box(int type, imm_union value) { return Primitive::box(type, value); }
imm_union Primitive_unbox(java_handle_t *h) { return Primitive::unbox(h); }
}
classinfo *Primitive_get_class_by_name(utf *name);
classinfo *Primitive_get_class_by_type(int type);
-classinfo *Primitive_get_arrayclass_by_name(utf *name);
classinfo *Primitive_get_arrayclass_by_type(int type);
-int Primitive_get_type_by_wrapperclass(classinfo *c);
-
java_handle_t *Primitive_box(int type, imm_union value);
imm_union Primitive_unbox(java_handle_t *h);
#endif
#include "native/jni.hpp"
#include "native/llni.h"
-#include "native/localref.h"
+#include "native/localref.hpp"
#include "native/native.hpp"
#include "native/vm/nativevm.h"
#include "vm/suck.hpp"
#include "vm/vm.hpp"
-#include "vm/jit/argument.h"
+#include "vm/jit/argument.hpp"
#include "vm/jit/asmpart.h"
#include "vm/jit/code.hpp"