vmsystem.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 799 行 · 第 1/2 页

JAVA
799
字号
/**
 * $Id: VmSystem.java,v 1.15 2004/02/26 10:33:48 epr Exp $
 */

package org.jnode.vm;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Properties;

import org.jnode.system.BootLog;
import org.jnode.system.MemoryResource;
import org.jnode.system.ResourceManager;
import org.jnode.system.ResourceNotFreeException;
import org.jnode.system.ResourceOwner;
import org.jnode.system.SimpleResourceOwner;
import org.jnode.vm.classmgr.AbstractExceptionHandler;
import org.jnode.vm.classmgr.VmArray;
import org.jnode.vm.classmgr.VmByteCode;
import org.jnode.vm.classmgr.VmClassLoader;
import org.jnode.vm.classmgr.VmCompiledCode;
import org.jnode.vm.classmgr.VmCompiledExceptionHandler;
import org.jnode.vm.classmgr.VmConstClass;
import org.jnode.vm.classmgr.VmInterpretedExceptionHandler;
import org.jnode.vm.classmgr.VmMethod;
import org.jnode.vm.classmgr.VmType;
import org.jnode.vm.memmgr.VmWriteBarrier;

/**
 * System support for the Virtual Machine
 * 
 * @author Ewout Prangsma (epr@users.sourceforge.net)
 */
public final class VmSystem {

    public static final int RC_HANDLER = 0xFFFFFFFB;

    public static final int RC_DEFHANDLER = 0xFFFFFFF1;

    private static final int STACKTRACE_LIMIT = 256;

    private static boolean inited;

    private static VmSystemClassLoader systemLoader;

    private static String cmdLine;

    private static volatile long currentTimeMillis;

    private static long rtcIncrement;

    private static RTCService rtcService;

    private static SystemOutputStream bootOut;

    private static MemoryResource initJar;

    /**
     * Initialize the Virtual Machine
     */
    public static void initialize() {
        if (!inited) {
            // Initialize resource manager
            Unsafe.debug("1");
            final ResourceManager rm = ResourceManagerImpl.initialize();
            Unsafe.debug("2");

            /* Set System.err, System.out */
            bootOut = new SystemOutputStream();
            //final ScreenOutputStream os = new
            // ScreenOutputStream(Screen.getInstance());
            final PrintStream ps = new PrintStream(bootOut, true);
            System.setOut(ps);
            System.setErr(ps);

            Unsafe.debug("3");

            /* Initialize the system classloader */
            VmSystemClassLoader loader = (VmSystemClassLoader) (getVmClass(Unsafe
                    .getCurrentProcessor()).getLoader());
            systemLoader = loader;
            loader.initialize();

            Unsafe.debug("4");

            // Initialize VmThread
            VmThread.initialize();

            Unsafe.debug("5");

            /* Initialize the monitor system */
            MonitorManager.initialize();

            Unsafe.debug("6");

            final Vm vm = Vm.getVm();

            // Initialize the monitors for the heap manager
            vm.getHeapManager().start();

            Unsafe.debug("7");

            /* We're done initializing */
            inited = true;
            Unsafe.getCurrentProcessor().systemReadyForThreadSwitch();

            Unsafe.debug("8");

            // Load the command line
            final Properties props = System.getProperties();
            props.setProperty("jnode.cmdline", getCmdLine());

            Unsafe.debug("9");

            // Load the initial jarfile
            initJar = loadInitJar(rm);

            Unsafe.debug("A");

            // Start the compilation manager
            vm.startHotMethodManager();

            Unsafe.debug("B");
}
    }

    /**
     * Load the initial jarfile.
     * 
     * @param rm
     * @return The initial jarfile resource, or null if no initial jarfile is
     *         available.
     */
    private static MemoryResource loadInitJar(ResourceManager rm) {
        final Address start = Unsafe.getInitJarStart();
        final Address end = Unsafe.getInitJarEnd();
        final long size = Address.distance(end, start);
        if (size == 0L) {
            // No initial jarfile
            BootLog.info("No initial jarfile found");
            return null;
        } else {
            BootLog.info("Found initial jarfile of " + size + "b");
            try {
                final ResourceOwner owner = new SimpleResourceOwner("System");
                return rm.claimMemoryResource(owner, start, size,
                        ResourceManager.MEMMODE_NORMAL);
            } catch (ResourceNotFreeException ex) {
                BootLog.error("Cannot claim initjar resource", ex);
                return null;
            }
        }
    }

    // ------------------------------------------
    // Information
    // ------------------------------------------

    public static Properties getInitProperties() {

        final String arch;
        final Vm vm = Vm.getVm();
        arch = Unsafe.getCurrentProcessor().getArchitecture().getName();
        Unsafe.debug("arch=");
        Unsafe.debug(arch);

        final Properties res = new Properties();
        res.put("java.version", "1.1.0");
        res.put("java.vendor", "JNode.org");
        res.put("java.vendor.url", "http://jnode.org");
        res.put("java.home", "/");
        res.put("java.vm.specification.version", "1.4");
        res.put("java.vm.specification.vendor", "JNode.org");
        res.put("java.vm.specification.name", "jnode");
        res.put("java.vm.version", vm.getVersion());
        res.put("java.vm.vendor", "JNode.org");
        res.put("java.vm.name", "JNode");
        res.put("java.class.version", "1.1");
        res.put("java.class.path", "");
        res.put("java.library.path", "");
        res.put("java.io.tmpdir", "/tmp");
        res.put("java.compiler", "Internal");
        res.put("java.ext.dirs", "");
        res.put("os.name", "JNode");
        res.put("os.arch", arch);
        res.put("os.version", vm.getVersion());
        res.put("file.separator", "/");
        res.put("path.separator", ":");
        res.put("line.separator", "\n");
        res.put("user.name", "System");
        res.put("user.home", "/");
        res.put("user.dir", "/");

        return res;
    }

