// Load all resources
final Map<String, byte[]> resources = loadSystemResource(piRegistry);
/* Now create the processor */
final BaseVmArchitecture arch = getArchitecture();
final NativeStream os = createNativeStream();
clsMgr = new VmSystemClassLoader(null/*classesURL*/, arch,
new BuildObjectResolver(os, this));
blockedObjects.add(clsMgr);
blockedObjects.add(clsMgr.getSharedStatics());
blockedObjects.add(clsMgr.getSharedStatics().getTable());
blockedObjects.add(clsMgr.getIsolatedStatics());
blockedObjects.add(clsMgr.getIsolatedStatics().getTable());
blockedObjects.add(resources);
clsMgr.setSystemRtJar(resources);
// Initialize the statics table.
initializeStatics(clsMgr.getSharedStatics());
if (debug) {
log("Building in DEBUG mode", Project.MSG_WARN);
}
// Create the VM
final VmImpl vm = new VmImpl(version, arch, clsMgr.getSharedStatics(), debug, clsMgr, piRegistry);
blockedObjects.add(vm);
blockedObjects.add(VmUtils.getVm().getCompiledMethods());
final VmProcessor proc = createProcessor(vm, clsMgr.getSharedStatics(),
clsMgr.getIsolatedStatics());
log("Building for " + proc.getCPUID());
final Label clInitCaller = new Label("$$clInitCaller");
VmType<?> systemClasses[] = VmType.initializeForBootImage(clsMgr);
for (int i = 0; i < systemClasses.length; i++) {
clsMgr.addLoadedClass(systemClasses[i].getName(),
systemClasses[i]);
}
// First copy the native kernel file
if (enableJNasm) {
compileKernel(os, asmSourceInfo);
} else {
copyKernel(os);
}
os.setObjectRef(bootHeapStart);
// Setup a call to our first java method
initImageHeader(os, clInitCaller, vm, piRegistry);
// Create the initial stack
createInitialStack(os, initialStack, initialStackPtr);
/* Now load the classes */
loadClass(VmMethodCode.class);
loadClass(Unsafe.class);
loadClass(VmSystemClassLoader.class);
loadClass(VmType[].class);
loadClass(Vm.class);
loadClass(VirtualMemoryRegion.class).link();
vm.getHeapManager().loadClasses(clsMgr);
loadClass(VmHeapManager.class);
loadClass(VmSharedStatics.class);
loadClass(VmIsolatedStatics.class);
loadClass(VmUtils.getVm().getHeapManager().getClass());
loadClass(HeapHelper.class);
loadClass("org.jnode.vm.HeapHelperImpl");
loadClass(VmUtils.getVm().getCompiledMethods().getClass());
loadClass(VmCompiledCode[].class);
loadSystemClasses(resources.keySet());
/* Now emit the processor */
os.getObjectRef(proc);
/* Let the compilers load its native symbol offsets */
final NativeCodeCompiler[] cmps = arch.getCompilers();
for (int i = 0; i < cmps.length; i++) {
final NativeCodeCompiler cmp = cmps[i];
cmp.initialize(clsMgr);
os.getObjectRef(cmp);
}
/* Let the test compilers load its native symbol offsets */
final NativeCodeCompiler[] testCmps = arch.getTestCompilers();
if (testCmps != null) {
for (int i = 0; i < testCmps.length; i++) {
final NativeCodeCompiler cmp = testCmps[i];
cmp.initialize(clsMgr);
os.getObjectRef(cmp);
}
}
log("Compiling using " + cmps[0].getName() + " and "
+ cmps[cmps.length - 1].getName() + " compilers");
// Initialize the IMT compiler.
arch.getIMTCompiler().initialize(clsMgr);
// Load the jarfile as byte-array
// copyJarFile(blockedObjects, piRegistry);
// Now emit all object images to the actual image
emitObjects(os, arch, blockedObjects, false);
// Disallow the loading of new classes
clsMgr.setFailOnNewLoad(true);
emitObjects(os, arch, blockedObjects, false);
// Emit the vm
log("Emit vm", Project.MSG_VERBOSE);
blockedObjects.remove(vm);
emitObjects(os, arch, blockedObjects, false);
// Twice, this is intended!
emitObjects(os, arch, blockedObjects, false);
// Emit the compiled method list
log("Emit compiled methods", Project.MSG_VERBOSE);
blockedObjects.remove(VmUtils.getVm().getCompiledMethods());
final int compiledMethods = VmUtils.getVm().getCompiledMethods().size();
emitObjects(os, arch, blockedObjects, false);
// Twice, this is intended!
emitObjects(os, arch, blockedObjects, false);
/* Set the bootclasses */
log("prepare bootClassArray", Project.MSG_VERBOSE);
final VmType<?> bootClasses[] = clsMgr.prepareAfterBootstrap();
os.getObjectRef(bootClasses);
emitObjects(os, arch, blockedObjects, false);
// Twice, this is intended!
emitObjects(os, arch, blockedObjects, false);
// Emit the classmanager
log("Emit clsMgr", Project.MSG_VERBOSE);
// Turn auto-compilation on
clsMgr.setCompileRequired();
blockedObjects.remove(clsMgr);
emitObjects(os, arch, blockedObjects, false);
// Twice, this is intended!
emitObjects(os, arch, blockedObjects, false);
// Emit the statics table
log("Emit statics", Project.MSG_VERBOSE);
blockedObjects.remove(clsMgr.getSharedStatics());
blockedObjects.remove(clsMgr.getIsolatedStatics());
emitObjects(os, arch, blockedObjects, true);
// Twice, this is intended!
emitObjects(os, arch, blockedObjects, true);
// Emit the remaining objects
log("Emit rest; blocked=" + blockedObjects, Project.MSG_VERBOSE);
emitObjects(os, arch, null, true);
// Verify no methods have been compiled after we wrote the
// CompiledCodeList.
if (VmUtils.getVm().getCompiledMethods().size() != compiledMethods) {
throw new BuildException(
"Method have been compiled after CompiledCodeList was written.");
}
/* Write static initializer code */
emitStaticInitializerCalls(os, bootClasses, clInitCaller);
// This is the end of the image
X86BinaryAssembler.ObjectInfo dummyObjectAtEnd =
os.startObject(loadClass(VmMethodCode.class));
pageAlign(os);
dummyObjectAtEnd.markEnd();
os.setObjectRef(imageEnd);
os.setObjectRef(bootHeapEnd);
/* Link all native symbols */
linkNativeSymbols(os);
// Patch multiboot header
patchHeader(os);
// Store the image
storeImage(os);
// Generate the listfile
printLabels(os, bootClasses, clsMgr.getSharedStatics());
logLargeClasses(bootClasses);
// Generate debug info
for (int i = 0; i < cmps.length; i++) {
cmps[i].dumpStatistics();
}
final int bootHeapSize = os.getObjectRef(bootHeapEnd).getOffset()
- os.getObjectRef(bootHeapStart).getOffset();
final int bootHeapBitmapSize = (bootHeapSize / ObjectLayout.OBJECT_ALIGN) >> 3;
log("Boot heap size " + (bootHeapSize >>> 10) + "K bitmap size "
+ (bootHeapBitmapSize >>> 10) + "K");
log("Shared statics");
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
clsMgr.getSharedStatics().dumpStatistics(out);
log("Isolated statics");
clsMgr.getIsolatedStatics().dumpStatistics(out);
VmUtils.dumpStatistics(out);
logStatistics(os);
BytecodeParser.dumpStatistics();
log("Optimized methods : " + totalHighMethods + ", avg size "
+ (totalHighMethodSize / totalHighMethods) + ", tot size "
+ totalHighMethodSize);
log("Ondemand comp. methods: " + totalLowMethods + ", avg size "
+ (totalLowMethodSize / totalLowMethods) + ", tot size "
+ totalLowMethodSize);
log("Done.");
os.clear();
} catch (Throwable ex) {
ex.printStackTrace();
throw new BuildException(ex);
}