abstractbootimagebuilder.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 1,109 行 · 第 1/3 页
JAVA
1,109 行
/**
* $Id: AbstractBootImageBuilder.java,v 1.23 2004/02/26 10:33:12 epr Exp $
*/
package org.jnode.build;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import org.apache.tools.ant.Project;
import org.jnode.assembler.Label;
import org.jnode.assembler.NativeStream;
import org.jnode.assembler.UnresolvedObjectRefException;
import org.jnode.assembler.x86.X86Stream;
import org.jnode.plugin.PluginException;
import org.jnode.plugin.PluginRegistry;
import org.jnode.plugin.model.PluginRegistryModel;
import org.jnode.util.NumberUtils;
import org.jnode.vm.HeapHelperImpl;
import org.jnode.vm.Unsafe;
import org.jnode.vm.Vm;
import org.jnode.vm.VmArchitecture;
import org.jnode.vm.VmProcessor;
import org.jnode.vm.VmSystemClassLoader;
import org.jnode.vm.VmSystemObject;
import org.jnode.vm.bytecode.BytecodeParser;
import org.jnode.vm.classmgr.ObjectLayout;
import org.jnode.vm.classmgr.VmArray;
import org.jnode.vm.classmgr.VmClassType;
import org.jnode.vm.classmgr.VmMethodCode;
import org.jnode.vm.classmgr.VmStatics;
import org.jnode.vm.classmgr.VmType;
import org.jnode.vm.compiler.NativeCodeCompiler;
import org.jnode.vm.memmgr.HeapHelper;
import org.jnode.vm.memmgr.VmHeapManager;
import org.jnode.vm.memmgr.def.DefaultHeapManager;
import org.jnode.vm.memmgr.def.VmBootHeap;
import org.jnode.vm.memmgr.def.VmDefaultHeap;
/**
* Build the boot image from an assembler compiled bootstrap (in ELF format)
* combined with the precompiled Java classes.
*/
public abstract class AbstractBootImageBuilder extends AbstractPluginsTask {
/** System property set to indicate build time */
public static final String BUILDTIME_PROPERTY = "org.jnode.buildtime";
/**
* Classname/packagename of those classes/packages that need highly
* optimized compilation
*/
private final HashSet compileHighOptLevelPackages = new HashSet();
private File destFile;
private File kernelFile;
private File listFile;
private File debugFile;
private File jarFile;
private String version;
private VmSystemClassLoader clsMgr;
private URL classesURL = null;
private Set legalInstanceClasses;
/** Set of jbects that should not yet be emitted */
private final Set blockedObjects = new HashSet();
protected boolean debug = false;
protected static final Label bootHeapStart = new Label("$$bootHeapStart");
protected static final Label bootHeapEnd = new Label("$$bootHeapEnd");
protected static final Label imageEnd = new Label("$$image_end");
protected static final Label initialStack = new Label("$$initialStack");
protected static final Label initialStackPtr = new Label(
"$$initialStackPtr");
private int totalHighMethodSize;
private int totalHighMethods;
private int totalLowMethodSize;
private int totalLowMethods;
/**
* Construct a new BootImageBuilder
*/
public AbstractBootImageBuilder() {
setupCompileHighOptLevelPackages();
legalInstanceClasses = setupLegalInstanceClasses();
}
public final void execute() throws BuildException {
// Create the image
doExecute();
// Remove all garbage objects
cleanup();
System.gc();
// Make sure that all finalizers are called, in order to remove tmp files.
Runtime.getRuntime().runFinalization();
}
private final void doExecute() throws BuildException {
debug = (getProject().getProperty("jnode.debug") != null);
final long lmJar = jarFile.lastModified();
final long lmKernel = kernelFile.lastModified();
final long lmDest = destFile.lastModified();
final long lmPIL = getPluginListFile().lastModified();
if (version == null) {
throw new BuildException("Version property must be set");
}
final PluginList piList;
final long lmPI;
try {
log("plugin-list: " + getPluginListFile(), Project.MSG_DEBUG);
piList = getPluginList();
lmPI = piList.lastModified();
} catch (PluginException ex) {
throw new BuildException(ex);
} catch (IOException ex) {
throw new BuildException(ex);
}
if ((lmJar < lmDest) && (lmKernel < lmDest) && (lmPIL < lmDest)
&& (lmPI < lmDest)) {
// No need to do anything, skip
return; }
if (debugFile != null) {
debugFile.delete();
}
try {
System.getProperties().setProperty(BUILDTIME_PROPERTY, "1");
// Load the plugin descriptors
final PluginRegistry piRegistry;
piRegistry = new PluginRegistryModel(piList.getPluginList());
//piRegistry = new
// PluginRegistryModel(piList.getDescriptorUrlList());
testPluginPrerequisites(piRegistry);
/* Now create the processor */
final VmArchitecture arch = getArchitecture();
final NativeStream os = createNativeStream();
clsMgr = new VmSystemClassLoader(classesURL, arch,
new BuildObjectResolver(os, this));
blockedObjects.add(clsMgr);
blockedObjects.add(clsMgr.getStatics());
blockedObjects.add(clsMgr.getStatics().getTable());
if (debug) {
log("Building in DEBUG mode", Project.MSG_WARN);
}
// Create the VM
final HeapHelper helper = new HeapHelperImpl(arch);
final Vm vm = new Vm(version, arch, new DefaultHeapManager(clsMgr, helper,
clsMgr.getStatics()), clsMgr.getStatics(), debug);
blockedObjects.add(vm);
final VmProcessor proc = createProcessor(clsMgr.getStatics());
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
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(VmBootHeap.class);
loadClass(VmDefaultHeap.class);
loadClass(VmHeapManager.class);
loadClass(VmStatics.class);
loadClass(vm.getHeapManager().getClass());
loadClass(HeapHelper.class);
loadClass(HeapHelperImpl.class);
loadSystemClasses();
/* 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);
}
// Load the jarfile as byte-array
copyJarFile(os);
// Now emit all object images to the actual image
emitObjects(os, arch, blockedObjects);
// Disallow the loading of new classes
clsMgr.setFailOnNewLoad(true);
emitObjects(os, arch, blockedObjects);
// Emit the classmanager
log("Emit vm", Project.MSG_VERBOSE);
blockedObjects.remove(vm);
emitObjects(os, arch, blockedObjects);
// Twice, this is intended!
emitObjects(os, arch, blockedObjects);
/* Set the bootclasses */
log("prepare bootClassArray", Project.MSG_VERBOSE);
final VmType bootClasses[] = clsMgr.prepareAfterBootstrap();
os.getObjectRef(bootClasses);
emitObjects(os, arch, blockedObjects);
// Twice, this is intended!
emitObjects(os, arch, blockedObjects);
// Emit the classmanager
log("Emit clsMgr", Project.MSG_VERBOSE);
// Turn auto-compilation on
clsMgr.setCompileRequired();
blockedObjects.remove(clsMgr);
emitObjects(os, arch, blockedObjects);
// Twice, this is intended!
emitObjects(os, arch, blockedObjects);
// Emit the classmanager
log("Emit statics", Project.MSG_VERBOSE);
blockedObjects.remove(clsMgr.getStatics());
emitObjects(os, arch, blockedObjects);
// Twice, this is intended!
emitObjects(os, arch, blockedObjects);
// Emit the remaining objects
log("Emit rest; blocked=" + blockedObjects, Project.MSG_VERBOSE);
emitObjects(os, arch, null);
log("statics table 0x"
+ NumberUtils.hex(os.getObjectRef(
clsMgr.getStatics().getTable()).getOffset()),
Project.MSG_VERBOSE);
/* Write static initializer code */
emitStaticInitializerCalls(os, bootClasses, clInitCaller);
// This is the end of the image
X86Stream.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.getStatics());
// 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");
clsMgr.getStatics().dumpStatistics(System.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);
}
}
/**
* Create a platform specific native stream.
*
* @return NativeStream
*/
protected abstract NativeStream createNativeStream();
/**
* Create the default processor for this architecture.
*
* @return The processor
* @throws BuildException
*/
protected abstract VmProcessor createProcessor(VmStatics statics)
throws BuildException;
/**
* Gets the target architecture.
*
* @return The target architecture
* @throws BuildException
*/
protected abstract VmArchitecture getArchitecture() throws BuildException;
/**
* Copy the kernel native code into the native stream.
*
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?