⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cachedinstructioncompiler.java

📁 JPC: x86 PC Hardware Emulator. 牛津大学开发的一个纯JAVA的x86系统结构硬件模拟器。
💻 JAVA
字号:
/*    JPC: A x86 PC Hardware Emulator for a pure Java Virtual Machine    Release Version 2.0    A project from the Physics Dept, The University of Oxford    Copyright (C) 2007 Isis Innovation Limited    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License version 2 as published by    the Free Software Foundation.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License along    with this program; if not, write to the Free Software Foundation, Inc.,    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.     Details (including contact information) can be found at:     www.physics.ox.ac.uk/jpc*/package org.jpc.emulator.memory.codeblock.cache;

import org.jpc.emulator.memory.*;
import org.jpc.emulator.memory.codeblock.*;
import org.jpc.emulator.memory.codeblock.optimised.*;
import org.jpc.emulator.processor.*;

public class CachedInstructionCompiler implements CodeBlockCompiler, InstructionSource, ObjectTreeCache
{
    private CodeBlockCompiler underlying;
    private int operationBufferOffset;
    private int microcodeBufferOffset;
    private int[] bufferMicrocodes;
    private int[] bufferLength;
    private int[] bufferX86Length;

    private int operationReplayIndex;
    private int microcodeReplayIndex;

    private ObjectTreeStateMachine realModeTree;
    private ObjectTreeStateMachine protectedModeTree;
    private ObjectTreeStateMachine virtual8086ModeTree;
    private int foundRealModeBlockCount;
    private int addedRealModeBlockCount;
    private int foundProtectedModeBlockCount;
    private int addedProtectedModeBlockCount;
    private int foundVirtual8086ModeBlockCount;
    private int addedVirtual8086ModeBlockCount;

    public CachedInstructionCompiler(CodeBlockCompiler backup)
    {
	bufferMicrocodes = new int[100];
	bufferLength = new int[100];
	bufferX86Length = new int[100];
        microcodeBufferOffset = 0;
        operationBufferOffset = 0;

	this.underlying = backup;
 
        realModeTree = new ObjectTreeStateMachine();
        protectedModeTree = new ObjectTreeStateMachine();
        virtual8086ModeTree = new ObjectTreeStateMachine();
        foundRealModeBlockCount = addedRealModeBlockCount = 0;
        foundProtectedModeBlockCount = addedProtectedModeBlockCount = 0;
        foundVirtual8086ModeBlockCount = addedVirtual8086ModeBlockCount = 0;
    }

    public boolean getNext()
    {
        operationReplayIndex++;
        return  (operationReplayIndex < operationBufferOffset);
    }
 
    public int getMicrocode()
    {
        return bufferMicrocodes[microcodeReplayIndex++];
    }
 
    public int getLength()
    {
        return bufferLength[operationReplayIndex];
    }
 
    public int getX86Length()
    {
        return bufferX86Length[operationReplayIndex];
    }

    public CodeBlock getCodeBlock(ObjectTreeStateMachine codeBlockTree, InstructionSource source)
    {
        CodeBlock lastGoodBlock = null;
        microcodeBufferOffset = 0;
        operationBufferOffset = 0;

        while(source.getNext())
        {
            int uCodeLength = source.getLength();
            try {
                bufferLength[operationBufferOffset] = uCodeLength;
                bufferX86Length[operationBufferOffset] = source.getX86Length();
            } catch (ArrayIndexOutOfBoundsException e) {
                int[] newLength = new int[bufferLength.length * 2];
                int[] newX86Length = new int[bufferX86Length.length * 2];
                System.arraycopy(bufferLength, 0, newLength, 0, bufferLength.length);
                System.arraycopy(bufferX86Length, 0, newX86Length, 0, bufferX86Length.length);
                bufferLength = newLength;
                bufferX86Length = newX86Length;
                bufferLength[operationBufferOffset] = uCodeLength;
                bufferX86Length[operationBufferOffset] = source.getX86Length();
            }
            operationBufferOffset++;


            for(int i = 0; i < uCodeLength; i++)
            {
                // get ucode and step through tree, see if cb present
                int uCode = source.getMicrocode();

                codeBlockTree.stepTree(uCode);
                CodeBlock outputCodeBlock = (CodeBlock) codeBlockTree.getObjectAtState();
                if (outputCodeBlock != null)
                    lastGoodBlock = outputCodeBlock;

                // if no cb, buffer ucodes in order to pass on to backup factory
                try 
                {
                    bufferMicrocodes[microcodeBufferOffset] = uCode;
                } 
                catch (ArrayIndexOutOfBoundsException e) 
                {
                    int[] newMicrocodes = new int[bufferMicrocodes.length * 2];
                    System.arraycopy(bufferMicrocodes, 0, newMicrocodes, 0, bufferMicrocodes.length);
                    bufferMicrocodes = newMicrocodes;
                    bufferMicrocodes[microcodeBufferOffset] = uCode;
                }
                microcodeBufferOffset++;
            }
        }
        return lastGoodBlock;
    }


    public RealModeCodeBlock getRealModeCodeBlock(InstructionSource source)
    {
        realModeTree.resetTreeState();
        CodeBlock outputCodeBlock = getCodeBlock(realModeTree, source);

        if (outputCodeBlock == null)
        {
            operationReplayIndex = -1;
            microcodeReplayIndex = 0;
            outputCodeBlock = underlying.getRealModeCodeBlock(this);
            if (operationBufferOffset > 0) 
            {
                realModeTree.setObjectAtState(outputCodeBlock);
                addedRealModeBlockCount++;
            }
        }
        else 
        {
            foundRealModeBlockCount++;
        }
        
        return (RealModeCodeBlock) outputCodeBlock;
    }


    public ProtectedModeCodeBlock getProtectedModeCodeBlock(InstructionSource source)
    {
        protectedModeTree.resetTreeState();
        CodeBlock outputCodeBlock = getCodeBlock(protectedModeTree, source);

        if (outputCodeBlock == null)
        {
            operationReplayIndex = -1;
            microcodeReplayIndex = 0;
            outputCodeBlock = underlying.getProtectedModeCodeBlock(this);
            if (operationBufferOffset > 0)
            {
                protectedModeTree.setObjectAtState(outputCodeBlock);
                addedProtectedModeBlockCount++;
            }
        }
        else
        {
            foundProtectedModeBlockCount++;
        }

        return (ProtectedModeCodeBlock) outputCodeBlock;
    }

    public Virtual8086ModeCodeBlock getVirtual8086ModeCodeBlock(InstructionSource source)
    {
        virtual8086ModeTree.resetTreeState();
        CodeBlock outputCodeBlock = getCodeBlock(virtual8086ModeTree, source);

        if (outputCodeBlock == null)
        {
            operationReplayIndex = -1;
            microcodeReplayIndex = 0;
            outputCodeBlock = underlying.getVirtual8086ModeCodeBlock(this);
            if (operationBufferOffset > 0)
            {
                virtual8086ModeTree.setObjectAtState(outputCodeBlock);
                addedVirtual8086ModeBlockCount++;
            }
        }
        else
        {
            foundVirtual8086ModeBlockCount++;
        }

        return (Virtual8086ModeCodeBlock) outputCodeBlock;
    }



    public ObjectTreeStateMachine getObjectTree()
    {
        return realModeTree;
    }

    public long getAddedCount()
    {
        return addedRealModeBlockCount;
    }

    public long getFoundCount()
    {
        return foundRealModeBlockCount;
    }

}

⌨️ 快捷键说明

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