java virtual machince kaffe

源代码在线查看: jni-base.c

软件大小: 3714 K
上传用户: l550253832
关键词: machince virtual kaffe java
下载地址: 免注册下载 普通下载 VIP

相关代码

				/*				 * jni-base.c				 * Java Native Interface - Basic exported JNI functions.				 *				 * Copyright (c) 1996, 1997				 *	Transvirtual Technologies, Inc.  All rights reserved.				 *				 * Copyright (c) 2004, 2005				 *      The Kaffe.org's developers. See ChangeLog for details.				 *				 * See the file "license.terms" for information on usage and redistribution 				 * of this file. 				 */								#include "config.h"				#include "config-std.h"				#include "config-mem.h"				#include "debug.h"				#include "jni.h"				#include "jnirefs.h"				#include "jni_i.h"				#include "threadData.h"				#include "thread.h"				#include "baseClasses.h"				#include "kaffe_jni.h"				#include "support.h"				#include "classMethod.h"				#include "jvmpi_kaffe.h"				#include "external.h"				#include "system.h"								/*				 * Keep track of how many VM's are active. Right now				 * we only support one at a time.				 */				static int Kaffe_NumVM = 0;				static jthread_t startingThread;								extern struct JNINativeInterface Kaffe_JNINativeInterface;				extern KaffeVM_Arguments Kaffe_JavaVMInitArgs;								jint				JNI_GetDefaultJavaVMInitArgs(void* args)				{				  JavaVMInitArgs *vm_args = (JavaVMInitArgs *)args;				  switch (vm_args->version)				    {				    case JNI_VERSION_1_1:				      memcpy(args, &Kaffe_JavaVMInitArgs, sizeof(Kaffe_JavaVMInitArgs));				      vm_args->version = JNI_VERSION_1_1;				      break;				    case JNI_VERSION_1_4:				    case JNI_VERSION_1_2:				      vm_args->ignoreUnrecognized = JNI_FALSE;				      vm_args->options = NULL;				      vm_args->nOptions = 0;				      break;				    default:				      return -1;				  }				  				  return 0;				}								static char *				concatString(const char *s1, const char *s2)				{				  char *s;								  assert(s1 != NULL || s2 != NULL);								  if (s1 == NULL)				    s1 = "";				  if (s2 == NULL)				    s2 = "";				  				  s = (char *)malloc(strlen(s1) + strlen(s2) + 1);								  return strcat(strcpy(s, s1), s2);				}								static				size_t				parseSize(char* arg)				{					size_t sz;					char* narg;									sz = strtol(arg, &narg, 0);					switch (narg[0]) {					case 'b': case 'B':						break;									case 'k': case 'K':						sz *= 1024;						break;									case 'm': case 'M':						sz *= 1024 * 1024;						break;					default:						break;					}									return (sz);				}								/**				 * Parse a property set by the user. 				 * Users can set properties with the -D switch. 				 * 				 * This function modifies the global variable userProperties.				 *				 * @param opt the option string to parse				 */ 				static 				void				KaffeJNI_ParseUserProperty(char * opt)				{				  userProperty *prop; 				  unsigned int sz;				  char *internalOpt;								  /* Allocate a new property. */				  prop = (userProperty *)malloc(sizeof(userProperty)); 				  assert (prop != NULL);								  /* Skip '-D' in the option string. */				  internalOpt = strdup(&opt[2]);								  /* Insert new property at head of the user properties list. */				  prop->next = userProperties;				  userProperties = prop;								  /* Search for '=' to find out whether the property is				   * assigned a value.				   */				  for (sz = 0; internalOpt[sz] != 0; sz++)				    {				      if (internalOpt[sz] == '=')					{					  /* Split the property string into property 					   * name and value.					   */					  internalOpt[sz] = '\0';					  sz++;					  break;					}				    }								  /* Initialize new property with name and value. */				  prop->key = internalOpt;				  prop->value = &internalOpt[sz];				}								static jint				KaffeJNI_ParseArgs(KaffeVM_Arguments *args, JavaVMOption *options, jint nOptions)				{				  int i;				  char *classpath = NULL;				  char *bootClasspath = NULL;  				  size_t sz;								  for (i = 0; i < nOptions; i++)				    {				      char *opt = options[i].optionString;								      if (!strcmp(opt, "vfprintf"))					args->jni_vfprintf = (jint (*)(FILE*,const char *,va_list))options[i].extraInfo;				      else if (!strcmp(opt, "exit"))					args->exit = (void (*)(jint))options[i].extraInfo;				      else if (!strcmp(opt, "abort"))					args->abort = (void (*)(void))options[i].extraInfo;				      else if (!strncmp(opt, "-verbose:", 9))					{					  opt += 9;					  if (!strcmp(opt, "gc"))					    args->enableVerboseGC = 1;					  else if (!strcmp(opt, "class"))					    args->enableVerboseClassloading = 1;					  else if (!strcmp(opt, "jit"))					    args->enableVerboseJIT = 1;					  else if (!strcmp(opt, "call"))					    args->enableVerboseCall = 1;					}				      else if (!strcmp(opt, "-verify"))					args->verifyMode = 3;				      else if (!strcmp(opt, "-verifyremote"))					args->verifyMode = 2;				      else if (!strcmp(opt, "-noverify"))					args->verifyMode = 0;				      else if (!strncmp(opt, "-D", 2))					{					  KaffeJNI_ParseUserProperty(opt);					}				      else if (!strncmp(opt, "-Xbootclasspath:", 16))				        {					  bootClasspath = strdup(opt + 16);				        }				      else if (!strncmp(opt, "-Xbootclasspath/a:", 18))					{					  char *newBootPath = concatString(bootClasspath, 									   concatString(":", opt + 18));					  					  if (bootClasspath != NULL)					    free(bootClasspath);									  bootClasspath = newBootPath;					}				      else if (!strncmp(opt, "-Xbootclasspath/p:", 18))					{					  char *newBootPath = concatString(opt + 18, 									   concatString(":", bootClasspath));					  					  if (bootClasspath != NULL)					    free(bootClasspath);									  bootClasspath = newBootPath;					}				      else if (!strncmp(opt, "-Xclasspath:", 12))				        {					  classpath = strdup(opt + 12);				        }				      else if (!strncmp(opt, "-Xclasspath/a:", 14))					{					  char *newPath = concatString(classpath, 								       concatString(":", opt + 14));					  					  if (classpath != NULL)					    free(classpath);									  classpath = newPath;					}				      else if (!strncmp(opt, "-Xclasspath/p:", 14))					{					  char *newPath = concatString(opt + 14, 								       concatString(":", classpath));					  					  if (classpath != NULL)					    free(classpath);									  classpath = newPath;					}				      else if (!strncmp(opt, "-Xvmdebug:", 10))					{					  if (!dbgSetMaskStr(&opt[10]))					    return 0;					}				      else if (!strncmp(opt, "-Xss:", 5))				        {					  sz = parseSize(&opt[5]);					  if (sz < THREADSTACKSIZE)					    {					      fprintf(stderr,  "Warning: Attempt to set stack size smaller than %d - ignored.\n", THREADSTACKSIZE);					    }					  else					    {					      args->nativeStackSize = sz;					    }					  DBG(INIT,					    dprintf("Setup stack size to %zd\n", sz);					  );					}				    }				  args->bootClasspath = bootClasspath;				  args->classpath = classpath;								  return 1;				}								static char *				KaffeJNI_getSystemProperty(const char *key)				{				  jvalue retval;				  Hjava_lang_String *key_string = stringC2Java(key);				  				  do_execute_java_class_method(&retval, "gnu/classpath/SystemProperties", NULL, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;", key_string);				  if (retval.l == NULL)				    return NULL;								  return stringJava2C(retval.l);				}								#if defined(ENABLE_JVMPI)								static void				detectAllActiveThreads(jthread_t jtid, void *param UNUSED)				{				  JVMPI_Event ev;				  Hjava_lang_VMThread *tid;								  tid = (Hjava_lang_VMThread *)(KTHREAD(get_data)(jtid)->jlThread);								  jvmpiFillThreadStart(&ev, tid);				  jvmpiPostEvent(&ev);				  jvmpiCleanupThreadStart(&ev);				}								#endif /* defined(ENABLE_JVMPI) */								static void KaffeJNI_addEndorsedDirs()				{				  char *endorsed = KaffeJNI_getSystemProperty("java.endorsed.dirs");				  char *sep;				  char *save_endorsed = endorsed;								  if (endorsed == NULL)				    return;								  while ((sep = strstr(endorsed, path_separator)) != NULL)				    {				      *sep = 0;				      KaffeVM_prependClasspath(endorsed);				      endorsed = sep+1;				    }								  gc_free(save_endorsed);				}								jint				JNI_CreateJavaVM(JavaVM** vm, void** penv, void* args)				{				  JavaVMInitArgs *vm_args = (JavaVMInitArgs *)args;				  JNIEnv **env = (JNIEnv **)penv;								  switch (vm_args->version)				    {				    case JNI_VERSION_1_1:				      memcpy(&Kaffe_JavaVMArgs, args, sizeof(Kaffe_JavaVMArgs));				      break;				    case JNI_VERSION_1_4:				    case JNI_VERSION_1_2:				      memcpy(&Kaffe_JavaVMArgs, &Kaffe_JavaVMInitArgs, sizeof(Kaffe_JavaVMArgs));				      if (!KaffeJNI_ParseArgs(&Kaffe_JavaVMArgs, vm_args->options, vm_args->nOptions))					return -1;				      break;				    default:				      return -1;				    }								  /* We can only init. one KVM */				  if (Kaffe_NumVM != 0) {				    return -1;				  }								  /* Setup the machine */				  initialiseKaffe();								  KaffeJNI_addEndorsedDirs();								  /* Return the VM and JNI we're using */				  *vm = KaffeJNI_GetKaffeVM();				  *env = THREAD_JNIENV();				  startingThread = KTHREAD(current)();				  Kaffe_NumVM++;								#if defined(ENABLE_JVMPI)				  if (Kaffe_JavaVMArgs.profilerLibname != NULL)				    {				      char errbuf[256];				      jint (*onloadProfiler)(JavaVM *jvm, const char *options, void *reserved);								      if (loadNativeLibrary(Kaffe_JavaVMArgs.profilerLibname, NULL, errbuf, sizeof(errbuf)) < 0)					{					  fprintf(stderr,						  "Unable to load %s: %s\n",						  Kaffe_JavaVMArgs.profilerLibname,						  errbuf);					  exit(1);					}				      				      onloadProfiler = (jint (*)(JavaVM *jvm, const char *options, void *reserved))loadNativeLibrarySym("JVM_OnLoad");				      if (onloadProfiler != NULL && onloadProfiler (*vm, Kaffe_JavaVMArgs.profilerArguments, NULL) < 0)					exit(1);				    }				  				  if( JVMPI_EVENT_ISENABLED(JVMPI_EVENT_JVM_INIT_DONE) )				    {				      JVMPI_Event ev;								      ev.event_type = JVMPI_EVENT_JVM_INIT_DONE;				      jvmpiPostEvent(&ev);				    }								 				  if ( JVMPI_EVENT_ISENABLED(JVMPI_EVENT_THREAD_START) )				    {				      KTHREAD(suspendall)();				      				      KTHREAD(walkLiveThreads) (detectAllActiveThreads, NULL);								      KTHREAD(unsuspendall)();				    } 				#endif								  return 0;				}								jint				KaffeJNI_DestroyJavaVM(JavaVM* vm UNUSED)				{				  /* The destroy function must be called by the same thread that has				   * built the VM object				   */				#if defined(ENABLE_JVMPI)				  if ( JVMPI_EVENT_ISENABLED(JVMPI_EVENT_JVM_SHUT_DOWN) )				    {				      JVMPI_Event ev;								      ev.event_type = JVMPI_EVENT_JVM_SHUT_DOWN;				      jvmpiPostEvent(&ev);				    }				#endif								  if (KTHREAD(current)() != startingThread)				    return -1;								  exitThread();				  return 0;				}								jint				JNI_GetCreatedJavaVMs(JavaVM** vm, jsize buflen UNUSED, jsize* nvm)				{				  vm[0] = KaffeJNI_GetKaffeVM();				  *nvm = Kaffe_NumVM;								  return (0);				}							

相关资源