jvmpi_kaffe.c
来自「基于LWVCL开发的库」· C语言 代码 · 共 831 行 · 第 1/2 页
C
831 行
/* * jvmpi_kaffe.c * Routines for generating an assembly file with debugging information * * Copyright (c) 2003 University of Utah and the Flux Group. * All rights reserved. * * Copyright (c) 2003-2005 * The Kaffe.org's developers. All Rights reserved. * See ChangeLog for details. * * This file is licensed under the terms of the GNU Public License. * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * Contributed by the Flux Research Group, Department of Computer Science, * University of Utah, http://www.cs.utah.edu/flux/ */#include "config.h"#if defined(ENABLE_JVMPI)#include "debug.h"#include "config-std.h"#include "config-mem.h"#include "config-hacks.h"#include "gtypes.h"#include "native.h"#include "object.h"#include "jni.h"#include "code.h"#include "classMethod.h"#include "java_lang_Thread.h"#include "thread.h"#include "stackTrace.h"#include "stringSupport.h"#include <assert.h>#include "jvmpi_kaffe.h"JVMPI_Interface *jvmpiCreateInterface(jint version){ JVMPI_Interface *retval; assert((version == JVMPI_VERSION_1) || (version == JVMPI_VERSION_1_1) || (version == JVMPI_VERSION_1_2)); retval = &jvmpi_data.jk_Interface; retval->version = version; return( retval );}void jvmpiPostEvent(JVMPI_Event *ev){ assert(ev != NULL); assert(ev->event_type >= 0); assert((ev->event_type & ~JVMPI_REQUESTED_EVENT) < JVMPI_EVENT_COUNT); ev->env_id = THREAD_JNIENV(); switch( ev->event_type ) { case JVMPI_EVENT_CLASS_LOAD: case JVMPI_EVENT_CLASS_UNLOAD: case JVMPI_EVENT_OBJECT_ALLOC: gc_disableGC(); break; default: break; } jvmpi_data.jk_Interface.NotifyEvent(ev); switch( ev->event_type ) { case JVMPI_EVENT_CLASS_LOAD: case JVMPI_EVENT_CLASS_UNLOAD: case JVMPI_EVENT_OBJECT_ALLOC: gc_enableGC(); break; default: break; }}void jvmpiConvertField(JVMPI_Field *dst, fields *src){ assert(dst != NULL); assert(src != NULL); dst->field_name = src->name->data; dst->field_signature = src->signature->data;}void jvmpiConvertMethod(JVMPI_Method *dst, methods *src){ assert(dst != NULL); assert(src != NULL); dst->method_name = src->name->data; dst->method_signature = src->parsed_sig->signature->data; if( src->lines != NULL ) { dst->start_lineno = src->lines->entry[0].line_nr; dst->end_lineno = src->lines->entry[src->lines->length].line_nr; } else { dst->start_lineno = -1; dst->end_lineno = -1; } dst->method_id = src;}void jvmpiConvertLineno(JVMPI_Lineno *dst, lineNumberEntry *src, void *start_pc){ assert(dst != NULL); assert(src != NULL); dst->offset = src->start_pc - (uintp)start_pc; dst->lineno = src->line_nr;}void jvmpiFillObjectAlloc(JVMPI_Event *ev, struct Hjava_lang_Object *obj){ struct Hjava_lang_Class *cl; assert(ev != NULL); assert(obj != NULL); cl = OBJECT_CLASS(obj); ev->event_type = JVMPI_EVENT_OBJECT_ALLOC; ev->u.obj_alloc.arena_id = -1; ev->u.obj_alloc.class_id = cl; if( CLASS_IS_ARRAY(cl) ) { jint prim_type = 0; Hjava_lang_Class *eclazz = Kaffe_get_array_element_type(cl); if (CLASS_IS_PRIMITIVE(eclazz)) { switch( CLASS_PRIM_SIG(eclazz) ) { case 'I': prim_type = JVMPI_INT; break; case 'Z': prim_type = JVMPI_BOOLEAN; break; case 'S': prim_type = JVMPI_SHORT; break; case 'B': prim_type = JVMPI_BYTE; break; case 'C': prim_type = JVMPI_CHAR; break; case 'F': prim_type = JVMPI_FLOAT; break; case 'D': prim_type = JVMPI_DOUBLE; break; case 'J': prim_type = JVMPI_LONG; break; default: dprintf("Invalid primitive signature in jvmpiFillObjectAlloc\n"); KAFFEVM_ABORT(); break; } } else prim_type = JVMPI_CLASS; ev->u.obj_alloc.is_array = prim_type; } else { ev->u.obj_alloc.is_array = JVMPI_NORMAL_OBJECT; } ev->u.obj_alloc.size = KGC_getObjectSize(main_collector, obj); ev->u.obj_alloc.obj_id = obj;}void jvmpiFillThreadStart(JVMPI_Event *ev, struct Hjava_lang_VMThread *vmtid){ struct Hjava_lang_String *name; struct Hjava_lang_Thread *tid = unhand(vmtid)->thread; assert(ev != NULL); assert(tid != NULL); ev->event_type = JVMPI_EVENT_THREAD_START; if( (name = stringCharArray2Java(unhand_char_array(tid->name->value), tid->name->count)) != NULL ) ev->u.thread_start.thread_name = stringJava2C(name); else ev->u.thread_start.thread_name = NULL; if (tid->group != NULL) { ev->u.thread_start.group_name = stringJava2C(tid->group->name); if (tid->group->parent != NULL) ev->u.thread_start.parent_name = stringJava2C(tid->group->parent->name); else { ev->u.thread_start.parent_name = (char *)KMALLOC(7); strcpy(ev->u.thread_start.parent_name, "system"); } } else { ev->u.thread_start.group_name = (char *)KMALLOC(7); strcpy(ev->u.thread_start.group_name, "system"); ev->u.thread_start.parent_name = NULL; } ev->u.thread_start.thread_id = tid; ev->u.thread_start.thread_env_id = &KTHREAD(get_data)((jthread_t)tid->vmThread->vmdata)->jniEnv;}void jvmpiCleanupThreadStart(JVMPI_Event *ev){ if (ev->u.thread_start.parent_name != NULL) KFREE(ev->u.thread_start.parent_name); if (ev->u.thread_start.group_name != NULL) KFREE(ev->u.thread_start.group_name); if (ev->u.thread_start.thread_name != NULL) KFREE(ev->u.thread_start.thread_name);}void jvmpiFillClassLoad(JVMPI_Event *ev, struct Hjava_lang_Class *cl){ int lpc; assert(ev != NULL); assert(cl != NULL); for( lpc = 0; lpc < CLASS_NMETHODS(cl); lpc++ ) { jvmpiConvertMethod(&ev->u.class_load.methods[lpc], &(Kaffe_get_class_methods(cl)[lpc])); } for( lpc = 0; lpc < CLASS_NSFIELDS(cl); lpc++ ) { jvmpiConvertField(&ev->u.class_load.statics[lpc], &CLASS_SFIELDS(cl)[lpc]); } for( lpc = 0; lpc < CLASS_NIFIELDS(cl); lpc++ ) { jvmpiConvertField(&ev->u.class_load.instances[lpc], &CLASS_IFIELDS(cl)[lpc]); } ev->event_type = JVMPI_EVENT_CLASS_LOAD; ev->u.class_load.class_name = CLASS_CNAME(cl); ev->u.class_load.source_name = CLASS_SOURCEFILE(cl); ev->u.class_load.num_interfaces = cl->interface_len; ev->u.class_load.num_methods = CLASS_NMETHODS(cl); ev->u.class_load.num_static_fields = CLASS_NSFIELDS(cl); ev->u.class_load.num_instance_fields = CLASS_NIFIELDS(cl); ev->u.class_load.class_id = cl;}void jvmpiFillMethodLoad(JVMPI_Event *ev, Method *xmeth){ ev->event_type = JVMPI_EVENT_COMPILED_METHOD_LOAD; ev->u.compiled_method_load.method_id = xmeth; ev->u.compiled_method_load.code_addr = METHOD_NATIVECODE(xmeth); ev->u.compiled_method_load.code_size = (uintp)xmeth->c.ncode.ncode_end - (uintp)getMethodCodeStart(xmeth); if( xmeth->lines ) { JVMPI_Lineno *jvmpi_lineno = NULL; unsigned int lpc; jvmpi_lineno = alloca(sizeof(JVMPI_Lineno) * xmeth->lines->length); for( lpc = 0; lpc < xmeth->lines->length; lpc++ ) { jvmpiConvertLineno(&jvmpi_lineno[lpc], &xmeth->lines->entry[lpc], METHOD_NATIVECODE(xmeth)); } ev->u.compiled_method_load.lineno_table_size = xmeth->lines->length; ev->u.compiled_method_load.lineno_table = jvmpi_lineno; } else { ev->u.compiled_method_load.lineno_table_size = 0; ev->u.compiled_method_load.lineno_table = NULL; }}static jint jvmpiCreateSystemThread(char *name, jint priority, void (*f)(void *)){ jint retval; if( (priority != JVMPI_NORMAL_PRIORITY) && (priority != JVMPI_MAXIMUM_PRIORITY) && (priority != JVMPI_MINIMUM_PRIORITY) ) { retval = JNI_ERR; } else { jint mapped_priority = 0; Hjava_lang_Thread *th; errorInfo einfo; switch( priority ) { case JVMPI_NORMAL_PRIORITY: mapped_priority = java_lang_Thread_NORM_PRIORITY; break; case JVMPI_MAXIMUM_PRIORITY: mapped_priority = java_lang_Thread_MAX_PRIORITY; break; case JVMPI_MINIMUM_PRIORITY: mapped_priority = java_lang_Thread_MIN_PRIORITY; break; default: assert(0); break; } if( (th = createDaemon(f, name, NULL, mapped_priority, 1024 * 1024, // XXX &einfo)) != NULL ) { retval = JNI_OK; } else { discardErrorInfo(&einfo); retval = JNI_ERR; } } return( retval );}static jint jvmpiDisableEvent(jint event_type, void *arg UNUSED){ jint retval; switch( event_type ) { case JVMPI_EVENT_HEAP_DUMP: case JVMPI_EVENT_MONITOR_DUMP: case JVMPI_EVENT_OBJECT_DUMP: retval = JVMPI_NOT_AVAILABLE; break; default: BITMAP_CLEAR(jvmpi_data.jk_EventMask, event_type); retval = JVMPI_SUCCESS; break; } return( retval );}static void jvmpiDisableGC(void){ gc_disableGC();}static jint jvmpiEnableEvent(jint event_type, void *arg UNUSED){ jint retval = JVMPI_NOT_AVAILABLE; switch( event_type ) { case JVMPI_EVENT_HEAP_DUMP: case JVMPI_EVENT_MONITOR_DUMP: case JVMPI_EVENT_OBJECT_DUMP: retval = JVMPI_NOT_AVAILABLE; break; default: { BITMAP_SET(jvmpi_data.jk_EventMask, event_type); retval = JVMPI_SUCCESS; assert(BITMAP_ISSET(jvmpi_data.jk_EventMask, event_type)); } break; } return( retval );}static void jvmpiEnableGC(void){ gc_enableGC();}static void jvmpiGetCallTrace(JVMPI_CallTrace *trace, jint depth){ stackTraceInfo *sti = NULL; jthread_t jt; assert(trace != NULL); assert(trace->env_id != NULL); assert(trace->frames != NULL); assert(depth > 0); trace->num_frames = 0; if( (jt = KTHREAD(from_data)((threadData *)trace->env_id,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?