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 + -
显示快捷键?