    private static String getCmdLine() {
        if (cmdLine == null) {
            /* Load the command line */
            final int cmdLineSize = Unsafe.getCmdLine(null);
            final byte[] cmdLineArr = new byte[ cmdLineSize];
            Unsafe.getCmdLine(cmdLineArr);
            cmdLine = new String(cmdLineArr).trim();
        }
        return cmdLine;
    }

    /**
     * Gets the log of the bootstrap phase.
     * 
     * @return String
     */
    public static String getBootLog() {
        return bootOut.getData();
    }

    // ------------------------------------------
    // java.lang.Object support
    // ------------------------------------------

    /**
     * Gets the class of the given object
     * 
     * @param obj
     * @return The class
     */
    public static Class getClass(Object obj) {
        return getVmClass(obj).asClass();
    }

    /**
     * Gets the VmClass of the given object.
     * 
     * @param obj
     * @return VmClass
     */
    public static VmType getVmClass(Object obj) {
        if (obj == null) {
            throw new NullPointerException();
        } else {
            return Unsafe.getVmClass(obj);
        }
    }

    /**
     * Gets the memory address of the given object
     * 
     * @param obj
     * @return int
     */
    public static Address addressOf(Object obj) {
        return Unsafe.addressOf(obj);
    }

    /**
     * Clone the given object
     * 
     * @param obj
     * @return Object
     * @throws CloneNotSupportedException
     */
    public static Object clone(Object obj) throws CloneNotSupportedException {
        return Vm.getVm().getHeapManager().clone(obj);
    }

    /**
     * Gets the hashcode of the given object
     * 
     * @param obj
     * @return int
     */
    public static int getHashCode(Object obj) {
        if (obj == null) {
            throw new NullPointerException();
        } else {
            return Unsafe.addressToInt(Unsafe.addressOf(obj));
        }
    }

    // ------------------------------------------
    // java.lang.Class support
    // ------------------------------------------

    public static Class forName(String className) throws ClassNotFoundException {
        return getContextClassLoader().asClassLoader().loadClass(className);
    }

    /**
     * Gets the first non-system classloader out of the current stacktrace, or
     * the system classloader if no other classloader is found in the current
     * stacktrace.
     * 
     * @return The classloader
     */
    protected static VmClassLoader getContextClassLoader() {
        final VmStackReader reader = Unsafe.getCurrentProcessor()
                .getArchitecture().getStackReader();
        final VmSystemClassLoader systemLoader = VmSystem.systemLoader;
        Address f = Unsafe.getCurrentFrame();
        while (reader.isValid(f)) {
            final VmMethod method = reader.getMethod(f);
            final VmClassLoader loader = method.getDeclaringClass().getLoader();
            if ((loader != null) && (loader != systemLoader)) {
                return loader;
            } else {
                f = reader.getPrevious(f);
            }
        }
        return systemLoader;
    }

    // ------------------------------------------
    // java.lang.SecurityManager support
    // ------------------------------------------

    /**
     * Gets the current stacktrace as array of classes.
     * 
     * @return Class[]
     */
    public static Class[] getClassContext() {
        final VmStackReader reader = Unsafe.getCurrentProcessor()
                .getArchitecture().getStackReader();
        final VmStackFrame[] stack = reader.getVmStackTrace(Unsafe
                .getCurrentFrame(), null, STACKTRACE_LIMIT);
        final int count = stack.length;
        final Class[] result = new Class[ count];

        for (int i = 0; i < count; i++) {
            result[ i] = stack[ i].getMethod().getDeclaringClass().asClass();
        }

        return result;
    }

    /**
     * Do nothing, until interrupted by an interrupts.
     */
    public static void idle() {
        Unsafe.idle();
    }

    protected static Object allocStack(int size) {
        try {
            return Vm.getVm().getHeapManager()
                    .newInstance(
                            systemLoader.loadClass(
                                    "org.jnode.vm.VmSystemObject", true), size);
        } catch (ClassNotFoundException ex) {
            throw (NoClassDefFoundError) new NoClassDefFoundError()
                    .initCause(ex);
        }
    }

    /**
     * Gets the stacktrace of a given thread.
     * 
     * @param current
     * @return The stacktrace
     */
    public static Object[] getStackTrace(VmThread current) {
        if (current.inException) {
            Unsafe.debug("Exception in getStackTrace");
            Unsafe.die("getStackTrace");
            return null;
        } else {
            current.inException = true;
        }

        if (Vm.getVm().getHeapManager().isLowOnMemory()) { return null; }

        final VmProcessor proc = Unsafe.getCurrentProcessor();
        final VmStackReader reader = proc.getArchitecture().getStackReader();
        final VmStackFrame[] mt;
        //Address lastIP = null;
        if (current == proc.getCurrentThread()) {
            final Address curFrame = Unsafe.getCurrentFrame();
            mt = reader.getVmStackTrace(reader.getPrevious(curFrame), reader
                    .getReturnAddress(curFrame), STACKTRACE_LIMIT);
        } else {
            proc.disableReschedule();
            try {
                mt = reader.getVmStackTrace(current.getStackFrame(), current
                        .getInstructionPointer(), STACKTRACE_LIMIT);
                //lastIP = current.getInstructionPointer();
            } finally {
                proc.enableReschedule();
            }
        }
        final int cnt = (mt == null) ? 0 : mt.length;

        VmType lastClass = null;

        int i = 0;
        while (i < cnt) {

            final VmStackFrame f = mt[ i];
            if (f == null) {
                break;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?