utf_null.
(literalstring_u2): Replaced list_addfirst with list_add_first.
* src/vm/builtin.h (BUILTIN_MONITOR_ENTER, BUILTIN_MONITOR_EXIT):
Defined.
* src/vm/jit/powerpc/codegen.c (codegen): Don't use
BUILTIN_staticmonitorenter, use JITDATA_HAS_FLAG_VERBOSECALL instead
of opt_verbosecall.
(createnativestub): Likewise.
* src/vm/jit/code.c: Smaller changes.
* src/vm/jit/code.h (codeinfo): Added optlevel.
* src/vm/jit/Makefile.am (libjit_la_SOURCES): Added recompile.[ch].
* src/vm/jit/recompile.c: New file.
* src/vm/jit/recompile.h: Likewise.
* src/vm/jit/show.c (new_show_method, show_method)
(new_show_basicblock, show_basicblock): Use
JITDATA_HAS_FLAG_SHOWDISASSEMBLE instead of opt_showdisassemble.
* src/vm/jit/profile/profile.c (vm/jit/jit.h): Added.
(list_method_entry): Moved to src/vm/jit/recompile.h.
(profile_thread): First real implementation.
(profile_start_thread): Better code.
(profile_printstats): Use codeinfo frequencies.
* src/vm/jit/jit.c (jit_compile): Set jd->flags properly. Moved
codeinfo memory freeing before dump_release because we need jd, which
is allocated on dump memory.
(jit_recompile): New function.
(jit_compile_intern): Use jd->flags.
* src/vm/jit/codegen-common.c (codegen_createnativestub): Set
jd->flags.
* src/vm/jit/jit.h (JITDATA_FLAG_PARSE, JITDATA_FLAG_VERIFY)
(JITDATA_FLAG_SHOWINTERMEDIATE, JITDATA_FLAG_SHOWDISASSEMBLE)
(JITDATA_FLAG_VERBOSECALL): Added.
(JITDATA_HAS_FLAG_PARSE, JITDATA_HAS_FLAG_VERIFY)
(JITDATA_HAS_FLAG_IFCONV, JITDATA_HAS_FLAG_SHOWINTERMEDIATE)
(JITDATA_HAS_FLAG_SHOWDISASSEMBLE, JITDATA_HAS_FLAG_VERBOSECALL):
Likewise.
(jit_recompile): Likewise.
* src/vm/vm.c (vm/jit/recompile.h): Added.
(vm_create): Call recompile_init and recompile_start_thread.
* src/toolbox/list.h (config.h, vm/types.h, vm/global.h): Added.
(list): Added lock.
(list_init): Renamed to list_create.
(list_addfirst): Renamed to list_add_first.
(list_addlast): Renamed to list_add_last.
(list_add_last_unsynced): New function.
* src/toolbox/list.c (mm/memory.h, threads/native/threads.h)
(vm/builtin.h): Added.
(list_init): Renamed to list_create.
(list_addfirst): Renamed to list_add_first and made synchronized.
(list_addlast): Likewise.
(list_add_last_unsynced): Likewise.
(list_add_before): Made synchronized.
(list_remove): Likewise.
(list_first): Likewise.
(list_last): Likewise.
(list_next): Likewise.
(list_prev): Likewise.
* src/vm/suck.c (suck_init): Replaced list_init with list_create.
(suck_add): Replaced list_addlast with list_add_last.
* src/vm/loader.c (load_constantpool): Replaced list_addfirst with
list_add_first.
(load_newly_created_array): Likewise.
* src/vm/properties.c (properties_init): Replaced list_init with
list_create.
(properties_add): Use list_add_last_unsynced, as this is required
during bootstrapping.
* src/threads/native/threads.h (THREAD_FLAG_JAVA)
(THREAD_FLAG_INTERNAL): Added.
(threadobject): Added flags.
* src/threads/native/threads.c (threads_init): Flag main thread as
Java thread (required for profiling sampling).
(threads_startup_thread): Flag threads as Java or internal thread.
Changes: Christian Thalinger
Edwin Steiner
- $Id: threads.c 5031 2006-06-14 18:36:22Z motse $
+ $Id: threads.c 5049 2006-06-23 12:07:26Z twisti $
*/
threads_table_add(mainthreadobj);
+ /* mark main thread as Java thread */
+
+ mainthreadobj->flags = THREAD_FLAG_JAVA;
+
#if defined(ENABLE_INTRP)
/* create interpreter stack */
Thread startup function called by pthread_create.
+ Thread which have a startup.function != NULL are marked as internal
+ threads. All other threads are threated as normal Java threads.
+
NOTE: This function is not called directly by pthread_create. The Boehm GC
inserts its own GC_start_routine in between, which then calls
threads_startup.
/* find and run the Thread.run()V method if no other function was passed */
if (function == NULL) {
+ /* this is a normal Java thread */
+
+ thread->flags |= THREAD_FLAG_JAVA;
+
method = class_resolveclassmethod(thread->o.header.vftbl->class,
utf_run,
utf_void__void,
thread->o.header.vftbl->class,
true);
- if (!method)
+ if (method == NULL)
throw_exception();
(void) vm_call_method(method, (java_objectheader *) thread);
}
else {
+ /* this is an internal thread */
+
+ thread->flags |= THREAD_FLAG_INTERNAL;
+
/* call passed function, e.g. finalizer_thread */
(function)();
Changes: Christian Thalinger
- $Id: threads.h 5039 2006-06-19 22:23:44Z twisti $
+ $Id: threads.h 5049 2006-06-23 12:07:26Z twisti $
*/
*******************************************************************************/
+#define THREAD_FLAG_JAVA 0x01 /* a normal Java thread */
+#define THREAD_FLAG_INTERNAL 0x02 /* CACAO internal thread */
+
+
struct threadobject {
java_lang_VMThread o; /* the java.lang.VMThread object */
ptrint thinlock; /* pre-computed thin lock value */
- s4 index; /* thread index, startin with 1 */
+ s4 index; /* thread index, starting with 1 */
+ u1 flags; /* flag field */
- pthread_t tid; /* pthread id */
+ pthread_t tid; /* pthread id */
#if defined(__DARWIN__)
mach_port_t mach_thread; /* Darwin thread id */
Authors: Reinhard Grafl
- $Id: list.c 4394 2006-01-31 22:27:23Z twisti $
+ $Id: list.c 5049 2006-06-23 12:07:26Z twisti $
*/
#include "vm/types.h"
+#include "mm/memory.h"
+
+#if defined(ENABLE_THREADS)
+# include "threads/native/threads.h"
+#endif
+
#include "toolbox/list.h"
+#include "vm/builtin.h"
+
+
+/* list_create *****************************************************************
+ Allocates a new list and initializes the lock object.
-void list_init(list *l, int nodeoffset)
+*******************************************************************************/
+
+list *list_create(s4 nodeoffset)
{
- l->first = NULL;
- l->last = NULL;
+ list *l;
+
+ l = NEW(list);
+
+#if defined(ENABLE_THREADS)
+ lock_init_object_lock((java_objectheader *) l);
+#endif
+
+ l->first = NULL;
+ l->last = NULL;
l->nodeoffset = nodeoffset;
+
+ return l;
}
-void list_addfirst(list *l, void *element)
+void list_add_first(list *l, void *element)
{
- listnode *n = (listnode *) (((u1 *) element) + l->nodeoffset);
+ listnode *ln;
+
+ ln = (listnode *) (((u1 *) element) + l->nodeoffset);
+
+ BUILTIN_MONITOR_ENTER(l);
if (l->first) {
- n->prev = NULL;
- n->next = l->first;
- l->first->prev = n;
- l->first = n;
-
- } else {
- n->prev = NULL;
- n->next = NULL;
- l->last = n;
- l->first = n;
+ ln->prev = NULL;
+ ln->next = l->first;
+ l->first->prev = ln;
+ l->first = ln;
+ }
+ else {
+ ln->prev = NULL;
+ ln->next = NULL;
+ l->last = ln;
+ l->first = ln;
+ }
+
+ BUILTIN_MONITOR_EXIT(l);
+}
+
+
+/* list_add_last ***************************************************************
+
+ Adds the element as last element.
+
+*******************************************************************************/
+
+void list_add_last(list *l, void *element)
+{
+ listnode *ln;
+
+ ln = (listnode *) (((u1 *) element) + l->nodeoffset);
+
+ BUILTIN_MONITOR_ENTER(l);
+
+ if (l->last) {
+ ln->prev = l->last;
+ ln->next = NULL;
+ l->last->next = ln;
+ l->last = ln;
+ }
+ else {
+ ln->prev = NULL;
+ ln->next = NULL;
+ l->last = ln;
+ l->first = ln;
}
+
+ BUILTIN_MONITOR_EXIT(l);
}
-void list_addlast(list *l, void *element)
+/* list_add_list_unsynced ******************************************************
+
+ Adds the element as last element but does NO locking!
+
+ ATTENTION: This function is used during bootstrap. DON'T USE IT!!!
+
+*******************************************************************************/
+
+void list_add_last_unsynced(list *l, void *element)
{
- listnode *n = (listnode *) (((u1 *) element) + l->nodeoffset);
+ listnode *ln;
+
+ ln = (listnode *) (((u1 *) element) + l->nodeoffset);
if (l->last) {
- n->prev = l->last;
- n->next = NULL;
- l->last->next = n;
- l->last = n;
-
- } else {
- n->prev = NULL;
- n->next = NULL;
- l->last = n;
- l->first = n;
+ ln->prev = l->last;
+ ln->next = NULL;
+ l->last->next = ln;
+ l->last = ln;
+ }
+ else {
+ ln->prev = NULL;
+ ln->next = NULL;
+ l->last = ln;
+ l->first = ln;
}
}
void list_add_before(list *l, void *element, void *newelement)
{
- listnode *n = (listnode *) (((u1 *) element) + l->nodeoffset);
- listnode *newn = (listnode *) (((u1 *) newelement) + l->nodeoffset);
+ listnode *ln;
+ listnode *newln;
+
+ ln = (listnode *) (((u1 *) element) + l->nodeoffset);
+ newln = (listnode *) (((u1 *) newelement) + l->nodeoffset);
+
+ BUILTIN_MONITOR_ENTER(l);
/* set the new links */
- newn->prev = n->prev;
- newn->next = n;
+ newln->prev = ln->prev;
+ newln->next = ln;
- if (newn->prev)
- newn->prev->next = newn;
+ if (newln->prev)
+ newln->prev->next = newln;
- n->prev = newn;
+ ln->prev = newln;
/* set list's first and last if necessary */
- if (l->first == n)
- l->first = newn;
+ if (l->first == ln)
+ l->first = newln;
+
+ if (l->last == ln)
+ l->last = newln;
- if (l->last == n)
- l->last = newn;
+ BUILTIN_MONITOR_EXIT(l);
}
void list_remove(list *l, void *element)
{
- listnode *n = (listnode *) (((u1 *) element) + l->nodeoffset);
+ listnode *ln;
+
+ ln = (listnode *) (((u1 *) element) + l->nodeoffset);
- if (n->next)
- n->next->prev = n->prev;
+ BUILTIN_MONITOR_ENTER(l);
+
+ if (ln->next)
+ ln->next->prev = ln->prev;
else
- l->last = n->prev;
+ l->last = ln->prev;
- if (n->prev)
- n->prev->next = n->next;
+ if (ln->prev)
+ ln->prev->next = ln->next;
else
- l->first = n->next;
+ l->first = ln->next;
+
+ ln->next = NULL;
+ ln->prev = NULL;
- n->next = NULL;
- n->prev = NULL;
+ BUILTIN_MONITOR_EXIT(l);
}
void *list_first(list *l)
{
- if (!l->first)
- return NULL;
+ void *el;
- return ((u1 *) l->first) - l->nodeoffset;
+ BUILTIN_MONITOR_ENTER(l);
+
+ if (l->first == NULL)
+ el = NULL;
+ else
+ el = ((u1 *) l->first) - l->nodeoffset;
+
+ BUILTIN_MONITOR_EXIT(l);
+
+ return el;
}
void *list_last(list *l)
{
- if (!l->last)
- return NULL;
+ void *el;
+
+ BUILTIN_MONITOR_ENTER(l);
+
+ if (l->last == NULL)
+ el = NULL;
+ else
+ el = ((u1 *) l->last) - l->nodeoffset;
- return ((u1 *) l->last) - l->nodeoffset;
+ BUILTIN_MONITOR_EXIT(l);
+
+ return el;
}
void *list_next(list *l, void *element)
{
- listnode *n;
+ listnode *ln;
+ void *el;
+
+ ln = (listnode *) (((u1 *) element) + l->nodeoffset);
- n = (listnode *) (((u1 *) element) + l->nodeoffset);
+ BUILTIN_MONITOR_ENTER(l);
+
+ if (ln->next == NULL)
+ el = NULL;
+ else
+ el = ((u1 *) ln->next) - l->nodeoffset;
- if (!n->next)
- return NULL;
+ BUILTIN_MONITOR_EXIT(l);
- return ((u1 *) n->next) - l->nodeoffset;
+ return el;
}
void *list_prev(list *l, void *element)
{
- listnode *n;
+ listnode *ln;
+ void *el;
- n = (listnode *) (((u1 *) element) + l->nodeoffset);
+ ln = (listnode *) (((u1 *) element) + l->nodeoffset);
+
+ BUILTIN_MONITOR_ENTER(l);
+
+ if (ln->prev == NULL)
+ el = NULL;
+ else
+ el = ((u1 *) ln->prev) - l->nodeoffset;
- if (!n->prev)
- return NULL;
+ BUILTIN_MONITOR_EXIT(l);
- return ((u1 *) n->prev) - l->nodeoffset;
+ return el;
}
-/* src/toolbox/list.h -
+/* src/toolbox/list.h - synchronized linked list
Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
Changes: Christian Thalinger
- $Id: list.h 4394 2006-01-31 22:27:23Z twisti $
+ $Id: list.h 5049 2006-06-23 12:07:26Z twisti $
*/
#ifndef _LIST_H
#define _LIST_H
+#include "config.h"
+#include "vm/types.h"
+
+#include "vm/global.h"
+
+
/* ---------------------- interface description -----------------------------
The list management with this module works like this:
*/
-typedef struct listnode { /* structure for list element */
- struct listnode *next;
- struct listnode *prev;
-} listnode;
+/* listnode *******************************************************************/
+
+typedef struct listnode listnode;
+
+struct listnode {
+ listnode *next;
+ listnode *prev;
+};
+
+
+/* list ***********************************************************************/
+typedef struct list list;
-typedef struct list { /* structure for list head */
- listnode *first;
- listnode *last;
- int nodeoffset;
-} list;
+struct list {
+#if defined(ENABLE_THREADS)
+ java_objectheader lock; /* threads lock object */
+#endif
+ listnode *first;
+ listnode *last;
+ s4 nodeoffset;
+};
/* function prototypes ********************************************************/
-void list_init(list *l, int nodeoffset);
+list *list_create(s4 nodeoffset);
-void list_addfirst(list *l, void *element);
-void list_addlast(list *l, void *element);
+void list_add_first(list *l, void *element);
+void list_add_last(list *l, void *element);
+void list_add_last_unsynced(list *l, void *element);
void list_add_before(list *l, void *element, void *newelement);
Changes: Edwin Steiner
Christian Thalinger
- $Id: builtin.h 4921 2006-05-15 14:24:36Z twisti $
+ $Id: builtin.h 5049 2006-06-23 12:07:26Z twisti $
*/
#define BUILTIN_staticmonitorenter (functionptr) builtin_staticmonitorenter
void builtin_monitorexit(java_objectheader *o);
#define BUILTIN_monitorexit (functionptr) builtin_monitorexit
+
+# define BUILTIN_MONITOR_ENTER(o) builtin_monitorenter((java_objectheader *) o)
+# define BUILTIN_MONITOR_EXIT(o) builtin_monitorexit((java_objectheader *) o)
+#else
+# define BUILTIN_MONITOR_ENTER(o) /* noop */
+# define BUILTIN_MONITOR_EXIT(o) /* noop */
#endif
s4 builtin_idiv(s4 a, s4 b);
##
## Changes: Edwin Steiner
##
-## $Id: Makefile.am 5045 2006-06-21 16:29:29Z ajordan $
+## $Id: Makefile.am 5049 2006-06-23 12:07:26Z twisti $
## Process this file with automake to produce Makefile.in
parse.h \
reg.c \
reg.h \
+ recompile.c \
+ recompile.h \
replace.c \
replace.h \
show.c \
-/* vm/jit/code.c - codeinfo struct for representing compiled code
+/* src/vm/jit/code.c - codeinfo struct for representing compiled code
Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
Authors: Edwin Steiner
- Changes:
+ Changes: Christian Thalinger
$Id$
#include "vm/options.h"
#include "arch.h"
+
/* code_codeinfo_new ***********************************************************
Create a new codeinfo for the given method.
return code;
}
+
/* code_get_sync_slot_count ****************************************************
Return the number of stack slots used for storing the synchronized object
#endif /* ENABLE_THREADS */
}
+
/* code_get_stack_frame_size ***************************************************
Return the number of stack slots that the stack frame of the given code
return count;
}
+
/* code_codeinfo_free **********************************************************
Free the memory used by a codeinfo.
replace_free_replacement_points(code);
- FREE(code,codeinfo);
+ FREE(code, codeinfo);
}
+
/* code_free_code_of_method ****************************************************
Free all codeinfos of the given method
-/* vm/jit/code.h - codeinfo struct for representing compiled code
+/* src/vm/jit/code.h - codeinfo struct for representing compiled code
Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
Authors: Edwin Steiner
- Changes:
+ Changes: Christian Thalinger
$Id$
/* machine code. */
struct codeinfo {
- methodinfo *m; /* method this is a realization of */
- codeinfo *prev; /* previous codeinfo of this method*/
-
+ methodinfo *m; /* method this is a realization of */
+ codeinfo *prev; /* previous codeinfo of this method */
+
+ u1 optlevel; /* optimization level of this code */
+
/* machine code */
- u1 *mcode; /* pointer to machine code */
- u1 *entrypoint; /* machine code entry point */
- s4 mcodelength; /* length of generated machine code*/
- bool isleafmethod; /* does method call subroutines */
-
- /* replacement */
- rplpoint *rplpoints; /* replacement points */
- rplalloc *regalloc; /* register allocation info */
- s4 rplpointcount; /* number of replacement points */
- s4 globalcount; /* number of global allocations */
- s4 regalloccount; /* number of total allocations */
- s4 memuse; /* number of arg + local slots */
- u1 savedintcount; /* number of callee saved int regs */
- u1 savedfltcount; /* number of callee saved flt regs */
-
- /* profiling XXX will be removed */
- u4 frequency; /* number of method invocations */
- u4 *bbfrequency;
- s8 cycles; /* number of cpu cycles */
+ u1 *mcode; /* pointer to machine code */
+ u1 *entrypoint; /* machine code entry point */
+ s4 mcodelength; /* length of generated machine code */
+ bool isleafmethod; /* does method call subroutines */
+
+ /* replacement */
+ rplpoint *rplpoints; /* replacement points */
+ rplalloc *regalloc; /* register allocation info */
+ s4 rplpointcount; /* number of replacement points */
+ s4 globalcount; /* number of global allocations */
+ s4 regalloccount; /* number of total allocations */
+ s4 memuse; /* number of arg + local slots */
+ u1 savedintcount; /* number of callee saved int regs */
+ u1 savedfltcount; /* number of callee saved flt regs */
+
+ u4 frequency; /* number of method invocations */
+ u4 *bbfrequency;
+ s8 cycles; /* number of cpu cycles */
};
codeinfo *code_codeinfo_new(methodinfo *m);
memory. All functions writing values into the data area return the offset
relative the begin of the code area (start of procedure).
- $Id: codegen-common.c 5038 2006-06-19 22:22:34Z twisti $
+ $Id: codegen-common.c 5049 2006-06-23 12:07:26Z twisti $
*/
code = jd->code;
+ /* set the flags for the current JIT run */
+
+ if (opt_verbosecall)
+ jd->flags |= JITDATA_FLAG_VERBOSECALL;
+
/* setup code generation stuff */
#if defined(ENABLE_JIT)
Christian Thalinger
Christian Ullrich
- $Id: jit.c 5007 2006-06-01 15:09:24Z edwin $
+ $Id: jit.c 5049 2006-06-23 12:07:26Z twisti $
*/
return m->code->entrypoint;
}
-#if defined(ENABLE_THREADS)
/* enter a monitor on the method */
- builtin_monitorenter((java_objectheader *) m);
-#endif
+ BUILTIN_MONITOR_ENTER(m);
/* if method has been already compiled return immediately */
- if (m->code) {
-#if defined(ENABLE_THREADS)
- builtin_monitorexit((java_objectheader *) m);
-#endif
+ if (m->code != NULL) {
+ BUILTIN_MONITOR_EXIT(m);
assert(m->code->entrypoint);
return m->code->entrypoint;
#if defined(ENABLE_LOOP)
jd->ld = DNEW(loopdata);
#endif
- jd->flags = 0;
/* Allocate codeinfo memory from the heap as we need to keep them. */
/* set the flags for the current JIT run */
+ jd->flags = JITDATA_FLAG_PARSE;
+
+ if (opt_verify)
+ jd->flags |= JITDATA_FLAG_VERIFY;
+
if (opt_ifconv)
jd->flags |= JITDATA_FLAG_IFCONV;
+ if (opt_showintermediate)
+ jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
+
+ if (opt_showdisassemble)
+ jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
+
+ if (opt_verbosecall)
+ jd->flags |= JITDATA_FLAG_VERBOSECALL;
+
#if defined(ENABLE_JIT)
# if defined(ENABLE_INTRP)
if (!opt_intrp)
m->instructions = NULL;
m->stack = NULL;
+ if (r != NULL) {
+ DEBUG_JIT_COMPILEVERBOSE("Running: ");
+ }
+ else {
+ /* We had an exception! Finish stuff here if necessary. */
+
+ /* release codeinfo */
+
+ code_codeinfo_free(jd->code);
+
+ /* Release memory for basic block profiling information. */
+
+ if (opt_prof)
+ if (m->bbfrequency)
+ MFREE(m->bbfrequency, u4, m->basicblockcount);
+ }
+
/* release dump area */
dump_release(dumpsize);
compilingtime_stop();
#endif
-
-#if defined(ENABLE_THREADS)
/* leave the monitor */
- builtin_monitorexit((java_objectheader *) m);
+ BUILTIN_MONITOR_EXIT(m);
+
+ /* return pointer to the methods entry point */
+
+ return r;
+}
+
+
+/* jit_recompile ***************************************************************
+
+ Recompiles a Java method.
+
+*******************************************************************************/
+
+u1 *jit_recompile(methodinfo *m)
+{
+ u1 *r;
+ jitdata *jd;
+ u1 optlevel;
+ s4 dumpsize;
+
+ /* check for max. optimization level */
+
+ optlevel = m->code->optlevel;
+
+ if (optlevel == 1) {
+ log_message_method("not recompiling: ", m);
+ return NULL;
+ }
+
+ log_message_method("Recompiling start: ", m);
+
+ STATISTICS(count_jit_calls++);
+
+#if defined(ENABLE_STATISTICS)
+ /* measure time */
+
+ if (opt_getcompilingtime)
+ compilingtime_start();
#endif
- if (r) {
- DEBUG_JIT_COMPILEVERBOSE("Running: ");
+ /* mark start of dump memory area */
+
+ dumpsize = dump_size();
+
+ /* allocate jitdata structure and fill it */
+
+ jd = DNEW(jitdata);
- } else {
+ jd->m = m;
+ jd->cd = DNEW(codegendata);
+ jd->rd = DNEW(registerdata);
+#if defined(ENABLE_LOOP)
+ jd->ld = DNEW(loopdata);
+#endif
+ jd->flags = 0;
+
+ /* Allocate codeinfo memory from the heap as we need to keep them. */
+
+ jd->code = code_codeinfo_new(m); /* XXX check allocation */
+
+ /* set the current optimization level to the previous one plus 1 */
+
+ jd->code->optlevel = optlevel + 1;
+
+ /* get the optimization flags for the current JIT run */
+
+ jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
+ jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
+/* jd->flags |= JITDATA_FLAG_VERBOSECALL; */
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+ if (!opt_intrp)
+# endif
+ /* initialize the register allocator */
+
+ reg_setup(jd);
+#endif
+
+ /* setup the codegendata memory */
+
+ codegen_setup(jd);
+
+ /* now call internal compile function */
+
+ r = jit_compile_intern(jd);
+
+ /* clear pointers to dump memory area */
+
+ m->basicblocks = NULL;
+ m->basicblockindex = NULL;
+ m->instructions = NULL;
+ m->stack = NULL;
+
+ if (r == NULL) {
/* We had an exception! Finish stuff here if necessary. */
- /* Release memory for basic block profiling information. */
+ /* release codeinfo */
- if (opt_prof)
- if (m->bbfrequency)
- MFREE(m->bbfrequency, u4, m->basicblockcount);
+ code_codeinfo_free(jd->code);
}
+ /* release dump area */
+
+ dump_release(dumpsize);
+
+#if defined(ENABLE_STATISTICS)
+ /* measure time */
+
+ if (opt_getcompilingtime)
+ compilingtime_stop();
+#endif
+
+ log_message_method("Recompiling done: ", m);
+
/* return pointer to the methods entry point */
return r;
}
+
/* jit_compile_intern **********************************************************
Static internal function which does the actual compilation.
if (f == NULL)
return NULL;
#else
-
f = NULL;
#endif
/* if there is no javacode, print error message and return empty method */
- if (!m->jcode) {
+ if (m->jcode == NULL) {
DEBUG_JIT_COMPILEVERBOSE("No code given for: ");
code->entrypoint = (u1 *) (ptrint) do_nothing_function;
DEBUG_JIT_COMPILEVERBOSE("Analysing done: ");
#ifdef ENABLE_VERIFIER
- if (opt_verify) {
+ if (jd->flags & JITDATA_FLAG_VERIFY) {
DEBUG_JIT_COMPILEVERBOSE("Typechecking: ");
/* call typecheck pass */
RT_TIMING_GET_TIME(time_loop);
#if defined(ENABLE_IFCONV)
- if (jd->flags & JITDATA_FLAG_IFCONV)
+ if (JITDATA_HAS_FLAG_IFCONV(jd))
if (!ifconv_static(jd))
return NULL;
#endif
#if !defined(NDEBUG)
/* intermediate and assembly code listings */
- if (opt_showintermediate) {
+ if (JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd)) {
show_method(jd);
-
- } else if (opt_showdisassemble) {
+ }
+ else if (JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
# if defined(ENABLE_DISASSEMBLER)
DISASSEMBLE(code->entrypoint,
code->entrypoint + (code->mcodelength - cd->dseglen));
/* jit_asm_compile *************************************************************
- This method is called from asm_vm_call_method and does things like:
- create stackframe info for exceptions, compile the method, patch
- the entrypoint of the method into the calculated address in the JIT
- code, and flushes the instruction cache.
+ This method is called from asm_vm_call_method and does:
+
+ - create stackframe info for exceptions
+ - compile the method
+ - patch the entrypoint of the method into the calculated address in
+ the JIT code
+ - flushes the instruction cache.
*******************************************************************************/
Changes: Christian Thalinger
Edwin Steiner
- $Id: jit.h 5026 2006-06-12 18:50:13Z edwin $
+ $Id: jit.h 5049 2006-06-23 12:07:26Z twisti $
*/
/* jitdata ********************************************************************/
-#define JITDATA_FLAG_IFCONV 0x00000001
+#define JITDATA_FLAG_PARSE 0x00000001
+#define JITDATA_FLAG_VERIFY 0x00000002
+
+#define JITDATA_FLAG_IFCONV 0x00000004
+
+#define JITDATA_FLAG_SHOWINTERMEDIATE 0x20000000
+#define JITDATA_FLAG_SHOWDISASSEMBLE 0x40000000
+#define JITDATA_FLAG_VERBOSECALL 0x80000000
+
+
+#define JITDATA_HAS_FLAG_PARSE(jd) \
+ ((jd)->flags & JITDATA_FLAG_PARSE)
+
+#define JITDATA_HAS_FLAG_VERIFY(jd) \
+ ((jd)->flags & JITDATA_FLAG_VERIFY)
+
+#define JITDATA_HAS_FLAG_IFCONV(jd) \
+ ((jd)->flags & JITDATA_FLAG_IFCONV)
+
+#define JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd) \
+ ((jd)->flags & JITDATA_FLAG_SHOWINTERMEDIATE)
+
+#define JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd) \
+ ((jd)->flags & JITDATA_FLAG_SHOWDISASSEMBLE)
+
+#define JITDATA_HAS_FLAG_VERBOSECALL(jd) \
+ ((jd)->flags & JITDATA_FLAG_VERBOSECALL)
+
struct jitdata {
- methodinfo *m; /* methodinfo of the method compiled */
- codeinfo *code;
- codegendata *cd;
- registerdata *rd;
+ methodinfo *m; /* methodinfo of the method compiled */
+ codeinfo *code;
+ codegendata *cd;
+ registerdata *rd;
#if defined(ENABLE_LOOP)
- loopdata *ld;
+ loopdata *ld;
#endif
- u4 flags; /* contains JIT compiler flags */
+ u4 flags; /* contains JIT compiler flags */
new_instruction *new_instructions;
basicblock *new_basicblocks;
/* compile a method with jit compiler */
u1 *jit_compile(methodinfo *m);
+u1 *jit_recompile(methodinfo *m);
/* patch the method entrypoint */
u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra);
Christian Ullrich
Edwin Steiner
- $Id: codegen.c 5038 2006-06-19 22:22:34Z twisti $
+ $Id: codegen.c 5049 2006-06-23 12:07:26Z twisti $
*/
#if defined(ENABLE_THREADS)
if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
- /* stack offset for monitor argument */
+ p = dseg_addaddress(cd, BUILTIN_monitorenter);
+ M_ALD(REG_ITMP3, REG_PV, p);
+ M_MTCTR(REG_ITMP3);
- s1 = rd->memuse;
-
-#if 0
- if (opt_verbosecall) {
- M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT * 4 + FLT_ARG_CNT * 8));
-
- for (p = 0; p < INT_ARG_CNT; p++)
- M_IST(rd->argintregs[p], REG_SP, p * 4);
-
- for (p = 0; p < FLT_ARG_CNT * 2; p += 2)
- M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 4);
-
- s1 += INT_ARG_CNT + FLT_ARG_CNT;
- }
-#endif
-
- /* decide which monitor enter function to call */
+ /* get or test the lock object */
if (m->flags & ACC_STATIC) {
- p = dseg_addaddress(cd, BUILTIN_staticmonitorenter);
- M_ALD(REG_ITMP3, REG_PV, p);
- M_MTCTR(REG_ITMP3);
- p = dseg_addaddress(cd, m->class);
+ p = dseg_addaddress(cd, &m->class->object.header);
M_ALD(rd->argintregs[0], REG_PV, p);
- M_AST(rd->argintregs[0], REG_SP, s1 * 4);
- M_JSR;
-
- } else {
- p = dseg_addaddress(cd, BUILTIN_monitorenter);
- M_ALD(REG_ITMP3, REG_PV, p);
- M_MTCTR(REG_ITMP3);
+ }
+ else {
M_TST(rd->argintregs[0]);
M_BEQ(0);
codegen_add_nullpointerexception_ref(cd);
- M_AST(rd->argintregs[0], REG_SP, s1 * 4);
- M_JSR;
}
-#if 0
- if (opt_verbosecall) {
- for (p = 0; p < INT_ARG_CNT; p++)
- M_ILD(rd->argintregs[p], REG_SP, p * 4);
-
- for (p = 0; p < FLT_ARG_CNT; p++)
- M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 4);
-
-
- M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
- }
-#endif
+ M_AST(rd->argintregs[0], REG_SP, rd->memuse * 4);
+ M_JSR;
}
#endif
/* call trace function */
- if (opt_verbosecall)
+ if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
codegen_trace_args(jd, stackframesize, false);
}
/* call trace function */
- if (opt_verbosecall) {
+ if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
M_MFLR(REG_ZERO);
M_LDA(REG_SP, REG_SP, -10 * 8);
M_DST(REG_FRESULT, REG_SP, 48+0);
M_AST_INTERN(REG_ZERO, REG_SP, LA_LR_OFFSET);
M_STWU(REG_SP, REG_SP, -(stackframesize * 4));
- if (opt_verbosecall)
+ if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
/* parent_argbase == stackframesize * 4 */
codegen_trace_args(jd, stackframesize * 4 , true);
/* print call trace */
- if (opt_verbosecall) {
+ if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
/* just restore the value we need, don't care about the other */
if (md->returntype.type != TYPE_VOID) {
#include "vm/method.h"
#include "vm/options.h"
#include "vm/stringlocal.h"
+#include "vm/jit/jit.h"
#include "vm/jit/methodheader.h"
-
-
-/* list_method_entry **********************************************************/
-
-typedef struct list_method_entry list_method_entry;
-
-struct list_method_entry {
- methodinfo *m;
- listnode linkage;
-};
+#include "vm/jit/recompile.h"
/* global variables ***********************************************************/
#if defined(ENABLE_THREADS)
-static java_lang_VMThread *profile_vmthread;
+static threadobject *profile_threadobject;
#endif
#if defined(ENABLE_THREADS)
static void profile_thread(void)
{
- threadobject *tobj;
- pthread_t tid;
+ threadobject *t;
s4 nanos;
u1 *pc;
u1 *pv;
- codeinfo *code;
methodinfo *m;
-
- /* Get the thread id of the profiling thread, so we can skip it in
- the profiling runs. */
-
- tobj = THREADOBJECT;
-
- tid = tobj->tid;
+ codeinfo *code;
while (true) {
- /* sleep thread for 0.5-1 ms */
+ /* sleep thread for 0.5-1.0 ms */
nanos = 500 + (int) (500.0 * (rand() / (RAND_MAX + 1.0)));
/* fprintf(stderr, "%d\n", nanos); */
/* iterate over all started threads */
- tobj = mainthreadobj;
+ t = mainthreadobj;
do {
- /* are we a different thread? */
+ /* is this a Java thread? */
- if (tobj->tid != tid) {
+ if (t->flags & THREAD_FLAG_JAVA) {
/* send SIGUSR2 to thread to get the current PC */
- pthread_kill(tobj->tid, SIGUSR2);
+ pthread_kill(t->tid, SIGUSR2);
/* the thread object now contains the current thread PC */
- pc = tobj->pc;
+ pc = t->pc;
/* get the PV for the current PC */
/* get methodinfo pointer from data segment */
if (pv == NULL) {
- m = NULL;
misses++;
}
else {
if (code != NULL) {
m = code->m;
- /* increase the method incovation counter */
+ /* native methods are never recompiled */
- m->frequency++;
- hits++;
+ if (!(m->flags & ACC_NATIVE)) {
+ /* increase the method incovation counter */
-/* if (m->frequency > 1000) { */
-/* printf("Recompile: "); */
-/* method_println(m); */
-/* m->frequency = 0; */
-/* } */
+ code->frequency++;
+ hits++;
+
+ if (code->frequency > 500) {
+ /* clear frequency count before
+ recompilation */
+
+ code->frequency = 0;
+
+ /* add this method to the method list
+ and start recompilation */
+
+ recompile_queue_method(m);
+ }
+ }
}
}
}
- tobj = tobj->next;
- } while ((tobj != NULL) && (tobj != mainthreadobj));
+ t = t->next;
+ } while ((t != NULL) && (t != mainthreadobj));
}
}
#endif
/* create the profile object */
- profile_vmthread =
- (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
+ profile_threadobject = NEW(threadobject);
- if (!profile_vmthread)
+ if (profile_threadobject == NULL)
return false;
t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
- t->vmThread = profile_vmthread;
+ t->vmThread = (java_lang_VMThread *) profile_threadobject;
t->name = javastring_new_from_ascii("Profiling Sampler");
t->daemon = true;
t->priority = 5;
- profile_vmthread->thread = t;
+ profile_threadobject->o.thread = t;
/* actually start the profile sampling thread */
list_method_entry *tlme;
classinfo *c;
methodinfo *m;
+ codeinfo *code;
u4 slot;
classcache_name_entry *nmen;
classcache_class_entry *clsen;
/* create new method list */
- l = NEW(list);
-
- list_init(l, OFFSET(list_method_entry, linkage));
+ l = list_create(OFFSET(list_method_entry, linkage));
/* iterate through all classes and methods */
for (i = 0; i < c->methodscount; i++) {
m = &(c->methods[i]);
+ code = m->code;
+
/* was this method actually called? */
- if (m->frequency > 0) {
+ if ((code != NULL) && (code->frequency > 0)) {
/* add to overall stats */
- frequency += m->frequency;
- cycles += m->cycles;
+ frequency += code->frequency;
+ cycles += code->cycles;
/* create new list entry */
/* sort the new entry into the list */
if ((tlme = list_first(l)) == NULL) {
- list_addfirst(l, lme);
+ list_add_first(l, lme);
}
else {
for (; tlme != NULL; tlme = list_next(l, tlme)) {
/* check the frequency */
- if (m->frequency > tlme->m->frequency) {
+ if (code->frequency > tlme->m->code->frequency) {
list_add_before(l, tlme, lme);
break;
}
it as last entry */
if (tlme == NULL)
- list_addlast(l, lme);
+ list_add_last(l, lme);
}
}
}
m = lme->m;
+ code = m->code;
+
printf("%10d %.5f %12ld %.5f ",
- m->frequency,
- (double) m->frequency / (double) frequency,
- (long)m->cycles,
- (double) m->cycles / (double) cycles);
+ code->frequency,
+ (double) code->frequency / (double) frequency,
+ (long) code->cycles,
+ (double) code->cycles / (double) cycles);
method_println(m);
}
printf("----------- -------------- \n");
- printf("%10d %12ld\n", frequency, (long)cycles);
+ printf("%10d %12ld\n", frequency, (long) cycles);
printf("\nruns : %10d\n", runs);
printf("hits : %10d\n", hits);
--- /dev/null
+/* src/vm/recompile.c - recompilation system
+
+ Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+ E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+ J. Wenninger, J. Wenninger, Institut f. Computersprachen - TU Wien
+
+ 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.
+
+ Contact: cacao@cacaojvm.org
+
+ Authors: Christian Thalinger
+
+ Changes:
+
+ $Id: cacao.c 4357 2006-01-22 23:33:38Z twisti $
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+#include "native/jni.h"
+#include "native/include/java_lang_Thread.h"
+#include "native/include/java_lang_VMThread.h"
+
+#if defined(ENABLE_THREADS)
+# include "threads/native/threads.h"
+#endif
+
+#include "toolbox/list.h"
+#include "vm/builtin.h"
+#include "vm/classcache.h"
+#include "vm/stringlocal.h"
+#include "vm/jit/recompile.h"
+
+
+/* global variables ***********************************************************/
+
+static threadobject *recompile_threadobject;
+static java_objectheader *lock_recompile_thread;
+static list *list_recompile_methods;
+
+
+/* recompile_init **************************************************************
+
+ Initializes the recompilation system.
+
+*******************************************************************************/
+
+bool recompile_init(void)
+{
+ /* initialize the recompile lock object */
+
+ lock_recompile_thread = NEW(java_objectheader);
+
+ lock_init_object_lock(lock_recompile_thread);
+
+ /* create method list */
+
+ list_recompile_methods = list_create(OFFSET(list_method_entry, linkage));
+
+ /* everything's ok */
+
+ return true;
+}
+
+
+/* recompile_replace_vftbl *****************************************************
+
+ XXX
+
+*******************************************************************************/
+
+static void recompile_replace_vftbl(methodinfo *m)
+{
+ codeinfo *code;
+ codeinfo *pcode;
+ u4 slot;
+ classcache_name_entry *nmen;
+ classcache_class_entry *clsen;
+ classinfo *c;
+ vftbl_t *vftbl;
+ s4 i;
+
+ /* get current and previous codeinfo structure */
+
+ code = m->code;
+ pcode = code->prev;
+
+ assert(pcode);
+
+ /* iterate over all classes */
+
+ for (slot = 0; slot < hashtable_classcache.size; slot++) {
+ nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
+
+ for (; nmen; nmen = nmen->hashlink) {
+ /* iterate over all class entries */
+
+ for (clsen = nmen->classes; clsen; clsen = clsen->next) {
+ c = clsen->classobj;
+
+ if (c == NULL)
+ continue;
+
+ /* Search for entrypoint of the previous codeinfo in
+ the vftbl and replace it with the current one. */
+
+ vftbl = c->vftbl;
+
+ /* Is the class linked? Means, is the vftbl finished? */
+
+ if (!(c->state & CLASS_LINKED))
+ continue;
+
+ /* Does the class have a vftbl? Some internal classes
+ (e.g. $NEW$) are linked, but do not have a
+ vftbl. */
+
+ if (vftbl == NULL)
+ continue;
+
+ for (i = 0; i < vftbl->vftbllength; i++) {
+ if (vftbl->table[i] == pcode->entrypoint) {
+ printf("replacing vftbl in: ");
+ class_println(c);
+ vftbl->table[i] = code->entrypoint;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+/* recompile_thread ************************************************************
+
+ XXX
+
+*******************************************************************************/
+
+static void recompile_thread(void)
+{
+ list_method_entry *lme;
+
+ while (true) {
+ /* get the lock on the recompile lock object, so we can call wait */
+
+ builtin_monitorenter(lock_recompile_thread);
+
+ /* wait forever (0, 0) on that object till we are signaled */
+
+ lock_wait_for_object(lock_recompile_thread, 0, 0);
+
+ /* leave the lock */
+
+ builtin_monitorexit(lock_recompile_thread);
+
+ /* get the next method and recompile it */
+
+ while ((lme = list_first(list_recompile_methods)) != NULL) {
+ /* recompile this method */
+
+ (void) jit_recompile(lme->m);
+
+ /* replace in vftbl's */
+
+ recompile_replace_vftbl(lme->m);
+
+ /* remove the compiled method */
+
+ list_remove(list_recompile_methods, lme);
+
+ /* free the entry */
+
+ FREE(lme, list_method_entry);
+ }
+ }
+}
+
+
+/* recompile_start_thread ******************************************************
+
+ Starts the recompilation thread.
+
+*******************************************************************************/
+
+bool recompile_start_thread(void)
+{
+ java_lang_Thread *t;
+
+ /* create the profile object */
+
+ recompile_threadobject = NEW(threadobject);
+
+ if (recompile_threadobject == NULL)
+ return false;
+
+ t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
+
+ t->vmThread = (java_lang_VMThread *) recompile_threadobject;
+ t->name = javastring_new_from_ascii("Recompiler");
+ t->daemon = true;
+ t->priority = 5;
+
+ recompile_threadobject->o.thread = t;
+
+ /* actually start the recompilation thread */
+
+ threads_start_thread(t, recompile_thread);
+
+ /* everything's ok */
+
+ return true;
+}
+
+
+/* recompile_queue_method ******************************************************
+
+ Adds a method to the recompilation list and signal the
+ recompilation thread that there is some work to do.
+
+*******************************************************************************/
+
+void recompile_queue_method(methodinfo *m)
+{
+ list_method_entry *lme;
+
+ /* create a method entry */
+
+ lme = NEW(list_method_entry);
+ lme->m = m;
+
+ /* and add it to the list */
+
+ list_add_last(list_recompile_methods, lme);
+
+ /* get the lock on the recompile lock object, so we can call notify */
+
+ builtin_monitorenter(lock_recompile_thread);
+
+ /* signal the recompiler thread */
+
+ lock_notify_object(lock_recompile_thread);
+
+ /* leave the lock */
+
+ builtin_monitorexit(lock_recompile_thread);
+}
+
+
+/*
+ * 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/vm/jit/recompile.h - recompilation system
+
+ Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+ E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+ J. Wenninger, J. Wenninger, Institut f. Computersprachen - TU Wien
+
+ 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.
+
+ Contact: cacao@cacaojvm.org
+
+ Authors: Christian Thalinger
+
+ Changes:
+
+ $Id: cacao.c 4357 2006-01-22 23:33:38Z twisti $
+
+*/
+
+
+#ifndef _RECOMPILE_H
+#define _RECOMPILE_H
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "vm/global.h"
+
+
+/* list_method_entry **********************************************************/
+
+typedef struct list_method_entry list_method_entry;
+
+struct list_method_entry {
+ methodinfo *m;
+ listnode linkage;
+};
+
+
+/* function prototypes ********************************************************/
+
+bool recompile_init(void);
+bool recompile_start_thread(void);
+
+void recompile_queue_method(methodinfo *m);
+
+#endif /* _PROFILE_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:
+ */
-/* vm/jit/show.c - showing the intermediate representation
+/* src/vm/jit/show.c - showing the intermediate representation
Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
#if defined(ENABLE_DISASSEMBLER)
/* show code before first basic block */
- if (stage >= SHOW_CODE && opt_showdisassemble) {
+ if ((stage >= SHOW_CODE) && JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
u1ptr = (u1 *) ((ptrint) code->mcode + cd->dseglen);
for (; u1ptr < (u1 *) ((ptrint) code->mcode + cd->dseglen + jd->new_basicblocks[0].mpc);)
#if defined(ENABLE_DISASSEMBLER)
/* show code before first basic block */
- if (opt_showdisassemble) {
+ if (JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
u1ptr = (u1 *) ((ptrint) code->mcode + cd->dseglen);
for (; u1ptr < (u1 *) ((ptrint) code->mcode + cd->dseglen + m->basicblocks[0].mpc);)
#if defined(ENABLE_DISASSEMBLER)
/* show stubs code */
- if (opt_showdisassemble && opt_showexceptionstubs) {
+ if (JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd) && opt_showexceptionstubs) {
printf("\nException stubs code:\n");
printf("Length: %d\n\n", (s4) (code->mcodelength -
((ptrint) cd->dseglen +
}
#if defined(ENABLE_DISASSEMBLER)
- if (stage >= SHOW_CODE && opt_showdisassemble && (!deadcode)) {
+ if ((stage >= SHOW_CODE) && JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd) &&
+ (!deadcode)) {
printf("\n");
u1ptr = (u1 *) ((ptrint) code->mcode + cd->dseglen + bptr->mpc);
}
#if defined(ENABLE_DISASSEMBLER)
- if (opt_showdisassemble && (!deadcode)) {
+ if (JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd) && (!deadcode)) {
printf("\n");
u1ptr = (u1 *) ((ptrint) code->mcode + cd->dseglen + bptr->mpc);
Edwin Steiner
Christian Thalinger
- $Id: loader.c 5031 2006-06-14 18:36:22Z motse $
+ $Id: loader.c 5049 2006-06-23 12:07:26Z twisti $
*/
/* link the class later, because we cannot link the class currently
loading */
- list_addfirst(&unlinkedclasses, tc);
+ list_add_first(&unlinkedclasses, tc);
}
/* the classref is created later */
tc = class_java_lang_Cloneable;
LOADER_ASSERT(tc->state & CLASS_LOADED);
- list_addfirst(&unlinkedclasses, tc);
+ list_add_first(&unlinkedclasses, tc);
c->interfaces[0].cls = tc;
tc = class_java_io_Serializable;
LOADER_ASSERT(tc->state & CLASS_LOADED);
- list_addfirst(&unlinkedclasses, tc);
+ list_add_first(&unlinkedclasses, tc);
c->interfaces[1].cls = tc;
} else {
Changes:
- $Id: properties.c 4958 2006-05-26 11:57:20Z twisti $
+ $Id: properties.c 5049 2006-06-23 12:07:26Z twisti $
*/
bool properties_init(void)
{
- list_properties = NEW(list);
-
- list_init(list_properties, OFFSET(list_properties_entry, linkage));
+ list_properties = list_create(OFFSET(list_properties_entry, linkage));
/* everything's ok */
p->key = key;
p->value = value;
- list_addlast(list_properties, p);
+ list_add_last_unsynced(list_properties, p);
}
Changes: Christian Thalinger
Edwin Steiner
- $Id: string.c 4921 2006-05-15 14:24:36Z twisti $
+ $Id: string.c 5049 2006-06-23 12:07:26Z twisti $
*/
*******************************************************************************/
-utf *javastring_toutf(java_lang_String *string, bool isclassname)
+utf *javastring_toutf(java_lang_String *s, bool isclassname)
{
- java_lang_String *str = (java_lang_String *) string;
+ if (s == NULL)
+ return utf_null;
- return utf_new_u2(str->value->data + str->offset, str->count, isclassname);
+ return utf_new_u2(s->value->data + s->offset, s->count, isclassname);
}
s4 javastring_strlen(java_lang_String *s)
{
- if (!s)
+ if (s == NULL)
return 0;
return s->count;
/* if we use eager loading, we have to check loaded String class */
if (opt_eager)
- list_addfirst(&unlinkedclasses, class_java_lang_String);
+ list_add_first(&unlinkedclasses, class_java_lang_String);
/* create new javastring */
Changes:
- $Id: suck.c 5022 2006-06-07 12:51:50Z twisti $
+ $Id: suck.c 5049 2006-06-23 12:07:26Z twisti $
*/
bool suck_init(void)
{
- list_classpath_entries = NEW(list);
-
- list_init(list_classpath_entries, OFFSET(list_classpath_entry, linkage));
+ list_classpath_entries = list_create(OFFSET(list_classpath_entry, linkage));
/* everything's ok */
/* add current classpath entry, if no error */
if (lce)
- list_addlast(list_classpath_entries, lce);
+ list_add_last(list_classpath_entries, lce);
}
/* goto next classpath entry, skip ':' delimiter */
#include "vm/vm.h"
#include "vm/jit/jit.h"
#include "vm/jit/asmpart.h"
+
+#include "vm/jit/recompile.h"
+
#include "vm/jit/profile/profile.h"
#include "vm/rt-timing.h"
#include "native/jvmti/cacaodbg.h"
#endif
+
/* Invocation API variables ***************************************************/
_Jv_JavaVM *_Jv_jvm; /* denotes a Java VM */
throw_main_exception_exit();
#endif
+ /* initialize recompilation */
+
+ if (!recompile_init())
+ throw_main_exception_exit();
+
#if defined(ENABLE_THREADS)
/* finally, start the finalizer thread */
if (!finalizer_start_thread())
throw_main_exception_exit();
+ /* start the recompilation thread (must be done before the
+ profiling thread) */
+
+ if (!recompile_start_thread())
+ throw_main_exception_exit();
+
# if defined(ENABLE_PROFILING)
/* start the profile sampling thread */