javaruntimes/starterutils/src.s60/j9starters60.cpp
branchRCL_3
changeset 19 04becd199f91
child 23 98ccebc37403
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javaruntimes/starterutils/src.s60/j9starters60.cpp	Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,451 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  This class is meant for starting the J9 JVM.
+*
+*/
+
+#include <string>
+#include <fstream>
+
+
+#include "j9starters60.h"
+
+#include "jvmargsmodifier.h"
+
+#include "logger.h"
+#include "javaoslayer.h"
+#include "dynamiclibloader.h"
+#include "javacommonutils.h"
+
+using namespace java::runtime;
+using namespace java::util;
+
+extern const wchar_t CLASS_PATH_SEPARATOR = L';';
+extern const char PATH_SEPARATOR_FROM  = '/';
+extern const char PATH_SEPARATOR_TO    = '\\';
+
+const wchar_t* const ODC_PROPERTY = L"-Dcom.ibm.j9.ext.odcs=";
+
+
+EXPORT_C JvmStarter*
+JvmStarter::getJvmStarterInstance(const Configuration configuration,
+                                  const std::wstring& indetifier)
+{
+    JELOG2(EJavaRuntime);
+    return  new J9StarterS60(configuration, indetifier);
+}
+
+EXPORT_C JvmStarter*
+JvmStarter::getJvmStarterInstance()
+{
+    JELOG2(EJavaRuntime);
+    return new J9StarterS60();
+}
+
+J9StarterS60::J9StarterS60()
+#ifdef __WINSCW__
+        :
+        mVariant(0)
+#endif // __WINSCW__
+{
+    JELOG2(EJavaRuntime);
+}
+
+J9StarterS60::J9StarterS60(const Configuration configuration,
+                           const std::wstring& indetifier)
+#ifdef __WINSCW__
+        :
+        mVariant(0)
+#endif // __WINSCW__
+{
+    JELOG2(EJavaRuntime);
+    mConfiguration = configuration;
+    mIdentifier = indetifier;
+    setDefaultArguments();
+}
+
+
+J9StarterS60::~J9StarterS60()
+{
+    JELOG2(EJavaRuntime);
+#ifdef __WINSCW__
+    delete mVariant;
+    mVariant = 0;
+    mLibLoader.Close();
+#endif // __WINSCW__
+}
+
+void J9StarterS60::setDefaultArguments()
+{
+    if (mConfiguration == CLDC)
+    {
+        mJvmArgs.push_back(L"-jcl:cldc11:nokiaextcldc");
+        mJvmArgs.push_back(L"-Xfuture:cldc");
+        mJvmArgs.push_back(L"-Dcom.nokia.jvm.port=j9.JvmPortCldc");
+    }
+    else if (mConfiguration == CDC)
+    {
+        mJvmArgs.push_back(L"-jcl:cdc11:nokiaextcdc");
+        mJvmArgs.push_back(L"-Dcom.nokia.jvm.port=j9.JvmPortCdc");
+    }
+    else if (mConfiguration == FOUNDATION)
+    {
+        mJvmArgs.push_front(L"-jcl:foun11:nokiaextcdc");
+        mJvmArgs.push_front(L"-Dcom.nokia.jvm.port=j9.JvmPortFoun");
+    }
+#ifdef RD_JAVA_UI_QT
+    mJvmArgs.push_back(L"-Xmso80K"); // Native thread stack size.
+    mJvmArgs.push_back(L"-Dcom.nokia.mj.impl.rt.ui="
+                       L"com.nokia.mj.impl.rt.ui.qt.RuntimeUiQt");
+#else // RD_JAVA_UI_QT
+    mJvmArgs.push_back(L"-Xmso16k"); // Native thread stack size.
+    mJvmArgs.push_back(L"-Dcom.nokia.mj.impl.rt.ui="
+                       L"com.nokia.mj.impl.rt.ui.avkon.RuntimeUiAvkon");
+    mJvmArgs.push_back(L"-Dcom.nokia.coreui=coreuiavkon");
+#endif // RD_JAVA_UI_QT
+
+    mJvmArgs.push_back(L"-Dfile.encoding=ISO-8859-1");
+    mJvmArgs.push_back(L"-Dmicroedition.connection.pkgs="
+                       L"com.nokia.mj.impl.gcf.protocol");
+    mJvmArgs.push_back(L"-Dmicroedition.encoding=ISO-8859-1");
+    mJvmArgs.push_back(L"-Xgc:finInc=32,compactMaxRelocationEntries=4096,"
+                       L"finalizeMasterPriority=10,finalizeSlavePriority=10");
+    mJvmArgs.push_back(L"-Xiss1K");   // Initial java thread stack size.
+    mJvmArgs.push_back(L"-Xits8K");   // Buffer for class/method/field names
+    // & signatures.
+    mJvmArgs.push_back(L"-Xminf0.1"); // Min percentage of heap free after GC.
+    mJvmArgs.push_back(L"-Xmaxf0.3"); // Max percentage of heap free after GC.
+    mJvmArgs.push_back(L"-Xmine16K"); // Minimum size for heap expansion.
+    mJvmArgs.push_back(L"-Xmns64K");  // Initial new space size. Keep this in sync with MemoryLogger.java
+    mJvmArgs.push_back(L"-Xmos64K");  // Initial old space size. Keep this in sync with MemoryLogger.java
+    mJvmArgs.push_back(L"-Xmox16M");  // Maximum old space size.
+    mJvmArgs.push_back(L"-Xmx16M");   // Memory maximum.
+    mJvmArgs.push_back(L"-Xmco16k");  // ROM class segment increment.
+    mJvmArgs.push_back(L"-Xmr1k");    // Remembered set size.
+
+    // Set the java home to point either to c:\\resource\\java\\jvm or
+    // z:\\resource\\java\\jvm. Default is z drive if the dir doesn't
+    // exist on the c drive
+    std::wstring javaHome = L"-Djava.home=";
+    struct stat fileStat;
+    int err = lstat("c:\\resource\\java\\jvm\\bin", &fileStat);
+    if (err == 0)
+    {
+        javaHome += L"c";
+    }
+    else
+    {
+        javaHome += L"z";
+    }
+    javaHome += L":\\resource\\java\\jvm";
+
+    mJvmArgs.push_back(javaHome.c_str());
+
+    // Not using extension dir to list platform odc files.
+    setInternalOdcFiles();
+
+}
+void J9StarterS60::overrideOldHeapSize(int heapSize)
+{
+    JELOG2(EJavaRuntime);
+    std::wstring oldSpace = L"-Xmos";
+    oldSpace += JavaCommonUtils::intToWstring(heapSize);
+    oldSpace += L"K";
+    mJvmArgs.push_back(oldSpace);
+}
+
+void J9StarterS60::overrideNewHeapSize(int heapSize)
+{
+    JELOG2(EJavaRuntime);
+    std::wstring newSpace = L"-Xmns";
+    newSpace += JavaCommonUtils::intToWstring(heapSize);
+    newSpace += L"K";
+    mJvmArgs.push_back(newSpace);
+}
+
+void J9StarterS60::overrideNativeStackSize(int stackSize)
+{
+    JELOG2(EJavaRuntime);
+    std::wstring stackSizeStr = L"-Xmso";
+    stackSizeStr += JavaCommonUtils::intToWstring(stackSize);
+    stackSizeStr += L"K";
+    mJvmArgs.push_back(stackSizeStr);
+}
+
+void J9StarterS60::overrideJavaStackSize(int stackSize)
+{
+    JELOG2(EJavaRuntime);
+    std::wstring stackSizeStr = L"-Xiss";
+    stackSizeStr += JavaCommonUtils::intToWstring(stackSize);
+    stackSizeStr += L"K";
+    mJvmArgs.push_back(stackSizeStr);
+}
+
+// #define RD_JAVA_VM_EXT_ODC_FEATURE_IN_USE
+void J9StarterS60::setInternalOdcFiles()
+{
+    JELOG2(EJavaRuntime);
+
+    int pathType = BOOT_CLASSPATH_MIDP;
+    if (mIdentifier == L"Installer")
+    {
+        pathType = BOOT_CLASSPATH_INSTALLER;
+    }
+    else if (mIdentifier == L"TCK_runner")
+    {
+        pathType = BOOT_CLASSPATH_TCKRUNNER;
+    }
+
+    std::list<std::wstring> odcFiles;
+    std::list<std::wstring> bcpEntities;
+    JavaOsLayer::bootClassPath(odcFiles, bcpEntities, pathType);
+
+    // Collect all the odc files into a comma separated list.
+    for (std::list<std::wstring>::const_iterator iter = odcFiles.begin();
+            iter != odcFiles.end();
+            ++iter)
+    {
+        appendOdcFile(*iter);
+    }
+
+    // Add the rest of the files into bootclasspath.
+    for (std::list<std::wstring>::const_iterator iter = bcpEntities.begin();
+            iter != bcpEntities.end();
+            ++iter)
+    {
+        appendBootClassPath(*iter);
+    }
+}
+
+void J9StarterS60::appendOdcFile(const std::wstring& odcFile)
+{
+    JELOG2(EJavaRuntime);
+    if (mOdcExtDirProperty.length() == 0)
+    {
+        mOdcExtDirProperty = ODC_PROPERTY;
+    }
+    else
+    {
+        mOdcExtDirProperty.append(L",");
+    }
+    mOdcExtDirProperty.append(odcFile);
+}
+
+#ifdef __WINSCW__
+void J9StarterS60::getJ9VariantL()
+{
+    // In emulator solve which variant should be loaded:
+    // J9.dll, j9_2.dll or j9_3.dll.
+    JELOG2(EJavaRuntime);
+    _LIT(KJ9_1, "j9");
+    _LIT(KJ9_2, "j9_1");
+
+    // Do this only once.
+    if (mVariant == 0)
+    {
+        mVariant = new std::string(); // codescanner::nonleavenew
+        int st = mLibLoader.Load(KJ9_1);
+        if (st != KErrNone)
+        {
+            LOG1(EJavaRuntime, EInfo, "Could not load j9.dll (err=%d)."
+                 " Trying j9_1.dll", st);
+            //
+            *mVariant = "_1";
+            st = mLibLoader.Load(KJ9_2);
+            if (st != KErrNone)
+            {
+                LOG1(EJavaRuntime, EInfo, "Could not load j9_1.dll (err=%d)."
+                     " Trying j9_2.dll", st);
+                // Variant 3 is the last one we got
+                *mVariant = "_2";
+            }
+        }
+    }
+}
+#endif // __WINSCW__
+
+
+
+
+typedef int (*J9mainFunc)(int argc, const char *argv[], char *envp[],
+                          TThreadId uiThreadId, TInt windowGroupId);
+
+int J9StarterS60::startJvm()
+{
+    JELOG2(EJavaRuntime);
+#ifdef __WINSCW__
+#ifdef _DEBUG
+    // The VM has WSD. In order to be able to run more than one VM instances
+    // in the emulator we might need to load j9_2 or j9_3 dll.
+    TRAP_IGNORE(getJ9VariantL());
+    // Set the JNI checks for WINSCW DEBUG.
+    std::wstring jnicheck(L"-Xrunjnichk");
+    if (*mVariant == "_1")
+    {
+        jnicheck += L"_1";
+    }
+    else if (*mVariant == "_2")
+    {
+        jnicheck += L"_2";
+    }
+    jnicheck += L":all,nonfatal,noadvice,nowarn";
+    mJvmArgs.push_back(jnicheck);
+#endif // _DEBUG
+#endif // __WINSCW__
+
+
+    // Set mJvmArgs container to contain all the JVM args and set mAppAndArgs
+    // to contain the main class and the arguments.
+    completeArgumentContainers();
+
+    // Give arguments to modifyJvmArguments for modification. Args
+    // are modified if the default empty implementation has been overridden
+    // by eclipsing the modifyJvmArguments dll.
+    modifyJvmArguments(mIdentifier, mJvmArgs, mAppAndArgs);
+
+    // Allocate space for the raw JVM args.
+    int rawJvmArgumentCount = mJvmArgs.size() + mAppAndArgs.size() + 1;
+    ScopedCharPointerArray rawJvmArgs(rawJvmArgumentCount);
+
+    int ind = 0;
+
+    // Just putting something to the first argument. Needs to dublicate so that
+    // the deletion succeeds.
+    rawJvmArgs.get()[ind++] = strdup("c:\\");  // codescanner::driveletters
+
+    LOG(EJavaRuntime, EInfo, "VM args:");
+    LOG1(EJavaRuntime, EInfo, " %s",rawJvmArgs.get()[ind-1]);
+
+    // Adding the JVM args.
+    for (JvmArgs_t::iterator jvmArgsIter = mJvmArgs.begin();
+            jvmArgsIter!= mJvmArgs.end();
+            ++jvmArgsIter)
+    {
+        rawJvmArgs.get()[ind++] = JavaCommonUtils::wstringToUtf8(*jvmArgsIter);
+        LOG1(EJavaRuntime, EInfo, " %s",rawJvmArgs.get()[ind-1]);
+    }
+
+    // Adding the Application main class and its args.
+    for (JvmArgs_t::iterator appAndArgsIter = mAppAndArgs.begin();
+            appAndArgsIter!= mAppAndArgs.end();
+            ++appAndArgsIter)
+    {
+        rawJvmArgs.get()[ind++] = JavaCommonUtils::wstringToUtf8(*appAndArgsIter);
+        LOG1(EJavaRuntime, EInfo, " %s",rawJvmArgs.get()[ind-1]);
+    }
+
+    // Clear all the strings & lists.
+    clear();
+    return startJvm(rawJvmArgumentCount, rawJvmArgs.get());
+}
+
+int J9StarterS60::startJvm(int argc, char** argv)
+{
+    JELOG2(EJavaRuntime);
+    std::string j9DllName = "j9";
+
+    // The VM has WSD. In order to be able to run more than one VM instances
+    // in the emulator we might need to load j9_2 or j9_3 dll.
+#ifdef __WINSCW__
+    TRAP_IGNORE(getJ9VariantL());
+    j9DllName += *mVariant;
+#endif // __WINSCW__
+
+    // Loading the main dll of the J9 VM.
+    DynamicLibLoader jvmLibLoader(j9DllName.c_str(), false);
+
+    // Looking for the method j9main.
+    J9mainFunc j9main = (J9mainFunc)(jvmLibLoader.getFunction("j9main"));
+
+    JavaOsLayer::startUpTrace("Starting VM()", -1, -1);
+    LOG(EJavaRuntime, EInfo, "j9main()");
+
+    // Call j9main.
+    int status = j9main(argc, (const char**)argv, 0, 0, 0);
+    LOG1(EJavaRuntime, EInfo, "j9main() returned. st = %d", status);
+    return status;
+}
+
+void J9StarterS60::enableThreadDumpL()
+{
+    RLibrary debugLib;
+    CleanupClosePushL(debugLib);
+    // If the javathreaddumper.dll exists in the system, then a
+    // thread dumper will be started.
+    _LIT(KThreadDumpper, "javathreaddumper");
+
+    if (debugLib.Load(KThreadDumpper) == KErrNone)
+    {
+        mJvmArgs.push_back(L"-Xdump");
+        mJvmArgs.push_back(L"-Xrunjavathreaddumper");
+    }
+    CleanupStack::PopAndDestroy(&debugLib);
+}
+
+void J9StarterS60::completeArgumentContainers()
+{
+    JELOG2(EJavaRuntime);
+
+    // Define Dump arguments.
+    if (mTheadDumpEnabled)
+    {
+        TRAP_IGNORE(enableThreadDumpL());
+    }
+
+    // Disable JIT, if requested.
+    if (mJitDisabled)
+    {
+        mJvmArgs.push_back(L"-Xint");
+    }
+
+    // Add the classpath.
+    if (mClassPath.length() > 0)
+    {
+        mJvmArgs.push_front(mClassPath);
+        mJvmArgs.push_front(L"-classpath");
+    }
+
+    // Add the extension classpath.
+    std::wstring ecp(L"-Dcom.ibm.j9.ext.dirs=");
+    if (mExtensionPath.length() > 0)
+    {
+        ecp += mExtensionPath;
+    }
+    mJvmArgs.push_front(ecp);
+
+    // Add the prepending boot classpath if set.
+    if (mBootClassPathPrepend.length() > 0)
+    {
+        std::wstring bcpp(L"-Xbootclasspath/p:");
+        bcpp += mBootClassPathPrepend;
+        mJvmArgs.push_front(bcpp);
+    }
+
+    // Add the appending boot classpath if set.
+    if (mBootClassPathAppend.length() > 0)
+    {
+        std::wstring bcpa(L"-Xbootclasspath/a:");
+        bcpa += mBootClassPathAppend;
+        mJvmArgs.push_front(bcpa);
+    }
+
+    // Add the defined odc files.
+    if (mOdcExtDirProperty.length() > 0)
+    {
+        appendSystemProperty(mOdcExtDirProperty);
+    }
+
+    // Add the main class.
+    mAppAndArgs.push_front(mMainClass);
+}