|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: This class is meant for starting the J9 JVM. |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <string> |
|
19 #include <fstream> |
|
20 |
|
21 |
|
22 #include "j9starters60.h" |
|
23 |
|
24 #include "jvmargsmodifier.h" |
|
25 |
|
26 #include "logger.h" |
|
27 #include "javaoslayer.h" |
|
28 #include "dynamiclibloader.h" |
|
29 #include "javacommonutils.h" |
|
30 |
|
31 using namespace java::runtime; |
|
32 using namespace java::util; |
|
33 |
|
34 extern const wchar_t CLASS_PATH_SEPARATOR = L';'; |
|
35 extern const char PATH_SEPARATOR_FROM = '/'; |
|
36 extern const char PATH_SEPARATOR_TO = '\\'; |
|
37 |
|
38 const wchar_t* const ODC_PROPERTY = L"-Dcom.ibm.j9.ext.odcs="; |
|
39 |
|
40 |
|
41 EXPORT_C JvmStarter* |
|
42 JvmStarter::getJvmStarterInstance(const Configuration configuration, |
|
43 const std::wstring& indetifier) |
|
44 { |
|
45 JELOG2(EJavaRuntime); |
|
46 return new J9StarterS60(configuration, indetifier); |
|
47 } |
|
48 |
|
49 EXPORT_C JvmStarter* |
|
50 JvmStarter::getJvmStarterInstance() |
|
51 { |
|
52 JELOG2(EJavaRuntime); |
|
53 return new J9StarterS60(); |
|
54 } |
|
55 |
|
56 J9StarterS60::J9StarterS60() |
|
57 #ifdef __WINSCW__ |
|
58 : |
|
59 mVariant(0) |
|
60 #endif // __WINSCW__ |
|
61 { |
|
62 JELOG2(EJavaRuntime); |
|
63 } |
|
64 |
|
65 J9StarterS60::J9StarterS60(const Configuration configuration, |
|
66 const std::wstring& indetifier) |
|
67 #ifdef __WINSCW__ |
|
68 : |
|
69 mVariant(0) |
|
70 #endif // __WINSCW__ |
|
71 { |
|
72 JELOG2(EJavaRuntime); |
|
73 mConfiguration = configuration; |
|
74 mIdentifier = indetifier; |
|
75 setDefaultArguments(); |
|
76 } |
|
77 |
|
78 |
|
79 J9StarterS60::~J9StarterS60() |
|
80 { |
|
81 JELOG2(EJavaRuntime); |
|
82 #ifdef __WINSCW__ |
|
83 delete mVariant; |
|
84 mVariant = 0; |
|
85 mLibLoader.Close(); |
|
86 #endif // __WINSCW__ |
|
87 } |
|
88 |
|
89 void J9StarterS60::setDefaultArguments() |
|
90 { |
|
91 if (mConfiguration == CLDC) |
|
92 { |
|
93 mJvmArgs.push_back(L"-jcl:cldc11:nokiaextcldc"); |
|
94 mJvmArgs.push_back(L"-Xfuture:cldc"); |
|
95 mJvmArgs.push_back(L"-Dcom.nokia.jvm.port=j9.JvmPortCldc"); |
|
96 } |
|
97 else if (mConfiguration == CDC) |
|
98 { |
|
99 mJvmArgs.push_back(L"-jcl:cdc11:nokiaextcdc"); |
|
100 mJvmArgs.push_back(L"-Dcom.nokia.jvm.port=j9.JvmPortCdc"); |
|
101 } |
|
102 else if (mConfiguration == FOUNDATION) |
|
103 { |
|
104 mJvmArgs.push_front(L"-jcl:foun11:nokiaextcdc"); |
|
105 mJvmArgs.push_front(L"-Dcom.nokia.jvm.port=j9.JvmPortFoun"); |
|
106 } |
|
107 #ifdef RD_JAVA_UI_QT |
|
108 mJvmArgs.push_back(L"-Xmso80K"); // Native thread stack size. |
|
109 mJvmArgs.push_back(L"-Dcom.nokia.mj.impl.rt.ui=" |
|
110 L"com.nokia.mj.impl.rt.ui.qt.RuntimeUiQt"); |
|
111 #else // RD_JAVA_UI_QT |
|
112 mJvmArgs.push_back(L"-Xmso16k"); // Native thread stack size. |
|
113 mJvmArgs.push_back(L"-Dcom.nokia.mj.impl.rt.ui=" |
|
114 L"com.nokia.mj.impl.rt.ui.avkon.RuntimeUiAvkon"); |
|
115 mJvmArgs.push_back(L"-Dcom.nokia.coreui=coreuiavkon"); |
|
116 #endif // RD_JAVA_UI_QT |
|
117 |
|
118 mJvmArgs.push_back(L"-Dfile.encoding=ISO-8859-1"); |
|
119 mJvmArgs.push_back(L"-Dmicroedition.connection.pkgs=" |
|
120 L"com.nokia.mj.impl.gcf.protocol"); |
|
121 mJvmArgs.push_back(L"-Dmicroedition.encoding=ISO-8859-1"); |
|
122 mJvmArgs.push_back(L"-Xgc:finInc=32,compactMaxRelocationEntries=4096," |
|
123 L"finalizeMasterPriority=10,finalizeSlavePriority=10"); |
|
124 mJvmArgs.push_back(L"-Xiss1K"); // Initial java thread stack size. |
|
125 mJvmArgs.push_back(L"-Xits8K"); // Buffer for class/method/field names |
|
126 // & signatures. |
|
127 mJvmArgs.push_back(L"-Xminf0.1"); // Min percentage of heap free after GC. |
|
128 mJvmArgs.push_back(L"-Xmaxf0.3"); // Max percentage of heap free after GC. |
|
129 mJvmArgs.push_back(L"-Xmine16K"); // Minimum size for heap expansion. |
|
130 mJvmArgs.push_back(L"-Xmns64K"); // Initial new space size. Keep this in sync with MemoryLogger.java |
|
131 mJvmArgs.push_back(L"-Xmos64K"); // Initial old space size. Keep this in sync with MemoryLogger.java |
|
132 mJvmArgs.push_back(L"-Xmox16M"); // Maximum old space size. |
|
133 mJvmArgs.push_back(L"-Xmx16M"); // Memory maximum. |
|
134 mJvmArgs.push_back(L"-Xmco16k"); // ROM class segment increment. |
|
135 mJvmArgs.push_back(L"-Xmr1k"); // Remembered set size. |
|
136 |
|
137 // Set the java home to point either to c:\\resource\\java\\jvm or |
|
138 // z:\\resource\\java\\jvm. Default is z drive if the dir doesn't |
|
139 // exist on the c drive |
|
140 std::wstring javaHome = L"-Djava.home="; |
|
141 struct stat fileStat; |
|
142 int err = lstat("c:\\resource\\java\\jvm\\bin", &fileStat); |
|
143 if (err == 0) |
|
144 { |
|
145 javaHome += L"c"; |
|
146 } |
|
147 else |
|
148 { |
|
149 javaHome += L"z"; |
|
150 } |
|
151 javaHome += L":\\resource\\java\\jvm"; |
|
152 |
|
153 mJvmArgs.push_back(javaHome.c_str()); |
|
154 |
|
155 // Not using extension dir to list platform odc files. |
|
156 setInternalOdcFiles(); |
|
157 |
|
158 } |
|
159 void J9StarterS60::overrideOldHeapSize(int heapSize) |
|
160 { |
|
161 JELOG2(EJavaRuntime); |
|
162 std::wstring oldSpace = L"-Xmos"; |
|
163 oldSpace += JavaCommonUtils::intToWstring(heapSize); |
|
164 oldSpace += L"K"; |
|
165 mJvmArgs.push_back(oldSpace); |
|
166 } |
|
167 |
|
168 void J9StarterS60::overrideNewHeapSize(int heapSize) |
|
169 { |
|
170 JELOG2(EJavaRuntime); |
|
171 std::wstring newSpace = L"-Xmns"; |
|
172 newSpace += JavaCommonUtils::intToWstring(heapSize); |
|
173 newSpace += L"K"; |
|
174 mJvmArgs.push_back(newSpace); |
|
175 } |
|
176 |
|
177 void J9StarterS60::overrideNativeStackSize(int stackSize) |
|
178 { |
|
179 JELOG2(EJavaRuntime); |
|
180 std::wstring stackSizeStr = L"-Xmso"; |
|
181 stackSizeStr += JavaCommonUtils::intToWstring(stackSize); |
|
182 stackSizeStr += L"K"; |
|
183 mJvmArgs.push_back(stackSizeStr); |
|
184 } |
|
185 |
|
186 void J9StarterS60::overrideJavaStackSize(int stackSize) |
|
187 { |
|
188 JELOG2(EJavaRuntime); |
|
189 std::wstring stackSizeStr = L"-Xiss"; |
|
190 stackSizeStr += JavaCommonUtils::intToWstring(stackSize); |
|
191 stackSizeStr += L"K"; |
|
192 mJvmArgs.push_back(stackSizeStr); |
|
193 } |
|
194 |
|
195 // #define RD_JAVA_VM_EXT_ODC_FEATURE_IN_USE |
|
196 void J9StarterS60::setInternalOdcFiles() |
|
197 { |
|
198 JELOG2(EJavaRuntime); |
|
199 |
|
200 int pathType = BOOT_CLASSPATH_MIDP; |
|
201 if (mIdentifier == L"Installer") |
|
202 { |
|
203 pathType = BOOT_CLASSPATH_INSTALLER; |
|
204 } |
|
205 else if (mIdentifier == L"TCK_runner") |
|
206 { |
|
207 pathType = BOOT_CLASSPATH_TCKRUNNER; |
|
208 } |
|
209 |
|
210 std::list<std::wstring> odcFiles; |
|
211 std::list<std::wstring> bcpEntities; |
|
212 JavaOsLayer::bootClassPath(odcFiles, bcpEntities, pathType); |
|
213 |
|
214 // Collect all the odc files into a comma separated list. |
|
215 for (std::list<std::wstring>::const_iterator iter = odcFiles.begin(); |
|
216 iter != odcFiles.end(); |
|
217 ++iter) |
|
218 { |
|
219 appendOdcFile(*iter); |
|
220 } |
|
221 |
|
222 // Add the rest of the files into bootclasspath. |
|
223 for (std::list<std::wstring>::const_iterator iter = bcpEntities.begin(); |
|
224 iter != bcpEntities.end(); |
|
225 ++iter) |
|
226 { |
|
227 appendBootClassPath(*iter); |
|
228 } |
|
229 } |
|
230 |
|
231 void J9StarterS60::appendOdcFile(const std::wstring& odcFile) |
|
232 { |
|
233 JELOG2(EJavaRuntime); |
|
234 if (mOdcExtDirProperty.length() == 0) |
|
235 { |
|
236 mOdcExtDirProperty = ODC_PROPERTY; |
|
237 } |
|
238 else |
|
239 { |
|
240 mOdcExtDirProperty.append(L","); |
|
241 } |
|
242 mOdcExtDirProperty.append(odcFile); |
|
243 } |
|
244 |
|
245 #ifdef __WINSCW__ |
|
246 void J9StarterS60::getJ9VariantL() |
|
247 { |
|
248 // In emulator solve which variant should be loaded: |
|
249 // J9.dll, j9_2.dll or j9_3.dll. |
|
250 JELOG2(EJavaRuntime); |
|
251 _LIT(KJ9_1, "j9"); |
|
252 _LIT(KJ9_2, "j9_1"); |
|
253 |
|
254 // Do this only once. |
|
255 if (mVariant == 0) |
|
256 { |
|
257 mVariant = new std::string(); // codescanner::nonleavenew |
|
258 int st = mLibLoader.Load(KJ9_1); |
|
259 if (st != KErrNone) |
|
260 { |
|
261 LOG1(EJavaRuntime, EInfo, "Could not load j9.dll (err=%d)." |
|
262 " Trying j9_1.dll", st); |
|
263 // |
|
264 *mVariant = "_1"; |
|
265 st = mLibLoader.Load(KJ9_2); |
|
266 if (st != KErrNone) |
|
267 { |
|
268 LOG1(EJavaRuntime, EInfo, "Could not load j9_1.dll (err=%d)." |
|
269 " Trying j9_2.dll", st); |
|
270 // Variant 3 is the last one we got |
|
271 *mVariant = "_2"; |
|
272 } |
|
273 } |
|
274 } |
|
275 } |
|
276 #endif // __WINSCW__ |
|
277 |
|
278 |
|
279 |
|
280 |
|
281 typedef int (*J9mainFunc)(int argc, const char *argv[], char *envp[], |
|
282 TThreadId uiThreadId, TInt windowGroupId); |
|
283 |
|
284 int J9StarterS60::startJvm() |
|
285 { |
|
286 JELOG2(EJavaRuntime); |
|
287 #ifdef __WINSCW__ |
|
288 #ifdef _DEBUG |
|
289 // The VM has WSD. In order to be able to run more than one VM instances |
|
290 // in the emulator we might need to load j9_2 or j9_3 dll. |
|
291 TRAP_IGNORE(getJ9VariantL()); |
|
292 // Set the JNI checks for WINSCW DEBUG. |
|
293 std::wstring jnicheck(L"-Xrunjnichk"); |
|
294 if (*mVariant == "_1") |
|
295 { |
|
296 jnicheck += L"_1"; |
|
297 } |
|
298 else if (*mVariant == "_2") |
|
299 { |
|
300 jnicheck += L"_2"; |
|
301 } |
|
302 jnicheck += L":all,nonfatal,noadvice,nowarn"; |
|
303 mJvmArgs.push_back(jnicheck); |
|
304 #endif // _DEBUG |
|
305 #endif // __WINSCW__ |
|
306 |
|
307 |
|
308 // Set mJvmArgs container to contain all the JVM args and set mAppAndArgs |
|
309 // to contain the main class and the arguments. |
|
310 completeArgumentContainers(); |
|
311 |
|
312 // Give arguments to modifyJvmArguments for modification. Args |
|
313 // are modified if the default empty implementation has been overridden |
|
314 // by eclipsing the modifyJvmArguments dll. |
|
315 modifyJvmArguments(mIdentifier, mJvmArgs, mAppAndArgs); |
|
316 |
|
317 // Allocate space for the raw JVM args. |
|
318 int rawJvmArgumentCount = mJvmArgs.size() + mAppAndArgs.size() + 1; |
|
319 ScopedCharPointerArray rawJvmArgs(rawJvmArgumentCount); |
|
320 |
|
321 int ind = 0; |
|
322 |
|
323 // Just putting something to the first argument. Needs to dublicate so that |
|
324 // the deletion succeeds. |
|
325 rawJvmArgs.get()[ind++] = strdup("c:\\"); // codescanner::driveletters |
|
326 |
|
327 LOG(EJavaRuntime, EInfo, "VM args:"); |
|
328 LOG1(EJavaRuntime, EInfo, " %s",rawJvmArgs.get()[ind-1]); |
|
329 |
|
330 // Adding the JVM args. |
|
331 for (JvmArgs_t::iterator jvmArgsIter = mJvmArgs.begin(); |
|
332 jvmArgsIter!= mJvmArgs.end(); |
|
333 ++jvmArgsIter) |
|
334 { |
|
335 rawJvmArgs.get()[ind++] = JavaCommonUtils::wstringToUtf8(*jvmArgsIter); |
|
336 LOG1(EJavaRuntime, EInfo, " %s",rawJvmArgs.get()[ind-1]); |
|
337 } |
|
338 |
|
339 // Adding the Application main class and its args. |
|
340 for (JvmArgs_t::iterator appAndArgsIter = mAppAndArgs.begin(); |
|
341 appAndArgsIter!= mAppAndArgs.end(); |
|
342 ++appAndArgsIter) |
|
343 { |
|
344 rawJvmArgs.get()[ind++] = JavaCommonUtils::wstringToUtf8(*appAndArgsIter); |
|
345 LOG1(EJavaRuntime, EInfo, " %s",rawJvmArgs.get()[ind-1]); |
|
346 } |
|
347 |
|
348 // Clear all the strings & lists. |
|
349 clear(); |
|
350 return startJvm(rawJvmArgumentCount, rawJvmArgs.get()); |
|
351 } |
|
352 |
|
353 int J9StarterS60::startJvm(int argc, char** argv) |
|
354 { |
|
355 JELOG2(EJavaRuntime); |
|
356 std::string j9DllName = "j9"; |
|
357 |
|
358 // The VM has WSD. In order to be able to run more than one VM instances |
|
359 // in the emulator we might need to load j9_2 or j9_3 dll. |
|
360 #ifdef __WINSCW__ |
|
361 TRAP_IGNORE(getJ9VariantL()); |
|
362 j9DllName += *mVariant; |
|
363 #endif // __WINSCW__ |
|
364 |
|
365 // Loading the main dll of the J9 VM. |
|
366 DynamicLibLoader jvmLibLoader(j9DllName.c_str(), false); |
|
367 |
|
368 // Looking for the method j9main. |
|
369 J9mainFunc j9main = (J9mainFunc)(jvmLibLoader.getFunction("j9main")); |
|
370 |
|
371 JavaOsLayer::startUpTrace("Starting VM()", -1, -1); |
|
372 LOG(EJavaRuntime, EInfo, "j9main()"); |
|
373 |
|
374 // Call j9main. |
|
375 int status = j9main(argc, (const char**)argv, 0, 0, 0); |
|
376 LOG1(EJavaRuntime, EInfo, "j9main() returned. st = %d", status); |
|
377 return status; |
|
378 } |
|
379 |
|
380 void J9StarterS60::enableThreadDumpL() |
|
381 { |
|
382 RLibrary debugLib; |
|
383 CleanupClosePushL(debugLib); |
|
384 // If the javathreaddumper.dll exists in the system, then a |
|
385 // thread dumper will be started. |
|
386 _LIT(KThreadDumpper, "javathreaddumper"); |
|
387 |
|
388 if (debugLib.Load(KThreadDumpper) == KErrNone) |
|
389 { |
|
390 mJvmArgs.push_back(L"-Xdump"); |
|
391 mJvmArgs.push_back(L"-Xrunjavathreaddumper"); |
|
392 } |
|
393 CleanupStack::PopAndDestroy(&debugLib); |
|
394 } |
|
395 |
|
396 void J9StarterS60::completeArgumentContainers() |
|
397 { |
|
398 JELOG2(EJavaRuntime); |
|
399 |
|
400 // Define Dump arguments. |
|
401 if (mTheadDumpEnabled) |
|
402 { |
|
403 TRAP_IGNORE(enableThreadDumpL()); |
|
404 } |
|
405 |
|
406 // Disable JIT, if requested. |
|
407 if (mJitDisabled) |
|
408 { |
|
409 mJvmArgs.push_back(L"-Xint"); |
|
410 } |
|
411 |
|
412 // Add the classpath. |
|
413 if (mClassPath.length() > 0) |
|
414 { |
|
415 mJvmArgs.push_front(mClassPath); |
|
416 mJvmArgs.push_front(L"-classpath"); |
|
417 } |
|
418 |
|
419 // Add the extension classpath. |
|
420 std::wstring ecp(L"-Dcom.ibm.j9.ext.dirs="); |
|
421 if (mExtensionPath.length() > 0) |
|
422 { |
|
423 ecp += mExtensionPath; |
|
424 } |
|
425 mJvmArgs.push_front(ecp); |
|
426 |
|
427 // Add the prepending boot classpath if set. |
|
428 if (mBootClassPathPrepend.length() > 0) |
|
429 { |
|
430 std::wstring bcpp(L"-Xbootclasspath/p:"); |
|
431 bcpp += mBootClassPathPrepend; |
|
432 mJvmArgs.push_front(bcpp); |
|
433 } |
|
434 |
|
435 // Add the appending boot classpath if set. |
|
436 if (mBootClassPathAppend.length() > 0) |
|
437 { |
|
438 std::wstring bcpa(L"-Xbootclasspath/a:"); |
|
439 bcpa += mBootClassPathAppend; |
|
440 mJvmArgs.push_front(bcpa); |
|
441 } |
|
442 |
|
443 // Add the defined odc files. |
|
444 if (mOdcExtDirProperty.length() > 0) |
|
445 { |
|
446 appendSystemProperty(mOdcExtDirProperty); |
|
447 } |
|
448 |
|
449 // Add the main class. |
|
450 mAppAndArgs.push_front(mMainClass); |
|
451 } |