/* src/vm/jit/trace.c - Functions for tracing from java code.
- Copyright (C) 1996-2005, 2006, 2007 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, Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
#include "native/include/java_lang_String.h"
#include "native/include/java_lang_Throwable.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
#include "toolbox/logging.h"
#include "vm/global.h"
#include "vm/stringlocal.h"
+#include "vm/jit/argument.h"
#include "vm/jit/codegen-common.h"
#include "vm/jit/trace.h"
#include "vm/jit/show.h"
#endif
-/* _array_load_param **********************************************************
-
- Returns the argument specified by pd and td from one of the passed arrays
- and returns it.
-
-*******************************************************************************/
-
-static imm_union _array_load_param(paramdesc *pd, typedesc *td, uint64_t *arg_regs, uint64_t *stack)
-{
- imm_union ret;
-
- switch (td->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 {
- ret.l = arg_regs[pd->index];
- }
- break;
- case TYPE_LNG:
- if (pd->inmemory) {
- ret.l = (int64_t)stack[pd->index];
- } else {
-#if (SIZEOF_VOID_P == 8)
- ret.l = (int64_t)arg_regs[pd->index];
-#else
- ret.l = (int64_t)(
- (arg_regs[GET_HIGH_REG(pd->index)] << 32) |
- (arg_regs[GET_LOW_REG(pd->index)] & 0xFFFFFFFF)
- );
-#endif
- }
- break;
- case TYPE_FLT:
- if (pd->inmemory) {
- ret.l = (int64_t)stack[pd->index];
- } else {
- ret.l = (int64_t)arg_regs[pd->index + INT_ARG_CNT];
- }
- break;
- case TYPE_DBL:
- if (pd->inmemory) {
- ret.l = (int64_t)stack[pd->index];
- } else {
- ret.l = (int64_t)arg_regs[pd->index + INT_ARG_CNT];
- }
- break;
- }
-
- return ret;
-}
-
-/* _array_load_return_value ***************************************************
-
- Loads the proper return value form the return registers array and returns it.
-
-*******************************************************************************/
-
-static imm_union _array_load_return_value(typedesc *td, uint64_t *return_regs)
-{
- imm_union ret;
-
- switch (td->type) {
- case TYPE_INT:
- case TYPE_ADR:
- ret.l = return_regs[0];
- break;
- case TYPE_LNG:
-#if (SIZEOF_VOID_P == 8)
- ret.l = (int64_t)return_regs[0];
-#else
- ret.l = (int64_t)(
- (return_regs[0] << 32) | (return_regs[1] & 0xFFFFFFFF)
- );
-#endif
- break;
- case TYPE_FLT:
- ret.l = (int64_t)return_regs[2];
- break;
- case TYPE_DBL:
- ret.l = (int64_t)return_regs[2];
- break;
- }
-
- return ret;
-}
-
-
/* trace_java_call_print_argument **********************************************
XXX: Document me!
*******************************************************************************/
-static char *trace_java_call_print_argument(char *logtext, s4 *logtextlen,
- typedesc *paramtype, imm_union imu)
+static char *trace_java_call_print_argument(methodinfo *m, char *logtext, s4 *logtextlen, typedesc *paramtype, imm_union imu)
{
- java_object_t *o;
- classinfo *c;
- utf *u;
- u4 len;
+ java_object_t *o;
+ classinfo *c;
+ utf *u;
+ u4 len;
switch (paramtype->type) {
case TYPE_INT:
sprintf(logtext + strlen(logtext), "0x%016lx", (ptrint) imu.l);
#endif
- /* cast to java.lang.Object */
+ /* Workaround for sun.misc.Unsafe methods. In the future
+ (exact GC) we should check if the address is on the GC
+ heap. */
+
+ if ((m->clazz != NULL) &&
+ (m->clazz->name == utf_new_char("sun/misc/Unsafe")))
+ break;
+
+ /* Cast to java.lang.Object. */
o = (java_object_t *) (ptrint) imu.l;
- /* check return argument for java.lang.Class or java.lang.String */
+ /* Check return argument for java.lang.Class or
+ java.lang.String. */
if (o != NULL) {
- if (o->vftbl->class == class_java_lang_String) {
+ if (o->vftbl->clazz == class_java_lang_String) {
/* get java.lang.String object and the length of the
string */
strcat(logtext, "\")");
}
else {
- if (o->vftbl->class == class_java_lang_Class) {
+ if (o->vftbl->clazz == class_java_lang_Class) {
/* if the object returned is a java.lang.Class
cast it to classinfo structure and get the name
of the class */
/* if the object returned is not a java.lang.String or
a java.lang.Class just print the name of the class */
- u = o->vftbl->class->name;
+ u = o->vftbl->clazz->name;
}
len = strlen(" (Class = \"") + utf_bytes(u) + strlen("\")");
Traces an entry into a java method.
- arg_regs: Array of size ARG_CNT containing all argument registers in
- the same format as in asm_vm_call_method. The array is usually allocated
+ arg_regs: Array containing all argument registers as int64_t values in
+ the same order as listed in m->methoddesc. The array is usually allocated
on the stack and used for restoring the argument registers later.
stack: Pointer to first on stack argument in the same format passed to
void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack)
{
methoddesc *md;
- paramdesc *pd;
- typedesc *td;
- imm_union arg;
+ imm_union arg;
char *logtext;
s4 logtextlen;
- s4 dumpsize;
s4 i;
s4 pos;
+ int32_t dumpmarker;
#if defined(ENABLE_DEBUG_FILTER)
- if (! show_filters_test_verbosecall_enter(m)) return;
+ if (!show_filters_test_verbosecall_enter(m))
+ return;
#endif
#if defined(ENABLE_VMLOG)
strlen("-2147483647-") + /* INT_MAX should be sufficient */
TRACEJAVACALLINDENT +
strlen("called: ") +
- utf_bytes(m->class->name) +
+ ((m->clazz == NULL) ? strlen("NULL") : utf_bytes(m->clazz->name)) +
strlen(".") +
utf_bytes(m->name) +
utf_bytes(m->descriptor);
strlen(" TRANSIENT") +
strlen(" NATIVE") +
strlen(" INTERFACE") +
- strlen(" ABSTRACT");
+ strlen(" ABSTRACT") +
+ strlen(" METHOD_BUILTIN");
/* add maximal argument length */
/* allocate memory */
- dumpsize = dump_size();
+ DMARKER;
logtext = DMNEW(char, logtextlen);
strcpy(logtext + pos, "called: ");
- utf_cat_classname(logtext, m->class->name);
+ if (m->clazz != NULL)
+ utf_cat_classname(logtext, m->clazz->name);
+ else
+ strcat(logtext, "NULL");
strcat(logtext, ".");
utf_cat(logtext, m->name);
utf_cat(logtext, m->descriptor);
- if (m->flags & ACC_PUBLIC) strcat(logtext, " PUBLIC");
- if (m->flags & ACC_PRIVATE) strcat(logtext, " PRIVATE");
- if (m->flags & ACC_PROTECTED) strcat(logtext, " PROTECTED");
- if (m->flags & ACC_STATIC) strcat(logtext, " STATIC");
- if (m->flags & ACC_FINAL) strcat(logtext, " FINAL");
- if (m->flags & ACC_SYNCHRONIZED) strcat(logtext, " SYNCHRONIZED");
- if (m->flags & ACC_VOLATILE) strcat(logtext, " VOLATILE");
- if (m->flags & ACC_TRANSIENT) strcat(logtext, " TRANSIENT");
- if (m->flags & ACC_NATIVE) strcat(logtext, " NATIVE");
- if (m->flags & ACC_INTERFACE) strcat(logtext, " INTERFACE");
- if (m->flags & ACC_ABSTRACT) strcat(logtext, " ABSTRACT");
+ if (m->flags & ACC_PUBLIC) strcat(logtext, " PUBLIC");
+ if (m->flags & ACC_PRIVATE) strcat(logtext, " PRIVATE");
+ if (m->flags & ACC_PROTECTED) strcat(logtext, " PROTECTED");
+ if (m->flags & ACC_STATIC) strcat(logtext, " STATIC");
+ if (m->flags & ACC_FINAL) strcat(logtext, " FINAL");
+ if (m->flags & ACC_SYNCHRONIZED) strcat(logtext, " SYNCHRONIZED");
+ if (m->flags & ACC_VOLATILE) strcat(logtext, " VOLATILE");
+ if (m->flags & ACC_TRANSIENT) strcat(logtext, " TRANSIENT");
+ if (m->flags & ACC_NATIVE) strcat(logtext, " NATIVE");
+ if (m->flags & ACC_INTERFACE) strcat(logtext, " INTERFACE");
+ if (m->flags & ACC_ABSTRACT) strcat(logtext, " ABSTRACT");
+ if (m->flags & ACC_METHOD_BUILTIN) strcat(logtext, " METHOD_BUILTIN");
strcat(logtext, "(");
for (i = 0; i < md->paramcount; ++i) {
- pd = &md->params[i];
- td = &md->paramtypes[i];
- arg = _array_load_param(pd, td, arg_regs, stack);
- logtext = trace_java_call_print_argument(
- logtext, &logtextlen, td, arg
- );
+ arg = argument_jitarray_load(md, i, arg_regs, stack);
+ logtext = trace_java_call_print_argument(m, logtext, &logtextlen,
+ &md->paramtypes[i], arg);
if (i != (md->paramcount - 1)) {
strcat(logtext, ", ");
}
/* release memory */
- dump_release(dumpsize);
+ DRELEASE;
TRACEJAVACALLINDENT++;
Traces an exit form a java method.
- return_regs: Array of size 3 containing return registers:
- [0] : REG_RESULT
- [1] : REG_RESULT2 (if available on architecture)
- [2] : REG_FRESULT
+ return_regs: Array of size 1 containing return register.
The array is usually allocated on the stack and used for restoring the
- registers later. The format of the array is the same as the format of
- register arguments passed to asm_vm_call_method.
+ registers later.
*******************************************************************************/
methoddesc *md;
char *logtext;
s4 logtextlen;
- s4 dumpsize;
s4 i;
s4 pos;
imm_union val;
+ int32_t dumpmarker;
#if defined(ENABLE_DEBUG_FILTER)
if (!show_filters_test_verbosecall_exit(m))
strlen("-2147483647-") + /* INT_MAX should be sufficient */
TRACEJAVACALLINDENT +
strlen("finished: ") +
- utf_bytes(m->class->name) +
+ ((m->clazz == NULL) ? strlen("NULL") : utf_bytes(m->clazz->name)) +
strlen(".") +
utf_bytes(m->name) +
utf_bytes(m->descriptor) +
/* allocate memory */
- dumpsize = dump_size();
+ DMARKER;
logtext = DMNEW(char, logtextlen);
logtext[pos++] = '\t';
strcpy(logtext + pos, "finished: ");
- utf_cat_classname(logtext, m->class->name);
+ if (m->clazz != NULL)
+ utf_cat_classname(logtext, m->clazz->name);
+ else
+ strcat(logtext, "NULL");
strcat(logtext, ".");
utf_cat(logtext, m->name);
utf_cat(logtext, m->descriptor);
if (!IS_VOID_TYPE(md->returntype.type)) {
strcat(logtext, "->");
- val = _array_load_return_value(&md->returntype, return_regs);
+ val = argument_jitreturn_load(md, return_regs);
logtext =
- trace_java_call_print_argument(logtext, &logtextlen, &md->returntype, val);
+ trace_java_call_print_argument(m, logtext, &logtextlen,
+ &md->returntype, val);
}
log_text(logtext);
/* release memory */
- dump_release(dumpsize);
-
+ DRELEASE;
}
{
char *logtext;
s4 logtextlen;
- s4 dumpsize;
codeinfo *code;
+ int32_t dumpmarker;
/* calculate message length */
if (xptr) {
logtextlen =
- strlen("Exception ") + utf_bytes(xptr->vftbl->class->name);
+ strlen("Exception ") + utf_bytes(xptr->vftbl->clazz->name);
}
else {
logtextlen = strlen("Some Throwable");
if (m) {
logtextlen +=
- utf_bytes(m->class->name) +
+ utf_bytes(m->clazz->name) +
strlen(".") +
utf_bytes(m->name) +
utf_bytes(m->descriptor) +
logtextlen += strlen(")(0x12345678) at position 0x12345678 (");
#endif
- if (m->class->sourcefile == NULL)
+ if (m->clazz->sourcefile == NULL)
logtextlen += strlen("<NO CLASSFILE INFORMATION>");
else
- logtextlen += utf_bytes(m->class->sourcefile);
+ logtextlen += utf_bytes(m->clazz->sourcefile);
logtextlen += strlen(":65536)");
/* allocate memory */
- dumpsize = dump_size();
+ DMARKER;
logtext = DMNEW(char, logtextlen);
if (xptr) {
strcpy(logtext, "Exception ");
- utf_cat_classname(logtext, xptr->vftbl->class->name);
+ utf_cat_classname(logtext, xptr->vftbl->clazz->name);
} else {
strcpy(logtext, "Some Throwable");
strcat(logtext, " thrown in ");
if (m) {
- utf_cat_classname(logtext, m->class->name);
+ utf_cat_classname(logtext, m->clazz->name);
strcat(logtext, ".");
utf_cat(logtext, m->name);
utf_cat(logtext, m->descriptor);
(ptrint) code->entrypoint, (ptrint) pos);
#endif
- if (m->class->sourcefile == NULL)
+ if (m->clazz->sourcefile == NULL)
strcat(logtext, "<NO CLASSFILE INFORMATION>");
else
- utf_cat(logtext, m->class->sourcefile);
+ utf_cat(logtext, m->clazz->sourcefile);
sprintf(logtext + strlen(logtext), ":%d)", 0);
}
/* release memory */
- dump_release(dumpsize);
+ DRELEASE;
}
java_lang_String *s;
char *logtext;
s4 logtextlen;
- s4 dumpsize;
+ int32_t dumpmarker;
t = (java_lang_Throwable *) xptr;
if (t) {
logtextlen +=
- utf_bytes(xptr->vftbl->class->name);
+ utf_bytes(xptr->vftbl->clazz->name);
if (s) {
logtextlen += strlen(": ") +
u2_utflength(LLNI_field_direct(s, value)->data
/* allocate memory */
- dumpsize = dump_size();
+ DMARKER;
logtext = DMNEW(char, logtextlen);
strcpy(logtext, "Builtin exception thrown: ");
if (t) {
- utf_cat_classname(logtext, xptr->vftbl->class->name);
+ utf_cat_classname(logtext, xptr->vftbl->clazz->name);
if (s) {
char *buf;
/* release memory */
- dump_release(dumpsize);
+ DRELEASE;
}