/** * Adds JVM to the list unless it's already there. If JVM is not added to * the list, it gets deallocated. */ STATIC Bool JVM_Add(JVMSet * jvms, JVM * jvm) { if (jvm) { int pos = VECTOR_IndexOf(&jvms->found, jvm); if (pos < 0) { return VECTOR_TryAdd(&jvms->found, jvm); } else { /* if the new JVM has better flags, replace the old one */ Bool replace = False; JVM * jvm2 = VECTOR_Get(&jvms->found, pos); if (!(jvm2->flags & JVM_FLAG_SPECIAL) && (jvm->flags & JVM_FLAG_SPECIAL)) { /* copy version information from the existing JRE */ Char * tmp = jvm->versionString; jvm->version = jvm2->version; jvm->nVersionDigits = jvm2->nVersionDigits; jvm->versionString = jvm2->versionString; jvm2->versionString = tmp; replace = True; } else if ((jvm2->flags & JVM_FLAG_JDK) && !(jvm->flags & JVM_FLAG_JDK)) { /* we prefer JRE over JDK */ replace = True; } else if (!(jvm2->flags & JVM_FLAG_DEFAULT) && (jvm->flags & JVM_FLAG_DEFAULT)) { /* new JVM is the default one */ replace = True; } if (replace) { if (jvm2->nVersionDigits > jvm->nVersionDigits) { /* existing JVM has more detailed version information */ Char * tmp = jvm->versionString; jvm->version = jvm2->version; jvm->nVersionDigits = jvm2->nVersionDigits; jvm->versionString = jvm2->versionString; jvm2->versionString = tmp; } TRACE1("JNILIB: duplicate JVM %s\n",jvm->versionString); VECTOR_Set(&jvms->found, pos, jvm); return True; } else { if (jvm->nVersionDigits > jvm2->nVersionDigits) { /* new JVM has more detailed version information */ Char * tmp = jvm2->versionString; jvm2->version = jvm->version; jvm2->nVersionDigits = jvm->nVersionDigits; jvm2->versionString = jvm->versionString; jvm->versionString = tmp; } TRACE1("JNILIB: duplicate JVM %s\n",jvm2->versionString); JVM_Free(jvm); } } } return False; }
/** * Creates JVM context given the JRE home dir. We assume that the parameter * points to existing directory. Note that in this case we don't know the * version of JRE. We could figure it out by reading the manifest from rt.jar * but that might take considerable amount of time. A typical size of rt.jar * is over 25MB. Instead, we assume that if the caller has given us a path * to its own JRE installation, then this is the preferred version of JRE. */ STATIC JVM * JVM_CreateDirContext(Str home) { JVM * jvm = MEM_New(JVM); if (jvm) { memset(jvm, 0, sizeof(*jvm)); jvm->versionString = STRING_Dup("UNKNOWN"); jvm->javaHome = STRING_Dup(home); if (jvm->versionString && jvm->javaHome) { char s[MAX_PATH]; /* Normalize the Java home path */ Char* p; int len = StrLen(jvm->javaHome); for (p=StrChr(jvm->javaHome,'/'); p; p=strchr(p,'/')) *p = '\\'; while (len > 0 && jvm->javaHome[len-1] == '\\') { jvm->javaHome[--len] = 0; } /* find jvm.dll */ snprintf(s,COUNT(s),"%s\\%s",jvm->javaHome,JVM_DLL_1); s[COUNT(s)-1] = 0; if (FILE_IsFile(s)) { jvm->javaLib = STRING_Dup(s); if (jvm->javaLib) { TRACE1("JNILIB: Java runtime lib: %s\n",s); return jvm; } } else { TRACE1("JNILIB: no such file: %s\n",s); snprintf(s,COUNT(s),"%s\\%s",jvm->javaHome,JVM_DLL_2); s[COUNT(s)-1] = 0; if (FILE_IsFile(s)) { jvm->javaLib = STRING_Dup(s); if (jvm->javaLib) { TRACE1("JNILIB: Java runtime lib: %s\n",s); return jvm; } } else { TRACE1("JNILIB: no such file: %s\n",s); } } } JVM_Free(jvm); } return NULL; }
/** * @internal * * FUNCTION: jvmEndMemory() * TYPE: private operation * OVERVIEW: Finalize the JVM memory pool * INTERFACE: * parameters: count address to store memory leak count * size address to store totol bytes of memory leaked * returns: the number of memory leaks detected * */ int jvmEndMemory(int* count, int* size) { _JvmMemHdrPtr jvmMemoryHdr; char* jvmMemoryPtr; *count = 0; *size = 0; for (jvmMemoryPtr = JvmMemoryStart; jvmMemoryPtr < JvmMemoryEnd; jvmMemoryPtr += jvmMemoryHdr->size + sizeof(_JvmMemHdr)) { jvmMemoryHdr = (_JvmMemHdrPtr)jvmMemoryPtr; if (jvmMemoryHdr->magic != MAGIC) { tty->print_cr( "ERROR: memory corruption at 0x%p", jvmMemoryPtr); return -1; } else if (jvmMemoryHdr->free != 1) { #ifdef REPORT_LEVEL #if REPORT_LEVEL <= LOG_WARNING reportToLog(LOG_WARNING, LC_MALLOC, "WARNING: memory leak: size= %d address= 0x%p", jvmMemoryHdr->size, (void*)((char*)jvmMemoryHdr + sizeof(_JvmMemHdr))); printAllocation(LOG_WARNING, "allocated", jvmMemoryHdr->filename, jvmMemoryHdr->lineno); #endif #endif JVM_Free((void*)((char*)jvmMemoryHdr + sizeof(_JvmMemHdr))); *count += 1; *size += jvmMemoryHdr->size; } } return *count; }
/** * Creates JVM context given the JRE or JDK registry key. */ STATIC JVM * JVM_CreateRegContext(HKEY hJavaKey, Str szVersion, Bool isJdk) { int n; JavaVersion version; if (JVM_ParseVersion2(szVersion,&version,&n)) { JVM * jvm = MEM_New(JVM); if (jvm) { memset(jvm, 0, sizeof(*jvm)); if (isJdk) jvm->flags |= JVM_FLAG_JDK; jvm->version = version; jvm->versionString = STRING_Dup(szVersion); jvm->nVersionDigits = n; if (jvm->versionString) { if (JVM_Check(hJavaKey, jvm)) { return jvm; } } JVM_Free(jvm); } } else { TRACE1("JNILIB: unparsable Java version: %s\n",szVersion); } return NULL; }
/** * Free routine for the vector containing JVM structures */ STATIC void JVM_VectorFree(VElement elem) { JVM_Free(elem); }