From: <ls...@us...> - 2010-02-20 20:32:40
|
Revision: 5732 http://jnode.svn.sourceforge.net/jnode/?rev=5732&view=rev Author: lsantha Date: 2010-02-20 20:32:33 +0000 (Sat, 20 Feb 2010) Log Message: ----------- The X86BytecodeVisitor is reused across method compilations. Modified Paths: -------------- trunk/core/src/core/org/jnode/vm/x86/compiler/X86CompilerHelper.java trunk/core/src/core/org/jnode/vm/x86/compiler/l1a/EmitterContext.java trunk/core/src/core/org/jnode/vm/x86/compiler/l1a/FPCompiler.java trunk/core/src/core/org/jnode/vm/x86/compiler/l1a/VirtualStack.java trunk/core/src/core/org/jnode/vm/x86/compiler/l1a/X86BytecodeVisitor.java trunk/core/src/core/org/jnode/vm/x86/compiler/l1a/X86Level1ACompiler.java Modified: trunk/core/src/core/org/jnode/vm/x86/compiler/X86CompilerHelper.java =================================================================== --- trunk/core/src/core/org/jnode/vm/x86/compiler/X86CompilerHelper.java 2010-02-20 11:09:53 UTC (rev 5731) +++ trunk/core/src/core/org/jnode/vm/x86/compiler/X86CompilerHelper.java 2010-02-20 20:32:33 UTC (rev 5732) @@ -103,7 +103,7 @@ */ public final int SLOTSIZE; - private final EntryPoints entryPoints; + private EntryPoints entryPoints; private VmMethod method; @@ -119,7 +119,7 @@ private final AbstractX86StackManager stackMgr; - private final X86Assembler os; + private X86Assembler os; private final Map<VmType<?>, Label> classInitLabels = new HashMap<VmType<?>, Label>(); @@ -159,6 +159,11 @@ haveCMOV = cpuId.hasFeature(X86CpuID.FEAT_CMOV); } + public void reset(X86Assembler x86Assembler, EntryPoints entryPoints) { + this.os = x86Assembler; + this.entryPoints = entryPoints; + } + /** * Reset the state of this helper. */ Modified: trunk/core/src/core/org/jnode/vm/x86/compiler/l1a/EmitterContext.java =================================================================== --- trunk/core/src/core/org/jnode/vm/x86/compiler/l1a/EmitterContext.java 2010-02-20 11:09:53 UTC (rev 5731) +++ trunk/core/src/core/org/jnode/vm/x86/compiler/l1a/EmitterContext.java 2010-02-20 20:32:33 UTC (rev 5732) @@ -34,7 +34,7 @@ /** * The output stream */ - private final X86Assembler os; + private X86Assembler os; /** * Helper class @@ -64,7 +64,7 @@ /** * The compiler context */ - private final EntryPoints context; + private EntryPoints context; /** * Create a new context @@ -89,6 +89,13 @@ this.context = context; } + public void reset(X86Assembler os, EntryPoints entryPoints) { + this.os = os; + this.context = entryPoints; + gprPool.reset(os); + xmmPool.reset(os); + } + /** * Return the current emitter's stream * Modified: trunk/core/src/core/org/jnode/vm/x86/compiler/l1a/FPCompiler.java =================================================================== --- trunk/core/src/core/org/jnode/vm/x86/compiler/l1a/FPCompiler.java 2010-02-20 11:09:53 UTC (rev 5731) +++ trunk/core/src/core/org/jnode/vm/x86/compiler/l1a/FPCompiler.java 2010-02-20 20:32:33 UTC (rev 5732) @@ -32,7 +32,7 @@ abstract class FPCompiler { protected final X86BytecodeVisitor bcv; - protected final X86Assembler os; + protected X86Assembler os; protected final EmitterContext ec; protected final VirtualStack vstack; protected final int arrayDataOffset; @@ -85,6 +85,11 @@ this.arrayDataOffset = arrayDataOffset; } + void reset(X86Assembler os) { + this.os = os; + vstack.reset(ec); + } + /** * fadd / dadd * Modified: trunk/core/src/core/org/jnode/vm/x86/compiler/l1a/VirtualStack.java =================================================================== --- trunk/core/src/core/org/jnode/vm/x86/compiler/l1a/VirtualStack.java 2010-02-20 11:09:53 UTC (rev 5731) +++ trunk/core/src/core/org/jnode/vm/x86/compiler/l1a/VirtualStack.java 2010-02-20 20:32:33 UTC (rev 5732) @@ -20,7 +20,6 @@ package org.jnode.vm.x86.compiler.l1a; -import org.jnode.assembler.x86.X86Assembler; import org.jnode.assembler.x86.X86Register; import org.jnode.vm.JvmType; import org.jnode.vm.Vm; @@ -55,9 +54,8 @@ /** * Constructor; create and initialize stack with default size - * @param os */ - VirtualStack(X86Assembler os) { + VirtualStack() { this.operandStack = checkOperandStack ? new ItemStack(Item.Kind.STACK, Integer.MAX_VALUE) : null; stack = new Item[8]; tos = 0; Modified: trunk/core/src/core/org/jnode/vm/x86/compiler/l1a/X86BytecodeVisitor.java =================================================================== --- trunk/core/src/core/org/jnode/vm/x86/compiler/l1a/X86BytecodeVisitor.java 2010-02-20 11:09:53 UTC (rev 5731) +++ trunk/core/src/core/org/jnode/vm/x86/compiler/l1a/X86BytecodeVisitor.java 2010-02-20 20:32:33 UTC (rev 5732) @@ -111,12 +111,12 @@ /** * The destination compiled method */ - private final CompiledMethod cm; + private CompiledMethod cm; /** * Current context */ - private final EntryPoints context; + private EntryPoints context; /** * Bytecode Address of current instruction @@ -156,7 +156,7 @@ /** * Emit logging info */ - private final boolean log; + private boolean log; /** * Maximum number of local variable slots @@ -166,7 +166,7 @@ /** * The output stream */ - private final X86Assembler os; + private X86Assembler os; /** * Should we set the current instruction label on startInstruction? @@ -201,7 +201,7 @@ /** * Magic method compiler */ - private final MagicHelper magicHelper; + private MagicHelper magicHelper; /** * FP instruction compiler @@ -211,7 +211,7 @@ /** * Type size information */ - private final TypeSizeInfo typeSizeInfo; + private TypeSizeInfo typeSizeInfo; /** * Current inline depth (starting at 0) @@ -248,6 +248,11 @@ private final CounterGroup counters = Vm.getVm().getCounterGroup(getClass().getName()); /** + * It is true while the compilation of a method is in progress. + */ + private boolean working; + + /** * Create a new instance * * @param outputStream @@ -264,7 +269,7 @@ this.context = context; this.typeSizeInfo = typeSizeInfo; this.magicHelper = magicHelper; - this.vstack = new VirtualStack(os); + this.vstack = new VirtualStack(); final X86RegisterPool gprPool; final X86RegisterPool xmmPool; if (os.isCode32()) { @@ -275,8 +280,7 @@ xmmPool = new X86RegisterPool.XMMs64(); } this.ifac = ItemFactory.getFactory(); - final AbstractX86StackManager stackMgr = vstack.createStackMgr(gprPool, - ifac); + final AbstractX86StackManager stackMgr = vstack.createStackMgr(gprPool, ifac); this.helper = new X86CompilerHelper(os, stackMgr, context, isBootstrap); this.cm = cm; final int slotSize = helper.SLOTSIZE; @@ -284,13 +288,26 @@ this.arrayDataOffset = VmArray.DATA_OFFSET * slotSize; this.tibOffset = ObjectLayout.TIB_SLOT * slotSize; this.log = os.isLogEnabled(); - this.eContext = new EmitterContext(os, helper, vstack, gprPool, - xmmPool, ifac, context); + this.eContext = new EmitterContext(os, helper, vstack, gprPool, xmmPool, ifac, context); vstack.initializeStackMgr(stackMgr, eContext); // TODO check for SSE support and switch to SSE compiler if available this.fpCompiler = new FPCompilerFPU(this, os, eContext, vstack, arrayDataOffset); } + public void reset(NativeStream os, CompiledMethod cm, boolean bootstrap, EntryPoints entryPoints, + MagicHelper magicHelper, TypeSizeInfo typeSizeInfo) { + this.os = (X86Assembler) os; + this.cm = cm; + this.context = entryPoints; + this.magicHelper = magicHelper; + this.typeSizeInfo = typeSizeInfo; + this.log = this.os.isLogEnabled(); + this.vstack.reset(eContext); + this.helper.reset((X86Assembler) os, entryPoints); + this.eContext.reset((X86Assembler) os, entryPoints); + this.fpCompiler.reset((X86Assembler) os); + } + private void assertCondition(boolean cond, String message) { if (!cond) throw new Error("assert failed at addresss " + curAddress + ": " @@ -639,7 +656,7 @@ /** * @see org.jnode.vm.bytecode.BytecodeVisitor#endMethod() */ - public void endMethod() { + public synchronized void endMethod() { stackFrame.emitTrailer(typeSizeInfo, maxLocals); if (ItemFactory.CHECK_BALANCED_ITEM_FACTORY) { if (!ifac.isBalanced()) { @@ -647,8 +664,13 @@ ifac.balance(); } } + working = false; } + public synchronized boolean isWorking() { + return working; + } + /** * A try block has finished */ @@ -1142,7 +1164,8 @@ * @param method * @see org.jnode.vm.bytecode.BytecodeVisitor#startMethod(org.jnode.vm.classmgr.VmMethod) */ - public void startMethod(VmMethod method) { + public synchronized void startMethod(VmMethod method) { + working = true; if (debug) { BootLog.debug("setMethod(" + method + ")"); } Modified: trunk/core/src/core/org/jnode/vm/x86/compiler/l1a/X86Level1ACompiler.java =================================================================== --- trunk/core/src/core/org/jnode/vm/x86/compiler/l1a/X86Level1ACompiler.java 2010-02-20 11:09:53 UTC (rev 5731) +++ trunk/core/src/core/org/jnode/vm/x86/compiler/l1a/X86Level1ACompiler.java 2010-02-20 20:32:33 UTC (rev 5732) @@ -20,6 +20,8 @@ package org.jnode.vm.x86.compiler.l1a; +import java.util.ArrayList; +import java.util.List; import org.jnode.assembler.NativeStream; import org.jnode.assembler.ObjectResolver; import org.jnode.assembler.x86.X86BinaryAssembler; @@ -92,6 +94,10 @@ public X86Level1ACompiler() { } + private final ThreadLocal<X86BytecodeVisitor> byteCodeVisitorHolder = new ThreadLocal<X86BytecodeVisitor>(); + + private final ThreadLocal<List<X86BytecodeVisitor>> byteCodeVisitorListHolder = + new ThreadLocal<List<X86BytecodeVisitor>>(); /** * Create the visitor that converts bytecodes into native code. * @@ -107,7 +113,38 @@ boolean isBootstrap) { final InlineBytecodeVisitor cbv; final EntryPoints entryPoints = getEntryPoints(); - cbv = new X86BytecodeVisitor(os, cm, isBootstrap, entryPoints, getMagicHelper(), getTypeSizeInfo()); + X86BytecodeVisitor byteCodeVisitor = byteCodeVisitorHolder.get(); + if (byteCodeVisitor == null) { + byteCodeVisitor = new X86BytecodeVisitor(os, cm, isBootstrap, entryPoints, + getMagicHelper(), getTypeSizeInfo()); + byteCodeVisitorHolder.set(byteCodeVisitor); + } else { + if (byteCodeVisitor.isWorking()) { + //slow path + List<X86BytecodeVisitor> vlist = byteCodeVisitorListHolder.get(); + if (vlist == null) { + vlist = new ArrayList<X86BytecodeVisitor>(); + byteCodeVisitorListHolder.set(vlist); + } + byteCodeVisitor = null; + for (X86BytecodeVisitor bv : vlist) { + if (!bv.isWorking()) { + byteCodeVisitor = bv; + break; + } + } + if (byteCodeVisitor == null) { + byteCodeVisitor = new X86BytecodeVisitor(os, cm, isBootstrap, entryPoints, + getMagicHelper(), getTypeSizeInfo()); + vlist.add(byteCodeVisitor); + } else { + byteCodeVisitor.reset(os, cm, isBootstrap, entryPoints, getMagicHelper(), getTypeSizeInfo()); + } + } else { + byteCodeVisitor.reset(os, cm, isBootstrap, entryPoints, getMagicHelper(), getTypeSizeInfo()); + } + } + cbv = byteCodeVisitor; if (inlineMethods /*&& ((X86Assembler)os).isCode32()*/) { final VmClassLoader loader = method.getDeclaringClass().getLoader(); return new OptimizingBytecodeVisitor(entryPoints, cbv, loader); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |