changeset 2507:9ec15d6914ca

Pull over of compiler from maxine repository.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Wed, 27 Apr 2011 11:43:22 +0200
parents 4a3bf8a5bf41
children fea94949e0a2
files graal/Compiler/.checkstyle graal/Compiler/.checkstyle_checks.xml graal/Compiler/.classpath graal/Compiler/.project graal/Compiler/.settings/JavaSourceCodeFormatting.xml graal/Compiler/.settings/org.eclipse.jdt.core.prefs graal/Compiler/.settings/org.eclipse.jdt.ui.prefs graal/Compiler/LICENSE graal/Compiler/bin/com/sun/c1x/doc/IRInterpreter.txt graal/Compiler/bin/com/sun/c1x/doc/LoopPeeling.txt graal/Compiler/bin/com/sun/c1x/doc/backend_open_issues.txt graal/Compiler/bin/com/sun/c1x/doc/differences.txt graal/Compiler/bin/com/sun/c1x/doc/performance.txt graal/Compiler/src/com/sun/c1x/C1XCompilation.java graal/Compiler/src/com/sun/c1x/C1XCompiler.java graal/Compiler/src/com/sun/c1x/C1XCompilerExtension.java graal/Compiler/src/com/sun/c1x/C1XIntrinsic.java graal/Compiler/src/com/sun/c1x/C1XMetrics.java graal/Compiler/src/com/sun/c1x/C1XOptions.java graal/Compiler/src/com/sun/c1x/C1XTimers.java graal/Compiler/src/com/sun/c1x/alloc/ControlFlowOptimizer.java graal/Compiler/src/com/sun/c1x/alloc/EdgeMoveOptimizer.java graal/Compiler/src/com/sun/c1x/alloc/Interval.java graal/Compiler/src/com/sun/c1x/alloc/IntervalWalker.java graal/Compiler/src/com/sun/c1x/alloc/LIRInsertionBuffer.java graal/Compiler/src/com/sun/c1x/alloc/LinearScan.java graal/Compiler/src/com/sun/c1x/alloc/LinearScanWalker.java graal/Compiler/src/com/sun/c1x/alloc/MoveResolver.java graal/Compiler/src/com/sun/c1x/alloc/OperandPool.java graal/Compiler/src/com/sun/c1x/alloc/Range.java graal/Compiler/src/com/sun/c1x/alloc/RegisterVerifier.java graal/Compiler/src/com/sun/c1x/asm/AbstractAssembler.java graal/Compiler/src/com/sun/c1x/asm/Buffer.java graal/Compiler/src/com/sun/c1x/asm/ExceptionInfo.java graal/Compiler/src/com/sun/c1x/asm/Label.java graal/Compiler/src/com/sun/c1x/debug/BlockPrinter.java graal/Compiler/src/com/sun/c1x/debug/CFGPrinter.java graal/Compiler/src/com/sun/c1x/debug/CFGPrinterObserver.java graal/Compiler/src/com/sun/c1x/debug/InstructionPrinter.java graal/Compiler/src/com/sun/c1x/debug/LogStream.java graal/Compiler/src/com/sun/c1x/debug/TTY.java graal/Compiler/src/com/sun/c1x/debug/package-info.java graal/Compiler/src/com/sun/c1x/doc/IRInterpreter.txt graal/Compiler/src/com/sun/c1x/doc/LoopPeeling.txt graal/Compiler/src/com/sun/c1x/doc/backend_open_issues.txt graal/Compiler/src/com/sun/c1x/doc/differences.txt graal/Compiler/src/com/sun/c1x/doc/performance.txt graal/Compiler/src/com/sun/c1x/gen/LIRGenerator.java graal/Compiler/src/com/sun/c1x/gen/LIRItem.java graal/Compiler/src/com/sun/c1x/gen/PhiResolver.java graal/Compiler/src/com/sun/c1x/gen/package-info.java graal/Compiler/src/com/sun/c1x/globalstub/GlobalStub.java graal/Compiler/src/com/sun/c1x/globalstub/GlobalStubEmitter.java graal/Compiler/src/com/sun/c1x/graph/BlockMap.java graal/Compiler/src/com/sun/c1x/graph/BlockUtil.java graal/Compiler/src/com/sun/c1x/graph/CriticalEdgeFinder.java graal/Compiler/src/com/sun/c1x/graph/GraphBuilder.java graal/Compiler/src/com/sun/c1x/graph/IR.java graal/Compiler/src/com/sun/c1x/graph/MemoryMap.java graal/Compiler/src/com/sun/c1x/graph/ScopeData.java graal/Compiler/src/com/sun/c1x/graph/package-info.java graal/Compiler/src/com/sun/c1x/ir/AccessArray.java graal/Compiler/src/com/sun/c1x/ir/AccessField.java graal/Compiler/src/com/sun/c1x/ir/AccessIndexed.java graal/Compiler/src/com/sun/c1x/ir/AccessMonitor.java graal/Compiler/src/com/sun/c1x/ir/ArithmeticOp.java graal/Compiler/src/com/sun/c1x/ir/ArrayCopy.java graal/Compiler/src/com/sun/c1x/ir/ArrayLength.java graal/Compiler/src/com/sun/c1x/ir/Base.java graal/Compiler/src/com/sun/c1x/ir/BlockBegin.java graal/Compiler/src/com/sun/c1x/ir/BlockClosure.java graal/Compiler/src/com/sun/c1x/ir/BlockEnd.java graal/Compiler/src/com/sun/c1x/ir/BlockList.java graal/Compiler/src/com/sun/c1x/ir/BoundsCheck.java graal/Compiler/src/com/sun/c1x/ir/BreakpointTrap.java graal/Compiler/src/com/sun/c1x/ir/CheckCast.java graal/Compiler/src/com/sun/c1x/ir/CompareAndSwap.java graal/Compiler/src/com/sun/c1x/ir/CompareOp.java graal/Compiler/src/com/sun/c1x/ir/ComputeLinearScanOrder.java graal/Compiler/src/com/sun/c1x/ir/Condition.java graal/Compiler/src/com/sun/c1x/ir/Constant.java graal/Compiler/src/com/sun/c1x/ir/Convert.java graal/Compiler/src/com/sun/c1x/ir/DefaultValueVisitor.java graal/Compiler/src/com/sun/c1x/ir/ExceptionHandler.java graal/Compiler/src/com/sun/c1x/ir/ExceptionObject.java graal/Compiler/src/com/sun/c1x/ir/Goto.java graal/Compiler/src/com/sun/c1x/ir/Guard.java graal/Compiler/src/com/sun/c1x/ir/IRScope.java graal/Compiler/src/com/sun/c1x/ir/If.java graal/Compiler/src/com/sun/c1x/ir/IfOp.java graal/Compiler/src/com/sun/c1x/ir/IncrementRegister.java graal/Compiler/src/com/sun/c1x/ir/Info.java graal/Compiler/src/com/sun/c1x/ir/Infopoint.java graal/Compiler/src/com/sun/c1x/ir/InstanceOf.java graal/Compiler/src/com/sun/c1x/ir/Instruction.java graal/Compiler/src/com/sun/c1x/ir/Intrinsic.java graal/Compiler/src/com/sun/c1x/ir/Invoke.java graal/Compiler/src/com/sun/c1x/ir/LoadField.java graal/Compiler/src/com/sun/c1x/ir/LoadIndexed.java graal/Compiler/src/com/sun/c1x/ir/LoadPointer.java graal/Compiler/src/com/sun/c1x/ir/LoadRegister.java graal/Compiler/src/com/sun/c1x/ir/Local.java graal/Compiler/src/com/sun/c1x/ir/LogicOp.java graal/Compiler/src/com/sun/c1x/ir/LookupSwitch.java graal/Compiler/src/com/sun/c1x/ir/MemoryBarrier.java graal/Compiler/src/com/sun/c1x/ir/MonitorAddress.java graal/Compiler/src/com/sun/c1x/ir/MonitorEnter.java graal/Compiler/src/com/sun/c1x/ir/MonitorExit.java graal/Compiler/src/com/sun/c1x/ir/NativeCall.java graal/Compiler/src/com/sun/c1x/ir/NegateOp.java graal/Compiler/src/com/sun/c1x/ir/NewArray.java graal/Compiler/src/com/sun/c1x/ir/NewInstance.java graal/Compiler/src/com/sun/c1x/ir/NewMultiArray.java graal/Compiler/src/com/sun/c1x/ir/NewObjectArray.java graal/Compiler/src/com/sun/c1x/ir/NewObjectArrayClone.java graal/Compiler/src/com/sun/c1x/ir/NewTypeArray.java graal/Compiler/src/com/sun/c1x/ir/NullCheck.java graal/Compiler/src/com/sun/c1x/ir/Op2.java graal/Compiler/src/com/sun/c1x/ir/OsrEntry.java graal/Compiler/src/com/sun/c1x/ir/Pause.java graal/Compiler/src/com/sun/c1x/ir/Phi.java graal/Compiler/src/com/sun/c1x/ir/PointerOp.java graal/Compiler/src/com/sun/c1x/ir/ResolveClass.java graal/Compiler/src/com/sun/c1x/ir/Return.java graal/Compiler/src/com/sun/c1x/ir/ShiftOp.java graal/Compiler/src/com/sun/c1x/ir/SignificantBitOp.java graal/Compiler/src/com/sun/c1x/ir/StackAllocate.java graal/Compiler/src/com/sun/c1x/ir/StackHandle.java graal/Compiler/src/com/sun/c1x/ir/StateSplit.java graal/Compiler/src/com/sun/c1x/ir/StoreField.java graal/Compiler/src/com/sun/c1x/ir/StoreIndexed.java graal/Compiler/src/com/sun/c1x/ir/StorePointer.java graal/Compiler/src/com/sun/c1x/ir/StoreRegister.java graal/Compiler/src/com/sun/c1x/ir/Switch.java graal/Compiler/src/com/sun/c1x/ir/TableSwitch.java graal/Compiler/src/com/sun/c1x/ir/TemplateCall.java graal/Compiler/src/com/sun/c1x/ir/Throw.java graal/Compiler/src/com/sun/c1x/ir/TypeCheck.java graal/Compiler/src/com/sun/c1x/ir/TypeEqualityCheck.java graal/Compiler/src/com/sun/c1x/ir/UnsafeCast.java graal/Compiler/src/com/sun/c1x/ir/UnsafeGetObject.java graal/Compiler/src/com/sun/c1x/ir/UnsafeGetRaw.java graal/Compiler/src/com/sun/c1x/ir/UnsafeObjectOp.java graal/Compiler/src/com/sun/c1x/ir/UnsafeOp.java graal/Compiler/src/com/sun/c1x/ir/UnsafePrefetch.java graal/Compiler/src/com/sun/c1x/ir/UnsafePrefetchRead.java graal/Compiler/src/com/sun/c1x/ir/UnsafePrefetchWrite.java graal/Compiler/src/com/sun/c1x/ir/UnsafePutObject.java graal/Compiler/src/com/sun/c1x/ir/UnsafePutRaw.java graal/Compiler/src/com/sun/c1x/ir/UnsafeRawOp.java graal/Compiler/src/com/sun/c1x/ir/UnsignedCompareOp.java graal/Compiler/src/com/sun/c1x/ir/Value.java graal/Compiler/src/com/sun/c1x/ir/ValueClosure.java graal/Compiler/src/com/sun/c1x/ir/ValueVisitor.java graal/Compiler/src/com/sun/c1x/ir/package-info.java graal/Compiler/src/com/sun/c1x/lir/FrameMap.java graal/Compiler/src/com/sun/c1x/lir/LIRAssembler.java graal/Compiler/src/com/sun/c1x/lir/LIRBlock.java graal/Compiler/src/com/sun/c1x/lir/LIRBranch.java graal/Compiler/src/com/sun/c1x/lir/LIRCall.java graal/Compiler/src/com/sun/c1x/lir/LIRCompareAndSwap.java graal/Compiler/src/com/sun/c1x/lir/LIRConvert.java graal/Compiler/src/com/sun/c1x/lir/LIRDebugInfo.java graal/Compiler/src/com/sun/c1x/lir/LIRInstruction.java graal/Compiler/src/com/sun/c1x/lir/LIRLabel.java graal/Compiler/src/com/sun/c1x/lir/LIRList.java graal/Compiler/src/com/sun/c1x/lir/LIRMemoryBarrier.java graal/Compiler/src/com/sun/c1x/lir/LIRMonitorAddress.java graal/Compiler/src/com/sun/c1x/lir/LIRNegate.java graal/Compiler/src/com/sun/c1x/lir/LIROp0.java graal/Compiler/src/com/sun/c1x/lir/LIROp1.java graal/Compiler/src/com/sun/c1x/lir/LIROp2.java graal/Compiler/src/com/sun/c1x/lir/LIROp3.java graal/Compiler/src/com/sun/c1x/lir/LIROpcode.java graal/Compiler/src/com/sun/c1x/lir/LIROperand.java graal/Compiler/src/com/sun/c1x/lir/LIRSignificantBit.java graal/Compiler/src/com/sun/c1x/lir/LIRStackAllocate.java graal/Compiler/src/com/sun/c1x/lir/LIRTableSwitch.java graal/Compiler/src/com/sun/c1x/lir/LIRXirInstruction.java graal/Compiler/src/com/sun/c1x/lir/package-info.java graal/Compiler/src/com/sun/c1x/observer/CompilationEvent.java graal/Compiler/src/com/sun/c1x/observer/CompilationObserver.java graal/Compiler/src/com/sun/c1x/observer/ObservableCompiler.java graal/Compiler/src/com/sun/c1x/observer/package-info.java graal/Compiler/src/com/sun/c1x/opt/BlockMerger.java graal/Compiler/src/com/sun/c1x/opt/CEEliminator.java graal/Compiler/src/com/sun/c1x/opt/Canonicalizer.java graal/Compiler/src/com/sun/c1x/opt/GlobalValueNumberer.java graal/Compiler/src/com/sun/c1x/opt/InstructionSubstituter.java graal/Compiler/src/com/sun/c1x/opt/LivenessMarker.java graal/Compiler/src/com/sun/c1x/opt/NullCheckEliminator.java graal/Compiler/src/com/sun/c1x/opt/PhiSimplifier.java graal/Compiler/src/com/sun/c1x/opt/SCCPropagator.java graal/Compiler/src/com/sun/c1x/opt/TypeAnalyzer.java graal/Compiler/src/com/sun/c1x/opt/UnsafeCastEliminator.java graal/Compiler/src/com/sun/c1x/opt/ValueMap.java graal/Compiler/src/com/sun/c1x/package-info.java graal/Compiler/src/com/sun/c1x/target/Backend.java graal/Compiler/src/com/sun/c1x/target/amd64/AMD64.java graal/Compiler/src/com/sun/c1x/target/amd64/AMD64Assembler.java graal/Compiler/src/com/sun/c1x/target/amd64/AMD64Backend.java graal/Compiler/src/com/sun/c1x/target/amd64/AMD64GlobalStubEmitter.java graal/Compiler/src/com/sun/c1x/target/amd64/AMD64LIRAssembler.java graal/Compiler/src/com/sun/c1x/target/amd64/AMD64LIRGenerator.java graal/Compiler/src/com/sun/c1x/target/amd64/AMD64MacroAssembler.java graal/Compiler/src/com/sun/c1x/target/amd64/AMD64XirAssembler.java graal/Compiler/src/com/sun/c1x/target/sparc/SPARC.java graal/Compiler/src/com/sun/c1x/util/ArrayMap.java graal/Compiler/src/com/sun/c1x/util/BitMap2D.java graal/Compiler/src/com/sun/c1x/util/BlockWorkList.java graal/Compiler/src/com/sun/c1x/util/IntList.java graal/Compiler/src/com/sun/c1x/util/Util.java graal/Compiler/src/com/sun/c1x/value/FrameState.java graal/Compiler/src/com/sun/c1x/value/MutableFrameState.java graal/Compiler/src/com/sun/c1x/value/package-info.java
diffstat 215 files changed, 47388 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/.checkstyle	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<fileset-config file-format-version="1.2.0" simple-config="true">
+    <local-check-config name="C1X Checkstyle checks" location=".checkstyle_checks.xml" type="project" description="">
+        <additional-data name="protect-config-file" value="false"/>
+    </local-check-config>
+    <fileset name="all" enabled="true" check-config-name="C1X Checkstyle checks" local="true">
+        <file-match-pattern match-pattern="." include-pattern="true"/>
+    </fileset>
+</fileset-config>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/.checkstyle_checks.xml	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
+
+<!--
+    This configuration file was written by the eclipse-cs plugin configuration editor
+-->
+<!--
+    Checkstyle-Configuration: C1X Checkstyle checks
+    Description: none
+-->
+<module name="Checker">
+  <property name="severity" value="warning"/>
+  <module name="TreeWalker">
+    <property name="tabWidth" value="4"/>
+    <module name="FileContentsHolder"/>
+    <module name="JavadocStyle">
+      <property name="checkHtml" value="false"/>
+    </module>
+    <module name="LocalFinalVariableName"/>
+    <module name="LocalVariableName"/>
+    <module name="MemberName">
+      <property name="format" value="^(([a-z][a-zA-Z0-9]*$)|(_[A-Z][a-zA-Z0-9]*_[a-z][a-zA-Z0-9]*$))"/>
+    </module>
+    <module name="MethodName">
+      <property name="format" value="^[a-z][a-z_A-Z0-9]*$"/>
+    </module>
+    <module name="PackageName"/>
+    <module name="ParameterName"/>
+    <module name="TypeName">
+      <property name="format" value="^[A-Z][_a-zA-Z0-9]*$"/>
+    </module>
+    <module name="RedundantImport"/>
+    <module name="LineLength">
+      <property name="max" value="250"/>
+    </module>
+    <module name="MethodParamPad"/>
+    <module name="NoWhitespaceAfter">
+      <property name="tokens" value="ARRAY_INIT,BNOT,DEC,DOT,INC,LNOT,UNARY_MINUS,UNARY_PLUS"/>
+    </module>
+    <module name="NoWhitespaceBefore">
+      <property name="tokens" value="SEMI,DOT,POST_DEC,POST_INC"/>
+    </module>
+    <module name="ParenPad"/>
+    <module name="TypecastParenPad">
+      <property name="tokens" value="RPAREN,TYPECAST"/>
+    </module>
+    <module name="WhitespaceAfter"/>
+    <module name="WhitespaceAround">
+      <property name="tokens" value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN,BXOR,BXOR_ASSIGN,COLON,DIV,DIV_ASSIGN,EQUAL,GE,GT,LAND,LE,LITERAL_ASSERT,LITERAL_CATCH,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_RETURN,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE,LOR,LT,MINUS,MINUS_ASSIGN,MOD,MOD_ASSIGN,NOT_EQUAL,PLUS,PLUS_ASSIGN,QUESTION,SL,SLIST,SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN,LITERAL_ASSERT,TYPE_EXTENSION_AND"/>
+    </module>
+    <module name="RedundantModifier"/>
+    <module name="AvoidNestedBlocks">
+      <property name="allowInSwitchCase" value="true"/>
+    </module>
+    <module name="EmptyBlock">
+      <property name="option" value="text"/>
+      <property name="tokens" value="LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_IF,LITERAL_TRY,LITERAL_WHILE,STATIC_INIT"/>
+    </module>
+    <module name="LeftCurly"/>
+    <module name="NeedBraces"/>
+    <module name="RightCurly"/>
+    <module name="DoubleCheckedLocking">
+      <property name="severity" value="error"/>
+    </module>
+    <module name="EmptyStatement"/>
+    <module name="HiddenField">
+      <property name="severity" value="ignore"/>
+      <property name="ignoreConstructorParameter" value="true"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="FinalClass"/>
+    <module name="HideUtilityClassConstructor">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="ArrayTypeStyle"/>
+    <module name="UpperEll"/>
+    <module name="FallThrough"/>
+    <module name="FinalLocalVariable">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="MultipleVariableDeclarations"/>
+    <module name="StringLiteralEquality">
+      <property name="severity" value="error"/>
+    </module>
+    <module name="SuperFinalize"/>
+    <module name="UnnecessaryParentheses">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="Indentation">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="StaticVariableName">
+      <property name="format" value="^[A-Za-z][a-zA-Z0-9]*$"/>
+    </module>
+    <module name="EmptyForInitializerPad"/>
+    <module name="EmptyForIteratorPad"/>
+    <module name="ModifierOrder"/>
+    <module name="DefaultComesLast"/>
+    <module name="InnerAssignment">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="JUnitTestCase"/>
+    <module name="ModifiedControlVariable"/>
+    <module name="MutableException"/>
+    <module name="ParameterAssignment">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <property name="format" value="\s$"/>
+      <property name="message" value="Illegal trailing whitespace(s) at the end of the line."/>
+      <property name="ignoreComments" value="true"/>
+      <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Checks for trailing spaces at the end of a line"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <property name="format" value=" ,"/>
+      <property name="ignoreComments" value="true"/>
+      <metadata name="com.atlassw.tools.eclipse.checkstyle.customMessage" value="Illegal whitespace before a comma."/>
+      <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Checks for whitespace before a comma."/>
+    </module>
+  </module>
+  <module name="RegexpHeader">
+    <property name="header" value="/\*\n \* Copyright \(c\) (20[0-9][0-9], )?20[0-9][0-9], Oracle and/or its affiliates. All rights reserved.\n \* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n \*\n \* This code is free software; you can redistribute it and/or modify it\n \* under the terms of the GNU General Public License version 2 only, as\n \* published by the Free Software Foundation.\n \*\n \* This code is distributed in the hope that it will be useful, but WITHOUT\n \* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n \* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n \* version 2 for more details \(a copy is included in the LICENSE file that\n \* accompanied this code\).\n \*\n \* You should have received a copy of the GNU General Public License version\n \* 2 along with this work; if not, write to the Free Software Foundation,\n \* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n \*\n \* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n \* or visit www.oracle.com if you need additional information or have any\n \* questions.\n \*/\n"/>
+  </module>
+  <module name="FileTabCharacter">
+    <property name="severity" value="error"/>
+  </module>
+  <module name="NewlineAtEndOfFile">
+    <property name="lineSeparator" value="lf"/>
+  </module>
+  <module name="Translation"/>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop constant name check"/>
+    <property name="onCommentFormat" value="Checkstyle: resume constant name check"/>
+    <property name="checkFormat" value="ConstantNameCheck"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Allow non-conforming constant names"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop method name check"/>
+    <property name="onCommentFormat" value="Checkstyle: resume method name check"/>
+    <property name="checkFormat" value="MethodName"/>
+    <property name="checkC" value="false"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable method name checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CheckStyle: stop parameter assignment check"/>
+    <property name="onCommentFormat" value="CheckStyle: resume parameter assignment check"/>
+    <property name="checkFormat" value="ParameterAssignment"/>
+    <property name="checkC" value="false"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable Parameter Assignment"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop final variable check"/>
+    <property name="onCommentFormat" value="Checkstyle: resume final variable check"/>
+    <property name="checkFormat" value="FinalLocalVariable"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable final variable checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop"/>
+    <property name="onCommentFormat" value="Checkstyle: resume"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable all checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="// START GENERATED RAW ASSEMBLER METHODS"/>
+    <property name="onCommentFormat" value="// END GENERATED RAW ASSEMBLER METHODS"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable all checks for generated raw assembler methods"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="// START GENERATED LABEL ASSEMBLER METHODS"/>
+    <property name="onCommentFormat" value="// END GENERATED LABEL ASSEMBLER METHODS"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable all checks for generated label assembler methods"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CheckStyle: stop inner assignment check"/>
+    <property name="onCommentFormat" value="CheckStyle: resume inner assignment check"/>
+    <property name="checkFormat" value="InnerAssignment"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable inner assignment checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop field name check"/>
+    <property name="onCommentFormat" value="Checkstyle: resume field name check"/>
+    <property name="checkFormat" value="MemberName"/>
+    <property name="checkC" value="false"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable field name checks"/>
+  </module>
+</module>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/.classpath	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" exported="true" kind="src" path="/CRI"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/.project	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>Compiler</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>net.sourceforge.metrics.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>net.sf.eclipsecs.core.CheckstyleBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>net.sourceforge.metrics.nature</nature>
+		<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
+	</natures>
+</projectDescription>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/.settings/JavaSourceCodeFormatting.xml	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,264 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<profiles version="11">
+<profile kind="CodeFormatterProfile" name="C1XJavaCodeStyle" version="11">
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="4"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
+<setting id="org.eclipse.jdt.core.compiler.source" value="1.5"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="200"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="8"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
+<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
+<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.5"/>
+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="4"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="120"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.5"/>
+<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
+</profile>
+</profiles>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/.settings/org.eclipse.jdt.core.prefs	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,355 @@
+#Tue Jul 13 10:33:43 PDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=disabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=1
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
+org.eclipse.jdt.core.formatter.comment.line_length=120
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=4
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=4
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
+org.eclipse.jdt.core.formatter.indentation.size=8
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=true
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=200
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=true
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=true
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=false
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/.settings/org.eclipse.jdt.ui.prefs	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,64 @@
+#Thu Feb 18 11:36:17 PST 2010
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_MaxineJavaCodeStyle
+formatter_settings_version=11
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=java;javax;org;com;
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.ondemandthreshold=0
+org.eclipse.jdt.ui.overrideannotation=true
+org.eclipse.jdt.ui.staticondemandthreshold=0
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=false
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=false
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=false
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=false
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/LICENSE	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,347 @@
+The GNU General Public License (GPL)
+
+Version 2, June 1991
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim copies of this license
+document, but changing it is not allowed.
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share
+and change it.  By contrast, the GNU General Public License is intended to
+guarantee your freedom to share and change free software--to make sure the
+software is free for all its users.  This General Public License applies to
+most of the Free Software Foundation's software and to any other program whose
+authors commit to using it.  (Some other Free Software Foundation software is
+covered by the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+When we speak of free software, we are referring to freedom, not price.  Our
+General Public Licenses are designed to make sure that you have the freedom to
+distribute copies of free software (and charge for this service if you wish),
+that you receive source code or can get it if you want it, that you can change
+the software or use pieces of it in new free programs; and that you know you
+can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to deny
+you these rights or to ask you to surrender the rights.  These restrictions
+translate to certain responsibilities for you if you distribute copies of the
+software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis or for
+a fee, you must give the recipients all the rights that you have.  You must
+make sure that they, too, receive or can get the source code.  And you must
+show them these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and (2)
+offer you this license which gives you legal permission to copy, distribute
+and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain that
+everyone understands that there is no warranty for this free software.  If the
+software is modified by someone else and passed on, we want its recipients to
+know that what they have is not the original, so that any problems introduced
+by others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents.  We
+wish to avoid the danger that redistributors of a free program will
+individually obtain patent licenses, in effect making the program proprietary.
+To prevent this, we have made it clear that any patent must be licensed for
+everyone's free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and modification
+follow.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License applies to any program or other work which contains a notice
+placed by the copyright holder saying it may be distributed under the terms of
+this General Public License.  The "Program", below, refers to any such program
+or work, and a "work based on the Program" means either the Program or any
+derivative work under copyright law: that is to say, a work containing the
+Program or a portion of it, either verbatim or with modifications and/or
+translated into another language.  (Hereinafter, translation is included
+without limitation in the term "modification".) Each licensee is addressed as
+"you".
+
+Activities other than copying, distribution and modification are not covered by
+this License; they are outside its scope.  The act of running the Program is
+not restricted, and the output from the Program is covered only if its contents
+constitute a work based on the Program (independent of having been made by
+running the Program).  Whether that is true depends on what the Program does.
+
+1. You may copy and distribute verbatim copies of the Program's source code as
+you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this License
+and to the absence of any warranty; and give any other recipients of the
+Program a copy of this License along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and you may
+at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Program or any portion of it, thus
+forming a work based on the Program, and copy and distribute such modifications
+or work under the terms of Section 1 above, provided that you also meet all of
+these conditions:
+
+    a) You must cause the modified files to carry prominent notices stating
+    that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in whole or
+    in part contains or is derived from the Program or any part thereof, to be
+    licensed as a whole at no charge to all third parties under the terms of
+    this License.
+
+    c) If the modified program normally reads commands interactively when run,
+    you must cause it, when started running for such interactive use in the
+    most ordinary way, to print or display an announcement including an
+    appropriate copyright notice and a notice that there is no warranty (or
+    else, saying that you provide a warranty) and that users may redistribute
+    the program under these conditions, and telling the user how to view a copy
+    of this License.  (Exception: if the Program itself is interactive but does
+    not normally print such an announcement, your work based on the Program is
+    not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If identifiable
+sections of that work are not derived from the Program, and can be reasonably
+considered independent and separate works in themselves, then this License, and
+its terms, do not apply to those sections when you distribute them as separate
+works.  But when you distribute the same sections as part of a whole which is a
+work based on the Program, the distribution of the whole must be on the terms
+of this License, whose permissions for other licensees extend to the entire
+whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise the
+right to control the distribution of derivative or collective works based on
+the Program.
+
+In addition, mere aggregation of another work not based on the Program with the
+Program (or with a work based on the Program) on a volume of a storage or
+distribution medium does not bring the other work under the scope of this
+License.
+
+3. You may copy and distribute the Program (or a work based on it, under
+Section 2) in object code or executable form under the terms of Sections 1 and
+2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable source
+    code, which must be distributed under the terms of Sections 1 and 2 above
+    on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three years, to
+    give any third party, for a charge no more than your cost of physically
+    performing source distribution, a complete machine-readable copy of the
+    corresponding source code, to be distributed under the terms of Sections 1
+    and 2 above on a medium customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer to
+    distribute corresponding source code.  (This alternative is allowed only
+    for noncommercial distribution and only if you received the program in
+    object code or executable form with such an offer, in accord with
+    Subsection b above.)
+
+The source code for a work means the preferred form of the work for making
+modifications to it.  For an executable work, complete source code means all
+the source code for all modules it contains, plus any associated interface
+definition files, plus the scripts used to control compilation and installation
+of the executable.  However, as a special exception, the source code
+distributed need not include anything that is normally distributed (in either
+source or binary form) with the major components (compiler, kernel, and so on)
+of the operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the source
+code from the same place counts as distribution of the source code, even though
+third parties are not compelled to copy the source along with the object code.
+
+4. You may not copy, modify, sublicense, or distribute the Program except as
+expressly provided under this License.  Any attempt otherwise to copy, modify,
+sublicense or distribute the Program is void, and will automatically terminate
+your rights under this License.  However, parties who have received copies, or
+rights, from you under this License will not have their licenses terminated so
+long as such parties remain in full compliance.
+
+5. You are not required to accept this License, since you have not signed it.
+However, nothing else grants you permission to modify or distribute the Program
+or its derivative works.  These actions are prohibited by law if you do not
+accept this License.  Therefore, by modifying or distributing the Program (or
+any work based on the Program), you indicate your acceptance of this License to
+do so, and all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+6. Each time you redistribute the Program (or any work based on the Program),
+the recipient automatically receives a license from the original licensor to
+copy, distribute or modify the Program subject to these terms and conditions.
+You may not impose any further restrictions on the recipients' exercise of the
+rights granted herein.  You are not responsible for enforcing compliance by
+third parties to this License.
+
+7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues), conditions
+are imposed on you (whether by court order, agreement or otherwise) that
+contradict the conditions of this License, they do not excuse you from the
+conditions of this License.  If you cannot distribute so as to satisfy
+simultaneously your obligations under this License and any other pertinent
+obligations, then as a consequence you may not distribute the Program at all.
+For example, if a patent license would not permit royalty-free redistribution
+of the Program by all those who receive copies directly or indirectly through
+you, then the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply and
+the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents or
+other property right claims or to contest validity of any such claims; this
+section has the sole purpose of protecting the integrity of the free software
+distribution system, which is implemented by public license practices.  Many
+people have made generous contributions to the wide range of software
+distributed through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing to
+distribute software through any other system and a licensee cannot impose that
+choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+8. If the distribution and/or use of the Program is restricted in certain
+countries either by patents or by copyrighted interfaces, the original
+copyright holder who places the Program under this License may add an explicit
+geographical distribution limitation excluding those countries, so that
+distribution is permitted only in or among countries not thus excluded.  In
+such case, this License incorporates the limitation as if written in the body
+of this License.
+
+9. The Free Software Foundation may publish revised and/or new versions of the
+General Public License from time to time.  Such new versions will be similar in
+spirit to the present version, but may differ in detail to address new problems
+or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any later
+version", you have the option of following the terms and conditions either of
+that version or of any later version published by the Free Software Foundation.
+If the Program does not specify a version number of this License, you may
+choose any version ever published by the Free Software Foundation.
+
+10. If you wish to incorporate parts of the Program into other free programs
+whose distribution conditions are different, write to the author to ask for
+permission.  For software which is copyrighted by the Free Software Foundation,
+write to the Free Software Foundation; we sometimes make exceptions for this.
+Our decision will be guided by the two goals of preserving the free status of
+all derivatives of our free software and of promoting the sharing and reuse of
+software generally.
+
+NO WARRANTY
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN OTHERWISE
+STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE
+PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND
+PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE,
+YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
+ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE
+PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
+INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
+BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER
+OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+
+If you develop a new program, and you want it to be of the greatest possible
+use to the public, the best way to achieve this is to make it free software
+which everyone can redistribute and change under these terms.
+
+To do so, attach the following notices to the program.  It is safest to attach
+them to the start of each source file to most effectively convey the exclusion
+of warranty; and each file should have at least the "copyright" line and a
+pointer to where the full notice is found.
+
+    One line to give the program's name and a brief idea of what it does.
+
+    Copyright (C) <year> <name of author>
+
+    This program is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the Free
+    Software Foundation; either version 2 of the License, or (at your option)
+    any later version.
+
+    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., 59
+    Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this when it
+starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author Gnomovision comes
+    with ABSOLUTELY NO WARRANTY; for details type 'show w'.  This is free
+    software, and you are welcome to redistribute it under certain conditions;
+    type 'show c' for details.
+
+The hypothetical commands 'show w' and 'show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may be
+called something other than 'show w' and 'show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.  Here
+is a sample; alter the names:
+
+    Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+    'Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+    signature of Ty Coon, 1 April 1989
+
+    Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General Public
+License instead of this License.
+
+
+"CLASSPATH" EXCEPTION TO THE GPL
+
+Certain source files distributed by Sun Microsystems, Inc.  are subject to
+the following clarification and special exception to the GPL, but only where
+Sun has expressly included in the particular source file's header the words
+"Sun designates this particular file as subject to the "Classpath" exception
+as provided by Sun in the LICENSE file that accompanied this code."
+
+    Linking this library statically or dynamically with other modules is making
+    a combined work based on this library.  Thus, the terms and conditions of
+    the GNU General Public License cover the whole combination.
+
+    As a special exception, the copyright holders of this library give you
+    permission to link this library with independent modules to produce an
+    executable, regardless of the license terms of these independent modules,
+    and to copy and distribute the resulting executable under terms of your
+    choice, provided that you also meet, for each linked independent module,
+    the terms and conditions of the license of that module.  An independent
+    module is a module which is not derived from or based on this library.  If
+    you modify this library, you may extend this exception to your version of
+    the library, but you are not obligated to do so.  If you do not wish to do
+    so, delete this exception statement from your version.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/bin/com/sun/c1x/doc/IRInterpreter.txt	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,26 @@
+Current status and remaining issues in the IRInterpreter for HIR (September/18/09)
+=================================================================================
+
+Known Problems:
+With InterpretInvokedMethods disabled in C1XOptions:
+(2 fails)
+304: jtt/jvmni/JVM_GetClassContext01.java: (0) failed with false (expected true)
+557: jtt/reflect/Class_newInstance02.java: (0) failed with true (expected !java.lang.IllegalAccessException)
+
+The first problem is caused by the use of reflection in the IRInterpreter, and the calling stack is not as 
+expected by the JVM_GetClassContext01 test case. The second one is due to the private constructor of Class_newInstance01.
+Again, we are using reflection to call the newInstance() method to create an instance of class Class_newInstance01
+from the IRInterpreter class, which raises an IllegalAccessException.
+These are the only problems with all optimization levels.
+
+With InterpretInvokedMethods enabled in C1XOptions:
+(7 fails)
+245: jtt/except/Catch_StackOverflowError_03.java: (0) failed with !java.lang.InstantiationException (expected 0)
+304: jtt/jvmni/JVM_GetClassContext01.java: (0) failed with false (expected true)
+311: jtt/lang/Bridge_method01.java: (0) failed with unexpected com.sun.c1x.ci.CiBailout (expected 1)
+557: jtt/reflect/Class_newInstance02.java: (0) failed with true (expected !java.lang.IllegalAccessException)
+572: jtt/reflect/Invoke_virtual01.java: (1) failed with unexpected com.sun.c1x.ci.CiBailout (expected 55)
+575: jtt/reflect/Reflection_getCallerClass01.java: (1) failed with com.sun.c1x.debug.IRInterpreter$Evaluator (expected jtt.reflect.Reflection_getCallerClass01$Caller1)
+592: jtt/threads/Thread_isInterrupted04.java: (0) failed with false (expected true)
+
+Those are also due to reflection usage. The last problem has not been investigated.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/bin/com/sun/c1x/doc/LoopPeeling.txt	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,43 @@
+Remaining Issues in the Loop Peeling optimization (September/18/09)
+===================================================================
+
+Known Problems:
+Currently loop peeling is not working when the loop has exception
+blocks. The algorithm has to be updated to handle these cases.
+
+Limitations:
+The algorithm performs loop peeling only on innermost loops. However,
+this is not a limitation. If one wants to peel the outermost loop(s),
+after peeling the innermost loop, an additional pass is necessary
+to update the blocks of the outermost loop, since after peeling
+the innermost loop, newer blocks are added to the CFG.
+
+Current status as of 09/18/2009
+After running using hir configuration, with optimization level 3, the
+following test cases produce wrong results:
+(4 fails)
+233: jtt/except/Catch_Loop01.java: (4) failed with unexpected com.sun.c1x.ci.CiBailout (expected -170)
+234: jtt/except/Catch_Loop02.java: (4) failed with unexpected com.sun.c1x.ci.CiBailout (expected -170)
+245: jtt/except/Catch_StackOverflowError_03.java: (0) failed with unexpected com.sun.c1x.ci.CiBailout (expected 0)
+272: jtt/hotpath/HP_array04.java: (80) failed with unexpected java.lang.AssertionError (expected 15645)
+
+All of them are related the known problem aforementioned.
+All the tests have the innermost loops peeled, and produce right results.
+
+Future Work:
+1- Add more loop tests to jtt. New tests should run the loop 0, 1, 2 or more iterations.
+
+2- Peel loops with exception blocks. 
+
+3- Currently, all innermost loops are peeled. Should we add logic to filter out some loops from loop peeling?
+
+4- Improve the way instructions are cloned. Now the algorithm visits the blocks in BFS order, which
+might produce errors depending on the order the blocks are visited.
+
+5- After inserting new phi instructions at exit blocks, we need to iterate over the remaining CFG to update instructions
+that may use the new phi. The way it's done now might me inefficient if the block has more than one exit node, since
+we can iterate over the same block more than once. This needs to be improved.
+
+5- For performance reasons, improve the way loops are represented, for example, to use a bitmap to represent the loop blocks.
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/bin/com/sun/c1x/doc/backend_open_issues.txt	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,22 @@
+Remaining Issues in the C1X backend (after the port July-Sep 09)
+======================================================================
+
+Maxine/Inspector Related Open Issues:
+   - Global stubs: Change calling convention (no longer write to callee stack as this makes stepping through the instructions for saving the parameters to global stubs impossible in the inspector)
+   - Reference maps: Corrently implement TargetMethod.prepareReferenceMap for C1XTargetMethod (checking for the need to stack walk a possible callee saved target method) and call it from Maxine
+   - Disassembler: The Maxine disassembler still does not correctly display every machine code instruction issued by C1X
+   - MaxRiRuntime and C1XTargetMethod have fixed dependencies on the X86 parts (instruction decoding, registers, calling convention), should be factored out
+
+Compile-Time Performance Improvements:
+   - Consider deleting the LIRItem class
+   - Make sure that LIROperand objects are not shared among LIR instructions and can therefore be directly modified by the LinearScan register allocator (no more need for the lazy creation of LIRAddress objects in the LIRInstruction class)
+   
+Run-Time Performance Improvements:
+   - Store mapping between machine code location and bytecode index in the target method (remove arguments from global stub calls), this decreases the number of necessary parameters especially for resolution instructions.
+   - Use Inline Cache on virtual method calls
+
+Better Portability:
+   - Integrate XIR; consider using CiLocation / CiConstant in XIR
+   - The JIT adapter frames should be a more general mechanism that receives two calling conventions (in form of an array of locations) and adapts between them automatically
+   - Have the possibility to register intrinsics by specifying XIR code
+   
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/bin/com/sun/c1x/doc/differences.txt	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,154 @@
+Differences between C1 and C1X, including upgrades and limitations
+(and some general information about C1)
+======================================================================
+
+StrictFP:
+   - C1X has removed the backend code to deal with the FPU stack, and therefore
+     requires SSE2 currently. StrictFP is still tracked in the front end.
+   - C1 will not inline methods with different strictfp-ness. C1X does not have this
+     limitation because it only targets SSE2 x86 processors.
+
+JSR/RET
+   - C1 will bail out if it encounters strange JSR/RET patterns
+       - recursive JSRs
+       - JSR regions that are shared with non-JSR code
+       - RET encountered out of JSR (would not verify)
+
+Exceptions
+   -  C1 will bailout if the code of an exception handler can be reached via normal
+      control flow.
+   => C1X might be extended to introduce a phi for the exception
+      object in this case.
+   -  C1 will bailout if an exception handler covers itself
+
+Verification
+   -  C1 does not rely on bytecode verification having been run. However, if it detects
+      type errors in its building the IR graph it will usually bail out.
+   -  C1 requires a bitmap of the bytecode, where a bit for
+      each byte of the bytecode indicates if the bytecode at that location starts a
+      basic block. It uses this to construct the basic block list in a single pass.
+   => Assertion failures and/or bugs in C1X that cause exceptions to be thrown bail out
+      the compilation instead of crashing the VM.
+   => C1X's BlockMap does not computes the basic block starts in one pass over the bytecode
+      and one pass over the successor lists.
+   => C1X computes the "stores in loops" only when loops are encountered in the CFG.
+      An option can select conservative mode (all locals stored in all loops) trades
+      faster parse speed for fewer optimization opportunities
+   => C1X includes an IRChecker that typechecks the entire IR and checks for CFG
+      consistency that can be run after each pass.
+
+Constants
+   => C1X allows unrestricted use of object constants throughout the code, including
+      folding reads of static final fields that reference objects.
+
+Pinning
+   => C1X pins fewer instructions than C1
+   ** C1X will eventually allow certain kinds of instructions to float outside the CFG
+      and be scheduled with a C2-lite scheduling pass.
+
+Synchronization
+   -  C1 will refuse to compile methods with unbalanced synchronization. This property is
+      computed by the bytecode verifier and supplied to C1.
+   ** C1X will not rely on the bytecode verifier to compute this but should do so itself.
+   => C1 relied on the backend to generate synchronization code for the root method's
+      synchronization operations. C1X inserts code into the start block and generates
+      and exception handler to do this explicitly.
+
+Optimizations
+   => C1X has many more options to turn on individual passes, parts of passes, approximations,
+      etc. It is designed to have three optimization levels:
+      0 = super-fast: essentially no optimization
+      1 = fast:       inlining, constant folding, and local optimizations
+      2 = optimized:  inlining, constant folding, local and global optimizations, including
+                      iterative versions of all algorithms
+   ** Planned optimizations for C1X that C1 does not have:
+      TypeCheckElimination:        remove redundant casts and devirtualize more call sites
+      ArrayBoundsCheckElimination: remove redundant array bounds checks and/or restructure
+                                   code to deoptimize when bounds checks within loops will fail
+      LoopPeeling:                 replicate the first iteration of a loop
+      LoopUnrolling:               replicate the body of certain shapes of loops
+      LoopInvariantCodeMotion:     move invariant code out of a loop
+      ProfileGuidedInlining:       use receiver method profiles to emit guarded inlines
+      ProfileGuidedBlockLayout:    use profiling information for code placement
+      Peephole:                    peephole optimize backend output
+
+Block Merging
+   ** C1X will replace branches to blocks with a single Goto with a branch to the
+      block's successor, if the blocks cannot be merged otherwise.
+
+Constant Folding / Strength reduction
+   -  C1 had some of its strength reduction logic built into the GraphBuilder because
+      the Canonicalizer could not return multiple instructions.
+   => C1X added this ability, moved the logic to Canonicalizer, and added a few new
+      strength reductions.
+   => C1X should have an interface for doing folding of @FOLD method calls
+   => C1X folds many intrinsic operations that don't have side effects
+   => C1X folds all the basic floating point operations
+   => C1X strength reduces (e >> C >> K) to (e >> (C + K)) when C and K are constant
+   => Multiplies of power-of-2 constants are reduced to shifts in the canonicalizer
+      (instead of the backend)
+   ** C1X will be able to run a global sparse conditional constant propagation phase
+      to catch any missed canonicalization opportunities after graph building.
+
+Switches
+   -  C1 did not detect back edges in tableswitch/lookupswitch default branches
+   => C1X does detect these back edges
+   => C1X moved the canonicalization code of 1 and 2 branch switches to canonicalizer,
+      where it belongs
+
+Inlining
+   -  C1 cannot inline:
+      -  native methods (or their stubs), except some intrinsics
+      -  methods whose class has not been initialized
+      -  methods with unbalanced monitors
+      -  methods with JSRs (this is probably technically possible now)
+
+   -  C1 will not inline:
+      -  methods with exception handlers (optional)
+      -  synchronized methods (optional)
+      -  if the maximum inline depth is reached (default = 9)
+      -  if the maximum recursive inline depth is reached (default = 1)
+      -  if the callee is larger than the maximum inline size (reduced to 90% at each level, starting at 35)
+      -  constructors for subclasses of Throwable
+      -  if the strictfp-ness of the callee is different than the caller (on x87)
+      -  abstract methods
+      -  synchronized intrinsics
+
+Load/store elimination
+   => C1X may eliminate loads of static fields, which C1 did not
+   => C1X distinguishes loads/stores to different fields in MemoryBuffer
+   => C1X assumes that RiField instances are unique when .isLoaded() is true
+
+Local/Global Value Numbering
+   => C1X improved local load elimination and no longer value numbers fields, reducing the
+      logic necessary in ValueMap, simplifying it and improving its performance.
+   => C1X reuses the same simplified ValueMap for GVN. Since heap accesses are no longer
+      value numbered, the logic to kill values is unnecessary, greatly simplifying
+      GVN.
+   ** A global version of load elimination will compensate for this loss in the future.
+   => C1X value numbers are always or'd with a high order bit when value numbering is possible
+      to prevent value numbering failing if the value number is accidentally 0.
+
+Nullcheck elimination
+   => A new flag, NonNull, indicates instructions that produce values that are guaranteed
+      to be non-null (e.g. NewXXX and Local 0, NullCheck). Instructions that require null
+      checks check this flag for their inputs in their constructors, eliminating most
+      redundant null checks immediately, without requiring the NullCheckEliminator to run.
+   => C1X uses a more efficient block ordering for null check elimination. The first pass is
+      optimistic and attempts to visit the blocks in reverse post-order. For acyclic graphs,
+      this almost always succeeds, requiring no iteration. Full iterative data flow analysis
+      can be enabled separately. Bitmaps used during the fixpoint calculation are much
+      smaller due to local numbering of instructions (as opposed to global IDs).
+   ** C1X will recognize If's that check against null and propagate the non-nullness across
+      the appropriate branches.
+
+BlockListBuilder
+   -  C1 had a vestigial loop map in BlockListBuilder which was not really used.
+   => C1X does not need to compute a complete loop map in order to do selective phi creation,
+      it builds the "storesInLoops" BitMap in BlockMap.
+
+Types
+   => C1X adds the declared type of method parameters to Local instructions, which
+      may help with devirtualization
+   => C1X makes local 0 of instance methods non-null at the start
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/bin/com/sun/c1x/doc/performance.txt	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,85 @@
+Issues that can be addressed for improving performance in C1X
+----------------------------------------------------------------
+
+- indicates not done
+* indicates done
+
+Backend:
+	- better handling of constants, especially immediates
+	- (non XIR) checkcast, instanceof: use nullity
+	- (non XIR) checkcast, instanceof: emit fastpath direct compare
+	- use LEA instruction on x86
+	- recognize pointer arithmetic addressing modes
+	- recognize multiply by 3, 5, 9 and emit lea rk, [rs, rs*2], etc
+	- Maxine XIR: make direct runtime calls instead of through global stub
+	- Maxine XIR: implement inline allocation
+	- Maxine XIR: implement biased locking fastpath
+	- Maxine XIR: faster subtype checks for classes, leaves
+	- Maxine XIR: make use of XirSite nullity, range check information
+	- better handling of tableswitch bytecode
+	- better handling of two operand LIR form
+	- Make the following bytecode implementations inline:
+		- f2i f2l f2d d2i d2l d2f (SSE2)
+		* lrem ldiv (64 bit)
+		- fneg dneg
+	- Make the following bytecode implementations global stubs:
+		- frem drem
+	- Global stubs: use EAX for return value as normal instead of [rsp - 16]
+    - Emit direct call to runtime for new instance, monitorenter, monitorexit
+
+	* XIR: expose nullity, range checkness across XIR interface
+	- XIR: make use of CSE'd array length
+	- XIR: generate special if-instanceof XIR variant with label parameters
+    - Optimize special cases of bytecodes:
+        - (MIN_INT / -1) in IDIV,IREM
+        - (MIN_LONG / -1) in LDIV,LREM
+        - (-infinity, Nan, +infinity) in F2I, F2L, D2I, D2L
+
+
+Frontend:
+    - Remove redundant null check branches in NullCheckEliminator
+	- XIR: implement HIR -> HIR xir translation
+	- Refactor exception edges to allow removal, optimization
+	- Implement typecast elimination
+	- Implement constant propagation
+	- Implement GVN of memory loads / stores
+	- Implement memory reordering
+	- Implement loop invariant code motion
+	- Optimize endianness conversions and endian-writes
+	      (e.g. (x >> 24 & 0xff) | (....)) and a[0] = x >> 24 ...
+	- Finish loop peeling
+	- Implement loop unrolling
+	- Allow value numbering of constant loads
+	- Finish loop peeling
+	- Guarded and multiple inlining
+	- Maxine: speculative leaf class and leaf method assumption
+	- Maxine: adjust static / dynamic inlining heuristics
+		  (e.g. static: trivial methods only in cold spots)
+    - Aggressive optimization of array copy
+
+Compilation speed:
+    - Make special iterators for LIROperand input, temp, output
+    - Add analysisInfo field to Value and use in NullCheckEliminator
+	- Remove RiConstantPool, cpi from unresolved HIR instructions (move to RiField, RiMethod)
+	- Use BlockList instead of ArrayList<Block> where appropriate
+	- Use FrameState instead of ValueStack
+	- Remove exceptionHandlers, make DebugInfo hold FrameState, CiCodePos,
+		exception flags and exception handlers
+	- Clean up and simplify LIRInstruction constructor
+	- Create fewer LIRAddresses
+	- Simplify LIRGenerator logic (forcing of loading, etc)
+	- LIROperand: split into virtual register table?
+	- Cleanup assembler and remove dead code, useless assertions
+	- Chain assembler byte buffers and only assemble at the end
+	- Pick optimal initial assembler byte buffer size
+	- Pick good initial sizes for LinearScan data structures
+	- Remove unnecessary uses of ArrayList and replace with arrays or other list
+	- Use iteration over ArrayList instead of explicit loop
+	- Revisit manual editing / removal of items from ArrayList
+	- Remove non-XIR backend
+	- Pre-assemble XIR for backend
+
+	* Initialize compilation-unique instruction id's lazily with thread local compilation
+	* Remove dead LIROpcodes
+	* Remove dead code in LIRGenerator, X86LIRGenerator, LIRAssembler, X86LIRAssembler
+		(remove commented out code)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/src/com/sun/c1x/C1XCompilation.java	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.c1x;
+
+import java.util.*;
+
+import com.sun.c1x.alloc.*;
+import com.sun.c1x.asm.*;
+import com.sun.c1x.gen.*;
+import com.sun.c1x.gen.LIRGenerator.DeoptimizationStub;
+import com.sun.c1x.graph.*;
+import com.sun.c1x.ir.*;
+import com.sun.c1x.lir.*;
+import com.sun.c1x.observer.*;
+import com.sun.c1x.value.*;
+import com.sun.cri.bytecode.*;
+import com.sun.cri.ci.*;
+import com.sun.cri.ri.*;
+
+/**
+ * This class encapsulates global information about the compilation of a particular method,
+ * including a reference to the runtime, statistics about the compiled code, etc.
+ *
+ * @author Ben L. Titzer
+ */
+public final class C1XCompilation {
+
+    private static ThreadLocal<C1XCompilation> currentCompilation = new ThreadLocal<C1XCompilation>();
+
+    public final C1XCompiler compiler;
+    public final CiTarget target;
+    public final RiRuntime runtime;
+    public final RiMethod method;
+    public final RiRegisterConfig registerConfig;
+    public final CiStatistics stats;
+    public final int osrBCI;
+    public final CiAssumptions assumptions = new CiAssumptions();
+    public final FrameState placeholderState;
+
+    private boolean hasExceptionHandlers;
+    private final C1XCompilation parent;
+
+    /**
+     * @see #setNotTypesafe()
+     * @see #isTypesafe()
+     */
+    private boolean typesafe = true;
+
+    private int nextID = 1;
+
+    private FrameMap frameMap;
+    private AbstractAssembler assembler;
+
+    private IR hir;
+
+    private LIRGenerator lirGenerator;
+
+    /**
+     * Creates a new compilation for the specified method and runtime.
+     *
+     * @param compiler the compiler
+     * @param method the method to be compiled or {@code null} if generating code for a stub
+     * @param osrBCI the bytecode index for on-stack replacement, if requested
+     * @param stats externally supplied statistics object to be used if not {@code null}
+     */
+    public C1XCompilation(C1XCompiler compiler, RiMethod method, int osrBCI, CiStatistics stats) {
+        this.parent = currentCompilation.get();
+        currentCompilation.set(this);
+        this.compiler = compiler;
+        this.target = compiler.target;
+        this.runtime = compiler.runtime;
+        this.method = method;
+        this.osrBCI = osrBCI;
+        this.stats = stats == null ? new CiStatistics() : stats;
+        this.registerConfig = method == null ? compiler.globalStubRegisterConfig : runtime.getRegisterConfig(method);
+        this.placeholderState = method != null && method.minimalDebugInfo() ? new MutableFrameState(new IRScope(null, null, method, -1), 0, 0, 0) : null;
+
+        if (compiler.isObserved()) {
+            compiler.fireCompilationStarted(new CompilationEvent(this));
+        }
+    }
+
+    public void close() {
+        currentCompilation.set(parent);
+    }
+
+    public IR hir() {
+        return hir;
+    }
+
+    /**
+     * Records that this compilation has exception handlers.
+     */
+    public void setHasExceptionHandlers() {
+        hasExceptionHandlers = true;
+    }
+
+    /**
+     * Records that this compilation encountered an instruction (e.g. {@link Bytecodes#UNSAFE_CAST})
+     * that breaks the type safety invariant of the input bytecode.
+     */
+    public void setNotTypesafe() {
+        typesafe = false;
+    }
+
+    /**
+     * Checks whether this compilation is for an on-stack replacement.
+     *
+     * @return {@code true} if this compilation is for an on-stack replacement
+     */
+    public boolean isOsrCompilation() {
+        return osrBCI >= 0;
+    }
+
+    /**
+     * Translates a given kind to a canonical architecture kind.
+     * This is an identity function for all but {@link CiKind#Word}
+     * which is translated to {@link CiKind#Int} or {@link CiKind#Long}
+     * depending on whether or not this is a {@linkplain #is64Bit() 64-bit}
+     * compilation.
+     */
+    public CiKind archKind(CiKind kind) {
+        if (kind.isWord()) {
+            return target.arch.is64bit() ? CiKind.Long : CiKind.Int;
+        }
+        return kind;
+    }
+
+    /**
+     * Determines if two given kinds are equal at the {@linkplain #archKind(CiKind) architecture} level.
+     */
+    public boolean archKindsEqual(CiKind kind1, CiKind kind2) {
+        return archKind(kind1) == archKind(kind2);
+    }
+
+    /**
+     * Gets the frame which describes the layout of the OSR interpreter frame for this method.
+     *
+     * @return the OSR frame
+     */
+    public RiOsrFrame getOsrFrame() {
+        return runtime.getOsrFrame(method, osrBCI);
+    }
+
+    /**
+     * Records an assumption that the specified type has no finalizable subclasses.
+     *
+     * @param receiverType the type that is assumed to have no finalizable subclasses
+     * @return {@code true} if the assumption was recorded and can be assumed; {@code false} otherwise
+     */
+    public boolean recordNoFinalizableSubclassAssumption(RiType receiverType) {
+        return false;
+    }
+
+    /**
+     * Converts this compilation to a string.
+     *
+     * @return a string representation of this compilation
+     */
+    @Override
+    public String toString() {
+        if (isOsrCompilation()) {
+            return "osr-compile @ " + osrBCI + ": " + method;
+        }
+        return "compile: " + method;
+    }
+
+    /**
+     * Builds the block map for the specified method.
+     *
+     * @param method the method for which to build the block map
+     * @param osrBCI the OSR bytecode index; {@code -1} if this is not an OSR
+     * @return the block map for the specified method
+     */
+    public BlockMap getBlockMap(RiMethod method, int osrBCI) {
+        // PERF: cache the block map for methods that are compiled or inlined often
+        BlockMap map = new BlockMap(method, hir.numberOfBlocks());
+        boolean isOsrCompilation = false;
+        if (osrBCI >= 0) {
+            map.addEntrypoint(osrBCI, BlockBegin.BlockFlag.OsrEntry);
+            isOsrCompilation = true;
+        }
+        if (!map.build(!isOsrCompilation && C1XOptions.PhiLoopStores)) {
+            throw new CiBailout("build of BlockMap failed for " + method);
+        } else {
+            if (compiler.isObserved()) {
+                String label = CiUtil.format("BlockListBuilder %f %r %H.%n(%p)", method, true);
+                compiler.fireCompilationEvent(new CompilationEvent(this, label, map, method.code().length));
+            }
+        }
+        map.cleanup();
+        stats.bytecodeCount += map.numberOfBytes();
+        stats.blockCount += map.numberOfBlocks();
+        return map;
+    }
+
+    /**
+     * Returns the frame map of this compilation.
+     * @return the frame map
+     */
+    public FrameMap frameMap() {
+        return frameMap;
+    }
+
+    public AbstractAssembler masm() {
+        if (assembler == null) {
+            assembler = compiler.backend.newAssembler(registerConfig);
+            assembler.setFrameSize(frameMap.frameSize());
+            assembler.targetMethod.setCustomStackAreaOffset(frameMap.offsetToCustomArea());
+        }
+        return assembler;
+    }
+
+    public boolean hasExceptionHandlers() {
+        return hasExceptionHandlers;
+    }
+
+    /**
+     * Determines if this compilation has encountered any instructions (e.g. {@link Bytecodes#UNSAFE_CAST})
+     * that break the type safety invariant of the input bytecode.
+     */
+    public boolean isTypesafe() {
+        return typesafe;
+    }
+
+    public CiResult compile() {
+        CiTargetMethod targetMethod;
+        try {
+            emitHIR();
+            emitLIR();
+            targetMethod = emitCode();
+
+            if (C1XOptions.PrintMetrics) {
+                C1XMetrics.BytecodesCompiled += method.code().length;
+            }
+        } catch (CiBailout b) {
+            return new CiResult(null, b, stats);
+        } catch (Throwable t) {
+            return new CiResult(null, new CiBailout("Exception while compiling: " + method, t), stats);
+        } finally {
+            if (compiler.isObserved()) {
+                compiler.fireCompilationFinished(new CompilationEvent(this));
+            }
+        }
+
+        return new CiResult(targetMethod, null, stats);
+    }
+
+    public IR emitHIR() {
+        hir = new IR(this);
+        hir.build();
+        return hir;
+    }
+
+    public void initFrameMap(int numberOfLocks) {
+        frameMap = this.compiler.backend.newFrameMap(method, numberOfLocks);
+    }
+
+    private void emitLIR() {
+        if (C1XOptions.GenLIR) {
+            if (C1XOptions.PrintTimers) {
+                C1XTimers.LIR_CREATE.start();
+            }
+
+            initFrameMap(hir.topScope.maxLocks());
+
+            lirGenerator = compiler.backend.newLIRGenerator(this);
+            for (BlockBegin begin : hir.linearScanOrder()) {
+                lirGenerator.doBlock(begin);
+            }
+
+            if (C1XOptions.PrintTimers) {
+                C1XTimers.LIR_CREATE.stop();
+            }
+
+            new LinearScan(this, hir, lirGenerator, frameMap()).allocate();
+        }
+    }
+
+    private CiTargetMethod emitCode() {
+        if (C1XOptions.GenLIR && C1XOptions.GenCode) {
+            final LIRAssembler lirAssembler = compiler.backend.newLIRAssembler(this);
+            lirAssembler.emitCode(hir.linearScanOrder());
+
+            // generate code for slow cases
+            lirAssembler.emitLocalStubs();
+
+            // generate exception adapters
+            lirAssembler.emitExceptionEntries();
+
+            // generate deoptimization stubs
+            ArrayList<DeoptimizationStub> deoptimizationStubs = lirGenerator.deoptimizationStubs();
+            if (deoptimizationStubs != null) {
+                for (DeoptimizationStub stub : deoptimizationStubs) {
+                    lirAssembler.emitDeoptizationStub(stub);
+                }
+            }
+
+            // generate traps at the end of the method
+            lirAssembler.emitTraps();
+
+            CiTargetMethod targetMethod = masm().finishTargetMethod(method, runtime, lirAssembler.registerRestoreEpilogueOffset, false);
+            if (assumptions.count() > 0) {
+                targetMethod.setAssumptions(assumptions);
+            }
+
+            if (compiler.isObserved()) {
+                compiler.fireCompilationEvent(new CompilationEvent(this, "After code generation", hir.startBlock, false, true, targetMethod));
+            }
+
+            if (C1XOptions.PrintTimers) {
+                C1XTimers.CODE_CREATE.stop();
+            }
+            return targetMethod;
+        }
+
+        return null;
+    }
+
+    public int nextID() {
+        return nextID++;
+    }
+
+    public static C1XCompilation compilation() {
+        C1XCompilation compilation = currentCompilation.get();
+        assert compilation != null;
+        return compilation;
+    }
+
+    public static C1XCompilation compilationOrNull() {
+        return currentCompilation.get();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/src/com/sun/c1x/C1XCompiler.java	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.c1x;
+
+import java.util.*;
+
+import com.sun.c1x.debug.*;
+import com.sun.c1x.globalstub.*;
+import com.sun.c1x.observer.*;
+import com.sun.c1x.target.*;
+import com.sun.cri.ci.*;
+import com.sun.cri.ri.*;
+import com.sun.cri.xir.*;
+
+/**
+ * This class implements the compiler interface for C1X.
+ *
+ * @author Thomas Wuerthinger
+ * @author Ben L. Titzer
+ */
+public class C1XCompiler extends ObservableCompiler {
+
+    public final Map<Object, GlobalStub> stubs = new HashMap<Object, GlobalStub>();
+
+    /**
+     * The target that this compiler has been configured for.
+     */
+    public final CiTarget target;
+
+    /**
+     * The runtime that this compiler has been configured for.
+     */
+    public final RiRuntime runtime;
+
+    /**
+     * The XIR generator that lowers Java operations to machine operations.
+     */
+    public final RiXirGenerator xir;
+
+    /**
+     * The ordered set of compiler extensions.
+     */
+    public List<C1XCompilerExtension> extensions;
+
+    /**
+     * The backend that this compiler has been configured for.
+     */
+    public final Backend backend;
+
+    public final RiRegisterConfig globalStubRegisterConfig;
+
+    public C1XCompiler(RiRuntime runtime, CiTarget target, RiXirGenerator xirGen, RiRegisterConfig globalStubRegisterConfig) {
+        this.runtime = runtime;
+        this.target = target;
+        this.xir = xirGen;
+        this.globalStubRegisterConfig = globalStubRegisterConfig;
+        this.backend = Backend.create(target.arch, this);
+        init();
+    }
+
+    public CiResult compileMethod(RiMethod method, int osrBCI, RiXirGenerator xirGenerator, CiStatistics stats) {
+        long startTime = 0;
+        int index = C1XMetrics.CompiledMethods++;
+        if (C1XOptions.PrintCompilation) {
+            TTY.print(String.format("C1X %4d %-70s %-45s | ", index, method.holder().name(), method.name()));
+            startTime = System.nanoTime();
+        }
+
+        CiResult result = null;
+        TTY.Filter filter = new TTY.Filter(C1XOptions.PrintFilter, method);
+        C1XCompilation compilation = new C1XCompilation(this, method, osrBCI, stats);
+        try {
+            result = compilation.compile();
+        } finally {
+            filter.remove();
+            compilation.close();
+            if (C1XOptions.PrintCompilation && !TTY.isSuppressed()) {
+                long time = (System.nanoTime() - startTime) / 100000;
+                TTY.println(String.format("%3d.%dms", time / 10, time % 10));
+            }
+        }
+
+        return result;
+    }
+
+    private void init() {
+        final List<XirTemplate> xirTemplateStubs = xir.buildTemplates(backend.newXirAssembler());
+        final GlobalStubEmitter emitter = backend.newGlobalStubEmitter();
+
+        if (xirTemplateStubs != null) {
+            for (XirTemplate template : xirTemplateStubs) {
+                TTY.Filter filter = new TTY.Filter(C1XOptions.PrintFilter, template.name);
+                try {
+                    stubs.put(template, emitter.emit(template, runtime));
+                } finally {
+                    filter.remove();
+                }
+            }
+        }
+
+        for (GlobalStub.Id id : GlobalStub.Id.values()) {
+            TTY.Filter suppressor = new TTY.Filter(C1XOptions.PrintFilter, id);
+            try {
+                stubs.put(id, emitter.emit(id, runtime));
+            } finally {
+                suppressor.remove();
+            }
+        }
+
+        if (C1XOptions.PrintCFGToFile) {
+            addCompilationObserver(new CFGPrinterObserver());
+        }
+    }
+
+    public GlobalStub lookupGlobalStub(GlobalStub.Id id) {
+        GlobalStub globalStub = stubs.get(id);
+        assert globalStub != null : "no stub for global stub id: " + id;
+        return globalStub;
+    }
+
+    public GlobalStub lookupGlobalStub(XirTemplate template) {
+        GlobalStub globalStub = stubs.get(template);
+        assert globalStub != null : "no stub for XirTemplate: " + template;
+        return globalStub;
+    }
+
+    public GlobalStub lookupGlobalStub(CiRuntimeCall runtimeCall) {
+        GlobalStub globalStub = stubs.get(runtimeCall);
+        if (globalStub == null) {
+            globalStub = backend.newGlobalStubEmitter().emit(runtimeCall, runtime);
+            stubs.put(runtimeCall, globalStub);
+        }
+
+        assert globalStub != null : "could not find global stub for runtime call: " + runtimeCall;
+        return globalStub;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/src/com/sun/c1x/C1XCompilerExtension.java	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.c1x;
+
+import com.sun.c1x.graph.*;
+
+/**
+ * Mechanism for extending C1X with extra transformations, analysis, optimizations.
+ *
+ * TODO: add support for fine grain specification of where/when extensions are to be called
+ *
+ * @author Doug Simon
+ */
+public class C1XCompilerExtension {
+
+    public final void run(IR ir) {
+        process(ir);
+    }
+
+    protected void process(IR ir) {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/src/com/sun/c1x/C1XIntrinsic.java	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.c1x;
+
+import java.util.*;
+
+import com.sun.cri.ci.*;
+import com.sun.cri.ri.*;
+
+/**
+ * This enum represents all of the intrinsics, i.e. a library methods that
+ * are treated specially by the compiler. Note that the list includes more intrinsics
+ * than are currently handled by C1X.
+ *
+ * @author Ben L. Titzer
+ */
+public enum C1XIntrinsic {
+
+    // java.lang.Object
+    java_lang_Object$init     ("java.lang.Object", "<init>", "()V"),
+    java_lang_Object$hashCode ("java.lang.Object", "hashCode", "()I"),
+    java_lang_Object$getClass ("java.lang.Object", "getClass", "()Ljava/lang/Class;"),
+    java_lang_Object$clone    ("java.lang.Object", "clone", "()Ljava/lang/Object;"),
+
+    // java.lang.Class
+    java_lang_Class$isAssignableFrom ("java.lang.Class", "isAssignableFrom", "(Ljava/lang/Class;)Z"),
+    java_lang_Class$isInstance       ("java.lang.Class", "isInstance", "(Ljava/lang/Object;)Z"),
+    java_lang_Class$getModifiers     ("java.lang.Class", "getModifiers", "()I"),
+    java_lang_Class$isInterface      ("java.lang.Class", "isInterface", "()Z"),
+    java_lang_Class$isArray          ("java.lang.Class", "isArray", "()Z"),
+    java_lang_Class$isPrimitive      ("java.lang.Class", "isPrimitive", "()Z"),
+    java_lang_Class$getSuperclass    ("java.lang.Class", "getSuperclass", "()Ljava/lang/Class;"),
+    java_lang_Class$getComponentType ("java.lang.Class", "getComponentType", "()Ljava/lang/Class;"),
+
+    // java.util.Arrays
+    java_util_Arrays$copyOf ("java.util.Arrays", "copyOf", "([Ljava/lang/Object;I)[Ljava/lang/Object;"),
+
+    // java.lang.String
+    java_lang_String$compareTo ("java.lang.String", "compareTo", "(Ljava/lang/String;)I"),
+    java_lang_String$indexOf   ("java.lang.String", "indexOf", "(Ljava/lang/String;)I"),
+    java_lang_String$equals    ("java.lang.String", "equals", "(Ljava/lang/Object;)Z"),
+
+    // java.lang.Math
+    java_lang_Math$abs   ("java.lang.Math", "abs", "(D)D"),
+    java_lang_Math$sin   ("java.lang.Math", "sin", "(D)D"),
+    java_lang_Math$cos   ("java.lang.Math", "cos", "(D)D"),
+    java_lang_Math$tan   ("java.lang.Math", "tan", "(D)D"),
+    java_lang_Math$atan2 ("java.lang.Math", "atan2", "(DD)D"),
+    java_lang_Math$sqrt  ("java.lang.Math", "sqrt", "(D)D"),
+    java_lang_Math$log   ("java.lang.Math", "log", "(D)D"),
+    java_lang_Math$log10 ("java.lang.Math", "log10", "(D)D"),
+    java_lang_Math$pow   ("java.lang.Math", "pow", "(DD)D"),
+    java_lang_Math$exp   ("java.lang.Math", "exp", "(D)D"),
+    java_lang_Math$min   ("java.lang.Math", "min", "(II)I"),
+    java_lang_Math$max   ("java.lang.Math", "max", "(II)I"),
+
+    // java.lang.Float
+    java_lang_Float$floatToRawIntBits ("java.lang.Float", "floatToRawIntBits", "(F)I"),
+    java_lang_Float$floatToIntBits    ("java.lang.Float", "floatToIntBits", "(F)I"),
+    java_lang_Float$intBitsToFloat    ("java.lang.Float", "intBitsToFloat", "(I)F"),
+
+    // java.lang.Double
+    java_lang_Double$doubleToRawLongBits ("java.lang.Double", "doubleToRawLongBits", "(D)J"),
+    java_lang_Double$doubleToLongBits    ("java.lang.Double", "doubleToLongBits", "(D)J"),
+    java_lang_Double$longBitsToDouble    ("java.lang.Double", "longBitsToDouble", "(J)D"),
+
+    // java.lang.Integer
+    java_lang_Integer$bitCount     ("java.lang.Integer", "bitCount", "(I)I"),
+    java_lang_Integer$reverseBytes ("java.lang.Integer", "reverseBytes", "(I)I"),
+
+    // java.lang.Long
+    java_lang_Long$bitCount     ("java.lang.Long", "bitCount", "(J)I"),
+    java_lang_Long$reverseBytes ("java.lang.Long", "reverseBytes", "(J)J"),
+
+    // java.lang.System
+    java_lang_System$identityHashCode  ("java.lang.System", "identityHashCode", "(Ljava/lang/Object;)I"),
+    java_lang_System$currentTimeMillis ("java.lang.System", "currentTimeMillis", "()J"),
+    java_lang_System$nanoTime          ("java.lang.System", "nanoTime", "()J"),
+    java_lang_System$arraycopy         ("java.lang.System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V"),
+
+    // java.lang.Thread
+    java_lang_Thread$currentThread ("java.lang.Thread", "currentThread", "()Ljava/lang/Thread;"),
+
+    // java.lang.reflect.Array
+    java_lang_reflect_Array$getLength ("java.lang.reflect.Array", "getLength", "(Ljava/lang/Object;)I"),
+    java_lang_reflect_Array$newArray  ("java.lang.reflect.Array", "newArray", "(Ljava/lang/Class;I)Ljava/lang/Object;"),
+
+    // java.nio.Buffer
+    java_nio_Buffer$checkIndex ("java.nio.Buffer", "checkIndex", "(I)I"),
+
+    // sun.misc.Unsafe
+    sun_misc_Unsafe$compareAndSwapObject ("sun.misc.Unsafe", "compareAndSwapObject", "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z"),
+    sun_misc_Unsafe$compareAndSwapLong   ("sun.misc.Unsafe", "compareAndSwapLong", "(Ljava/lang/Object;JJJ)Z"),
+    sun_misc_Unsafe$compareAndSwapInt    ("sun.misc.Unsafe", "compareAndSwapInt", "(Ljava/lang/Object;JII)Z");
+
+    private static final HashMap<String, HashMap<String, C1XIntrinsic>> intrinsicMap = new HashMap<String, HashMap<String, C1XIntrinsic>>(100);
+
+    /**
+     * The name of the class in which this method is declared.
+     */
+    public final String className;
+
+    /**
+     * The name of this intrinsic method.
+     */
+    public final String methodName;
+
+    /**
+     * The signature of this intrinsic method as a string.
+     */
+    public final String signature;
+
+    C1XIntrinsic(String className, String methodName, String signature) {
+        // Check that enum names are according to convention.
+        assert className.equals(name().substring(0, name().indexOf('$')).replace('_', '.'));
+        assert methodName.equals("<init>") || methodName.equals(name().substring(name().indexOf('$') + 1));
+        this.methodName = methodName;
+        this.className = className;
+        this.signature = signature;
+    }
+
+    static {
+        // iterate through all the intrinsics and add them to the map
+        for (C1XIntrinsic i : C1XIntrinsic.values()) {
+            // note that the map uses internal names to map lookup faster
+            String className = CiUtil.toInternalName(i.className);
+            HashMap<String, C1XIntrinsic> map = intrinsicMap.get(className);
+            if (map == null) {
+                map = new HashMap<String, C1XIntrinsic>();
+                intrinsicMap.put(className, map);
+            }
+            map.put(i.methodName + i.signature, i);
+        }
+    }
+
+    /**
+     * Looks up an intrinsic for the specified method.
+     * @param method the compiler interface method
+     * @return a reference to the intrinsic for the method, if the method is an intrinsic
+     * (and is loaded); {@code null} otherwise
+     */
+    public static C1XIntrinsic getIntrinsic(RiMethod method) {
+        RiType holder = method.holder();
+        if (method.isResolved() && holder.isResolved() && holder.isInitialized()) {
+            // note that the map uses internal names to make lookup faster
+            HashMap<String, C1XIntrinsic> map = intrinsicMap.get(holder.name());
+            if (map != null) {
+                C1XIntrinsic result = map.get(method.name() + method.signature().asString());
+                return result;
+            }
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/src/com/sun/c1x/C1XMetrics.java	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.c1x;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.sun.c1x.debug.*;
+
+
+/**
+ * This class contains a number of fields that collect metrics about compilation, particularly
+ * the number of times certain optimizations are performed.
+ *
+ * @author Ben L. Titzer
+ */
+public class C1XMetrics {
+    public static int CompiledMethods;
+    public static int TargetMethods;
+    public static int LocalValueNumberHits;
+    public static int GlobalValueNumberHits;
+    public static int ValueMapResizes;
+    public static int InlinedFinalizerChecks;
+    public static int MethodsFolded;
+    public static int InlineForcedMethods;
+    public static int InlineForbiddenMethods;
+    public static int InlinedJsrs;
+    public static int NullCheckIterations;
+    public static int NullCheckEliminations;
+    public static int NullChecksRedundant;
+    public static int NullCheckIdsAssigned;
+    public static int ZeroChecksRedundant;
+    public static int DivideSpecialChecksRedundant;
+    public static int StoreCheckEliminations;
+    public static int BoundsChecksElminations;
+    public static int ConditionalEliminations;
+    public static int BlocksMerged;
+    public static int BlocksSkipped;
+    public static int BlocksDeleted;
+    public static int DeadCodeEliminated;
+    public static int ResolveCPEAttempts;
+    public static int BytecodesCompiled;
+    public static int CodeBytesEmitted;
+    public static int SafepointsEmitted;
+    public static int ExceptionHandlersEmitted;
+    public static int DataPatches;
+    public static int DirectCallSitesEmitted;
+    public static int IndirectCallSitesEmitted;
+    public static int HIRInstructions;
+    public static int LiveHIRInstructions;
+    public static int LIRInstructions;
+    public static int LIRVariables;
+    public static int LIRXIRInstructions;
+    public static int LIRMoveInstructions;
+    public static int LSRAIntervalsCreated;
+    public static int LSRASpills;
+    public static int LoadConstantIterations;
+    public static int CodeBufferCopies;
+    public static int UniqueValueIdsAssigned;
+    public static int RedundantConditionals;
+    public static int FrameStatesCreated;
+    public static int FrameStateValuesCreated;
+
+    public static void print() {
+        printClassFields(C1XMetrics.class);
+
+    }
+
+    public static void printClassFields(Class<?> javaClass) {
+        final String className = javaClass.getSimpleName();
+        TTY.println(className + " {");
+        for (final Field field : javaClass.getFields()) {
+            printField(field, false);
+        }
+        TTY.println("}");
+    }
+
+    public static void printField(final Field field, boolean tabbed) {
+        final String fieldName = String.format("%35s", field.getName());
+        try {
+            String prefix = tabbed ? "" : "    " + fieldName + " = ";
+            String postfix = tabbed ? "\t" : "\n";
+            if (field.getType() == int.class) {
+                TTY.print(prefix + field.getInt(null) + postfix);
+            } else if (field.getType() == boolean.class) {
+                TTY.print(prefix + field.getBoolean(null) + postfix);
+            } else if (field.getType() == float.class) {
+                TTY.print(prefix + field.getFloat(null) + postfix);
+            } else if (field.getType() == String.class) {
+                TTY.print(prefix + field.get(null) + postfix);
+            } else if (field.getType() == Map.class) {
+                Map<?, ?> m = (Map<?, ?>) field.get(null);
+                TTY.print(prefix + printMap(m) + postfix);
+            } else {
+                TTY.print(prefix + field.get(null) + postfix);
+            }
+        } catch (IllegalAccessException e) {
+            // do nothing.
+        }
+    }
+
+    private static String printMap(Map<?, ?> m) {
+        StringBuilder sb = new StringBuilder();
+
+        List<String> keys = new ArrayList<String>();
+        for (Object key : m.keySet()) {
+            keys.add((String) key);
+        }
+        Collections.sort(keys);
+
+        for (String key : keys) {
+            sb.append(key);
+            sb.append("\t");
+            sb.append(m.get(key));
+            sb.append("\n");
+        }
+
+        return sb.toString();
+    }
+
+    private static void printField(String fieldName, long value) {
+        TTY.print("    " + fieldName + " = " + value + "\n");
+    }
+
+    private static void printField(String fieldName, double value) {
+        TTY.print("    " + fieldName + " = " + value + "\n");
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/src/com/sun/c1x/C1XOptions.java	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.c1x;
+
+import com.sun.c1x.debug.TTY.*;
+
+/**
+ * This class encapsulates options that control the behavior of the C1X compiler.
+ * The help message for each option is specified by a {@linkplain #helpMap help map}.
+ *
+ * (tw) WARNING: Fields of this class are treated as final by Graal.
+ *
+ * @author Ben L. Titzer
+ */
+public final class C1XOptions {
+
+    // Checkstyle: stop
+    private static final boolean ____ = false;
+    // Checkstyle: resume
+
+    // inlining settings
+    public static boolean OptInline                          = ____;
+    public static boolean OptInlineExcept                    = ____;
+    public static boolean OptInlineSynchronized              = ____;
+
+    public static int     MaximumInstructionCount            = 37000;
+    public static float   MaximumInlineRatio                 = 0.90f;
+    public static int     MaximumInlineSize                  = 35;
+    public static int     MaximumTrivialSize                 = 6;
+    public static int     MaximumInlineLevel                 = 9;
+    public static int     MaximumRecursiveInlineLevel        = 1;
+    public static int     MaximumDesiredSize                 = 8000;
+    public static int     MaximumShortLoopSize               = 5;
+
+    // intrinsification settings
+    public static boolean OptIntrinsify                      = ____;
+
+    // debugging settings
+    public static boolean VerifyPointerMaps                  = ____;
+    public static boolean PinAllInstructions                 = ____;
+    public static boolean TestPatching                       = ____;
+    public static boolean FatalUnimplemented                 = ____;
+    public static int     MethodEndBreakpointGuards          = 0;
+    public static boolean ZapStackOnMethodEntry              = ____;
+    public static boolean StressLinearScan                   = ____;
+
+    /**
+     * See {@link Filter#Filter(String, Object)}.
+     */
+    public static String  PrintFilter                        = null;
+
+    // printing settings
+    public static boolean PrintHIR                           = ____;
+    public static boolean PrintInliningFailures              = ____;
+    public static boolean PrintLIR                           = ____;
+    public static boolean PrintCFGToFile                     = ____;
+    public static boolean PrintMetrics                       = ____;
+    public static boolean PrintTimers                        = ____;
+    public static boolean PrintCompilation                   = ____;
+    public static boolean PrintXirTemplates                  = ____;
+    public static boolean PrintIRWithLIR                     = ____;
+    public static boolean PrintAssembly                      = ____;
+    public static boolean PrintCodeBytes                     = ____;
+    public static int     PrintAssemblyBytesPerLine          = 16;
+    public static int     TraceLinearScanLevel               = 0;
+    public static boolean TraceRelocation                    = ____;
+    public static boolean TraceLIRVisit                      = ____;
+    public static boolean TraceAssembler                     = ____;
+    public static int     TraceBytecodeParserLevel           = 0;
+    public static boolean PrintAssumptions                   = ____;
+    public static boolean PrintInlinedIntrinsics             = ____;
+
+    // IR checking
+    public static boolean InterpretInvokedMethods            = ____;
+    public static boolean PrintStateInInterpreter            = ____;
+
+    // canonicalizer settings
+    public static boolean CanonicalizeIntrinsics             = true;
+    public static boolean CanonicalizeFloatingPoint          = true;
+    public static boolean CanonicalizeNarrowingInStores      = true;
+    public static boolean CanonicalizeConstantFields         = true;
+    public static boolean CanonicalizeUnsafes                = true;
+    public static boolean CanonicalizeMultipliesToShifts     = true;
+    public static boolean CanonicalizeObjectCheckCast        = true;
+    public static boolean CanonicalizeObjectInstanceOf       = true;
+    public static boolean CanonicalizeFoldableMethods        = true;
+    public static boolean CanonicalizeArrayStoreChecks       = true;
+
+    // all optimization settings
+    public static boolean OptCanonicalize;
+    public static boolean OptLocalValueNumbering;
+    public static boolean OptLocalLoadElimination;
+    public static boolean OptCSEArrayLength;
+    public static boolean OptGlobalValueNumbering;
+    public static boolean OptCEElimination;
+    public static boolean OptBlockMerging;
+    public static boolean OptBlockSkipping;
+    public static boolean OptNullCheckElimination;
+    public static boolean OptIterativeNCE;
+    public static boolean OptFlowSensitiveNCE;
+    public static boolean OptDeadCodeElimination1;
+    public static boolean OptDeadCodeElimination2;
+    public static boolean OptControlFlow;
+    public static boolean OptMoveElimination;
+
+    // optimistic optimization settings
+    public static boolean UseAssumptions                = true;
+
+    // state merging settings
+    public static boolean AssumeVerifiedBytecode        = ____;
+    public static boolean PhiSimplify                   = true;
+    public static boolean PhiLoopStores                 = true;
+
+    // miscellaneous settings
+    public static boolean SupportObjectConstants        = true;
+
+    // Linear scan settings
+    public static boolean CopyPointerStackArguments     = true;
+
+    // Code generator settings
+    public static boolean GenLIR                        = true;
+    public static boolean GenCode                       = true;
+
+    public static boolean UseConstDirectCall            = false;
+
+    public static boolean GenSpecialDivChecks           = ____;
+    public static boolean GenAssertionCode              = ____;
+    public static boolean AlignCallsForPatching         = true;
+    public static boolean NullCheckUniquePc             = ____;
+    public static boolean InvokeSnippetAfterArguments   = ____;
+    public static boolean ResolveClassBeforeStaticInvoke = true;
+
+    // Translating tableswitch instructions
+    public static int     SequentialSwitchLimit         = 4;
+    public static int     RangeTestsSwitchDensity       = 5;
+
+    public static int     InitialCodeBufferSize         = 232;
+    public static boolean DetailedAsserts               = true;
+
+    // Runtime settings
+    public static int     ReadPrefetchInstr             = 0;
+    public static boolean UseStackMapTableLiveness      = ____;
+    public static int     StackShadowPages              = 2;
+
+    // Assembler settings
+    public static boolean CommentedAssembly             = ____;
+    public static boolean PrintLIRWithAssembly          = ____;
+    public static int     Atomics                       = 0;
+    public static boolean UseNormalNop                  = true;
+    public static boolean UseAddressNop                 = true;
+    public static boolean UseIncDec                     = ____;
+    public static boolean UseXmmLoadAndClearUpper       = ____;
+    public static boolean UseXmmRegToRegMoveAll         = ____;
+
+    static {
+        setOptimizationLevel(1);
+    }
+
+    public static void setOptimizationLevel(int level) {
+        final boolean l = (level >= 1);
+        final boolean ll = (level >= 2);
+        final boolean lll = (level >= 3);
+
+        // Level 1 optimizations
+        OptCanonicalize                 = l;
+        OptLocalValueNumbering          = l;
+        OptLocalLoadElimination         = l;
+        PhiLoopStores                   = l;
+        OptControlFlow                  = l;
+        OptMoveElimination              = l;
+        OptNullCheckElimination         = l;
+
+        // Level 2 optimizations
+        OptInline                       = ll;
+        OptBlockMerging                 = ll;
+
+        // Level 3 optimizations
+        OptCSEArrayLength               = lll;
+        OptIntrinsify                   = lll;
+        OptInlineExcept                 = lll;
+        OptInlineSynchronized           = lll;
+        UseStackMapTableLiveness        = lll;
+        UseAssumptions                  = lll;
+        OptIterativeNCE                 = lll;
+        OptFlowSensitiveNCE             = lll;
+        OptDeadCodeElimination1         = lll;
+        OptDeadCodeElimination2         = lll;
+        OptGlobalValueNumbering         = lll;
+        OptCEElimination                = lll;
+        OptBlockSkipping                = lll;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/src/com/sun/c1x/C1XTimers.java	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2009, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.c1x;
+
+import com.sun.c1x.debug.*;
+
+/**
+ * This class contains timers that record the amount of time spent in various
+ * parts of the compiler.
+ *
+ * @author Christian Wimmer
+ */
+public enum C1XTimers {
+    HIR_CREATE("Create HIR"),
+    HIR_OPTIMIZE("Optimize HIR"),
+    NCE("Nullcheck elimination"),
+    LIR_CREATE("Create LIR"),
+    LIFETIME_ANALYSIS("Lifetime Analysis"),
+    LINEAR_SCAN("Linear Scan"),
+    RESOLUTION("Resolution"),
+    DEBUG_INFO("Create Debug Info"),
+    CODE_CREATE("Create Code");
+
+    private final String name;
+    private long start;
+    private long total;
+
+    private C1XTimers(String name) {
+        this.name = name;
+    }
+
+    public void start() {
+        start = System.nanoTime();
+    }
+
+    public void stop() {
+        total += System.nanoTime() - start;
+    }
+
+    public static void reset() {
+        for (C1XTimers t : values()) {
+            t.total = 0;
+        }
+    }
+
+    public static void print() {
+        long total = 0;
+        for (C1XTimers timer : C1XTimers.values()) {
+            total += timer.total;
+        }
+        if (total == 0) {
+            return;
+        }
+
+        TTY.println();
+        for (C1XTimers timer : C1XTimers.values()) {
+            TTY.println("%-20s: %7.4f s (%5.2f%%)", timer.name, timer.total / 1000000000.0, timer.total * 100.0 / total);
+            timer.total = 0;
+        }
+        TTY.println();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/src/com/sun/c1x/alloc/ControlFlowOptimizer.java	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.c1x.alloc;
+
+import java.util.*;
+
+import com.sun.c1x.*;
+import com.sun.c1x.graph.*;
+import com.sun.c1x.ir.*;
+import com.sun.c1x.lir.*;
+import com.sun.c1x.util.*;
+import com.sun.cri.ci.*;
+
+/**
+ * This class performs basic optimizations on the control flow graph after LIR generation.
+ *
+ * @author Thomas Wuerthinger
+ */
+final class ControlFlowOptimizer {
+
+    /**
+     * Performs control flow optimizations on the given IR graph.
+     * @param ir the IR graph that should be optimized
+     */
+    public static void optimize(IR ir) {
+        ControlFlowOptimizer optimizer = new ControlFlowOptimizer(ir);
+        List<BlockBegin> code = ir.linearScanOrder();
+
+        // push the OSR entry block to the end so that we're not jumping over it.
+        BlockBegin osrEntry = ((Base) code.get(0).end()).osrEntry();
+        if (osrEntry != null) {
+            int index = osrEntry.linearScanNumber();
+            assert code.get(index) == osrEntry : "wrong index";
+            code.remove(index);
+            code.add(osrEntry);
+        }
+
+        optimizer.reorderShortLoops(code);
+        optimizer.deleteEmptyBlocks(code);
+        optimizer.deleteUnnecessaryJumps(code);
+        optimizer.deleteJumpsToReturn(code);
+    }
+
+    private final IR ir;
+
+    private ControlFlowOptimizer(IR ir) {
+        this.ir = ir;
+    }
+
+    private void reorderShortLoop(List<BlockBegin> code, BlockBegin headerBlock, int headerIdx) {
+        int i = headerIdx + 1;
+        int maxEnd = Math.min(headerIdx + C1XOptions.MaximumShortLoopSize, code.size());
+        while (i < maxEnd && code.get(i).loopDepth() >= headerBlock.loopDepth()) {
+            i++;
+        }
+
+        if (i == code.size() || code.get(i).loopDepth() < headerBlock.loopDepth()) {
+            int endIdx = i - 1;
+            BlockBegin endBlock = code.get(endIdx);
+
+            if (endBlock.numberOfSux() == 1 && endBlock.suxAt(0) == headerBlock) {
+                // short loop from headerIdx to endIdx found . reorder blocks such that
+                // the headerBlock is the last block instead of the first block of the loop
+
+                for (int j = headerIdx; j < endIdx; j++) {
+                    code.set(j, code.get(j + 1));
+                }
+                code.set(endIdx, headerBlock);
+
+                // correct the flags so that any loop alignment occurs in the right place.
+                assert code.get(endIdx).checkBlockFlag(BlockBegin.BlockFlag.BackwardBranchTarget) : "must be backward branch target";
+                code.get(endIdx).clearBlockFlag(BlockBegin.BlockFlag.BackwardBranchTarget);
+                code.get(headerIdx).setBlockFlag(BlockBegin.BlockFlag.BackwardBranchTarget);
+            }
+        }
+    }
+
+    private void reorderShortLoops(List<BlockBegin> code) {
+        for (int i = code.size() - 1; i >= 0; i--) {
+            BlockBegin block = code.get(i);
+
+            if (block.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader)) {
+                reorderShortLoop(code, block, i);
+            }
+        }
+
+        assert verify(code);
+    }
+
+    // only blocks with exactly one successor can be deleted. Such blocks
+    // must always end with an unconditional branch to this successor
+    private boolean canDeleteBlock(BlockBegin block) {
+        if (block.numberOfSux() != 1 ||
+            block.numberOfExceptionHandlers() != 0 ||
+            block == ir.startBlock ||
+            block.isExceptionEntry() ||
+            block.suxAt(0) == block) {
+            return false;
+        }
+
+        List<LIRInstruction> instructions = block.lir().instructionsList();
+
+        assert instructions.size() >= 2 : "block must have label and branch";
+        assert instructions.get(0).code == LIROpcode.Label : "first instruction must always be a label";
+        assert instructions.get(instructions.size() - 1) instanceof LIRBranch : "last instruction must always be a branch";
+        assert ((LIRBranch) instructions.get(instructions.size() - 1)).cond() == Condition.TRUE : "branch must be unconditional";
+        assert ((LIRBranch) instructions.get(instructions.size() - 1)).block() == block.suxAt(0) : "branch target must be the successor";
+
+        // block must have exactly one successor
+
+        return instructions.size() == 2 && instructions.get(instructions.size() - 1).info == null;
+    }
+
+    private void deleteEmptyBlocks(List<BlockBegin> code) {
+        int oldPos = 0;
+        int newPos = 0;
+        int numBlocks = code.size();
+
+        while (oldPos < numBlocks) {
+            BlockBegin block = code.get(oldPos);
+
+            if (canDeleteBlock(block)) {
+                BlockBegin newTarget = block.suxAt(0);
+
+                // propagate backward branch target flag for correct code alignment
+                if (block.checkBlockFlag(BlockBegin.BlockFlag.BackwardBranchTarget)) {
+                    newTarget.setBlockFlag(BlockBegin.BlockFlag.BackwardBranchTarget);
+                }
+
+                // update the block references in any branching LIR instructions
+                for (BlockBegin pred : block.predecessors()) {
+                    for (LIRInstruction instr : pred.lir().instructionsList()) {
+                        if (instr instanceof LIRBranch) {
+                            ((LIRBranch) instr).substitute(block, newTarget);
+                        } else if (instr instanceof LIRTableSwitch) {
+                            ((LIRTableSwitch) instr).substitute(block, newTarget);
+                        }
+                    }
+                }
+
+                // adjust successor and predecessor lists
+                ir.replaceBlock(block, newTarget);
+                C1XMetrics.BlocksDeleted++;
+            } else {
+                // adjust position of this block in the block list if blocks before
+                // have been deleted
+                if (newPos != oldPos) {
+                    code.set(newPos, code.get(oldPos));
+                }
+                newPos++;
+            }
+            oldPos++;
+        }
+        Util.truncate(code, newPos);
+
+        assert verify(code);
+    }
+
+    private void deleteUnnecessaryJumps(List<BlockBegin> code) {
+        // skip the last block because there a branch is always necessary
+        for (int i = code.size() - 2; i >= 0; i--) {
+            BlockBegin block = code.get(i);
+            List<LIRInstruction> instructions = block.lir().instructionsList();
+
+            LIRInstruction lastOp = instructions.get(instructions.size() - 1);
+            if (lastOp.code == LIROpcode.Branch) {
+                assert lastOp instanceof LIRBranch : "branch must be of type LIRBranch";
+                LIRBranch lastBranch = (LIRBranch) lastOp;
+
+                assert lastBranch.block() != null : "last branch must always have a block as target";
+                assert lastBranch.label() == lastBranch.block().label() : "must be equal";
+
+                if (lastBranch.info == null) {
+                    if (lastBranch.block() == code.get(i + 1)) {
+                        // delete last branch instruction
+                        Util.truncate(instructions, instructions.size() - 1);
+
+                    } else {
+                        LIRInstruction prevOp = instructions.get(instructions.size() - 2);
+                        if (prevOp.code == LIROpcode.Branch || prevOp.code == LIROpcode.CondFloatBranch) {
+                            assert prevOp instanceof LIRBranch : "branch must be of type LIRBranch";
+                            LIRBranch prevBranch = (LIRBranch) prevOp;
+
+                            if (prevBranch.block() == code.get(i + 1) && prevBranch.info == null) {
+                                // eliminate a conditional branch to the immediate successor
+                                prevBranch.changeBlock(lastBranch.block());
+                                prevBranch.negateCondition();
+                                Util.truncate(instructions, instructions.size() - 1);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        assert verify(code);
+    }
+
+    private void deleteJumpsToReturn(List<BlockBegin> code) {
+        for (int i = code.size() - 1; i >= 0; i--) {
+            BlockBegin block = code.get(i);
+            List<LIRInstruction> curInstructions = block.lir().instructionsList();
+            LIRInstruction curLastOp = curInstructions.get(curInstructions.size() - 1);
+
+            assert curInstructions.get(0).code == LIROpcode.Label : "first instruction must always be a label";
+            if (curInstructions.size() == 2 && curLastOp.code == LIROpcode.Return) {
+                // the block contains only a label and a return
+                // if a predecessor ends with an unconditional jump to this block, then the jump
+                // can be replaced with a return instruction
+                //
+                // Note: the original block with only a return statement cannot be deleted completely
+                // because the predecessors might have other (conditional) jumps to this block.
+                // this may lead to unnecesary return instructions in the final code
+
+                assert curLastOp.info == null : "return instructions do not have debug information";
+
+                assert curLastOp instanceof LIROp1 : "return must be LIROp1";
+                CiValue returnOpr = ((LIROp1) curLastOp).operand();
+
+                for (int j = block.numberOfPreds() - 1; j >= 0; j--) {
+                    BlockBegin pred = block.predAt(j);
+                    List<LIRInstruction> predInstructions = pred.lir().instructionsList();
+                    LIRInstruction predLastOp = predInstructions.get(predInstructions.size() - 1);
+
+                    if (predLastOp.code == LIROpcode.Branch) {
+                        assert predLastOp instanceof LIRBranch : "branch must be LIRBranch";
+                        LIRBranch predLastBranch = (LIRBranch) predLastOp;
+
+                        if (predLastBranch.block() == block && predLastBranch.cond() == Condition.TRUE && predLastBranch.info == null) {
+                            // replace the jump to a return with a direct return
+                            // Note: currently the edge between the blocks is not deleted
+                            predInstructions.set(predInstructions.size() - 1, new LIROp1(LIROpcode.Return, returnOpr));
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private boolean verify(List<BlockBegin> code) {
+        for (BlockBegin block : code) {
+            List<LIRInstruction> instructions = block.lir().instructionsList();
+
+            for (LIRInstruction instr : instructions) {
+                if (instr instanceof LIRBranch) {
+                    LIRBranch opBranch = (LIRBranch) instr;
+                    assert opBranch.block() == null || code.contains(opBranch.block()) : "missing successor branch from: " + block + " to: " + opBranch.block();
+                    assert opBranch.unorderedBlock() == null || code.contains(opBranch.unorderedBlock()) : "missing successor branch from: " + block + " to: " + opBranch.unorderedBlock();
+                }
+            }
+
+            for (BlockBegin sux : block.end().successors()) {
+                assert code.contains(sux) : "missing successor from: " + block + "to: " + sux;
+            }
+
+            for (BlockBegin pred : block.predecessors()) {
+                assert code.contains(pred) : "missing predecessor from: " + block + "to: " + pred;
+            }
+        }
+
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/src/com/sun/c1x/alloc/EdgeMoveOptimizer.java	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.c1x.alloc;
+
+import java.util.*;
+
+import com.sun.c1x.*;
+import com.sun.c1x.ir.*;
+import com.sun.c1x.lir.*;
+
+/**
+ * This class optimizes moves, particularly those that result from eliminating SSA form.
+ *
+ * When a block has more than one predecessor, and all predecessors end with
+ * the {@linkplain #same(LIRInstruction, LIRInstruction) same} sequence of
+ * {@linkplain LIROpcode#Move move} instructions, then these sequences
+ * can be replaced with a single copy of the sequence at the beginning of the block.
+ *
+ * Similarly, when a block has more than one successor, then same sequences of
+ * moves at the beginning of the successors can be placed once at the end of
+ * the block. But because the moves must be inserted before all branch
+ * instructions, this works only when there is exactly one conditional branch
+ * at the end of the block (because the moves must be inserted before all
+ * branches, but after all compares).
+ *
+ * This optimization affects all kind of moves (reg->reg, reg->stack and
+ * stack->reg). Because this optimization works best when a block contains only
+ * a few moves, it has a huge impact on the number of blocks that are totally
+ * empty.
+ *
+ * @author Christian Wimmer (original HotSpot implementation)
+ * @author Thomas Wuerthinger
+ * @author Doug Simon
+ */
+final class EdgeMoveOptimizer {
+
+    /**
+     * Optimizes moves on block edges.
+     *
+     * @param blockList a list of blocks whose moves should be optimized
+     */
+    public static void optimize(List<BlockBegin> blockList) {
+        EdgeMoveOptimizer optimizer = new EdgeMoveOptimizer();
+
+        // ignore the first block in the list (index 0 is not processed)
+        for (int i = blockList.size() - 1; i >= 1; i--) {
+            BlockBegin block = blockList.get(i);
+
+            if (block.numberOfPreds() > 1 && !block.checkBlockFlag(BlockBegin.BlockFlag.ExceptionEntry)) {
+                optimizer.optimizeMovesAtBlockEnd(block);
+            }
+            if (block.numberOfSux() == 2) {
+                optimizer.optimizeMovesAtBlockBegin(block);
+            }
+        }
+    }
+
+    private final List<List<LIRInstruction>> edgeInstructionSeqences;
+
+    private EdgeMoveOptimizer() {
+        edgeInstructionSeqences = new ArrayList<List<LIRInstruction>>(4);
+    }
+
+    /**
+     * Determines if two operations are both {@linkplain LIROpcode#Move moves}
+     * that have the same {@linkplain LIROp1#operand() source} and {@linkplain LIROp1#result() destination}
+     * operands and they have the same {@linkplain LIRInstruction#info debug info}.
+     *
+     * @param op1 the first instruction to compare
+     * @param op2 the second instruction to compare
+     * @return {@code true} if {@code op1} and {@code op2} are the same by the above algorithm
+     */
+    private boolean same(LIRInstruction op1, LIRInstruction op2) {
+        assert op1 != null;
+        assert op2 != null;
+
+        if (op1.code == LIROpcode.Move && op2.code == LIROpcode.Move) {
+            assert op1 instanceof LIROp1 : "move must be LIROp1";
+            assert op2 instanceof LIROp1 : "move must be LIROp1";
+            LIROp1 move1 = (LIROp1) op1;
+            LIROp1 move2 = (LIROp1) op2;
+            if (move1.info == move2.info && move1.operand().equals(move2.operand()) && move1.result().equals(move2.result())) {
+                // these moves are exactly equal and can be optimized
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Moves the longest {@linkplain #same common} subsequence at the end all
+     * predecessors of {@code block} to the start of {@code block}.
+     */
+    private void optimizeMovesAtBlockEnd(BlockBegin block) {
+        if (block.isPredecessor(block)) {
+            // currently we can't handle this correctly.
+            return;
+        }
+
+        // clear all internal data structures
+        edgeInstructionSeqences.clear();
+
+        int numPreds = block.numberOfPreds();
+        assert numPreds > 1 : "do not call otherwise";
+        assert !block.checkBlockFlag(BlockBegin.BlockFlag.ExceptionEntry) : "exception handlers not allowed";
+
+        // setup a list with the LIR instructions of all predecessors
+        for (int i = 0; i < numPreds; i++) {
+            BlockBegin pred = block.predAt(i);
+            List<LIRInstruction> predInstructions = pred.lir().instructionsList();
+
+            if (pred.numberOfSux() != 1) {
+                // this can happen with switch-statements where multiple edges are between
+                // the same blocks.
+                return;
+            }
+
+            assert pred.suxAt(0) == block : "invalid control flow";
+            assert predInstructions.get(predInstructions.size() - 1).code == LIROpcode.Branch : "block with successor must end with branch";
+            assert predInstructions.get(predInstructions.size() - 1) instanceof LIRBranch : "branch must be LIROpBranch";
+            assert ((LIRBranch) predInstructions.get(predInstructions.size() - 1)).cond() == Condition.TRUE : "block must end with unconditional branch";
+
+            if (predInstructions.get(predInstructions.size() - 1).info != null) {
+                // can not optimize instructions that have debug info
+                return;
+            }
+
+            // ignore the unconditional branch at the end of the block
+            List<LIRInstruction> seq = predInstructions.subList(0, predInstructions.size() - 1);
+            edgeInstructionSeqences.add(seq);
+        }
+
+        // process lir-instructions while all predecessors end with the same instruction
+        while (true) {
+            List<LIRInstruction> seq = edgeInstructionSeqences.get(0);
+            if (seq.isEmpty()) {
+                return;
+            }
+
+            LIRInstruction op = last(seq);
+            for (int i = 1; i < numPreds; ++i) {
+                List<LIRInstruction> otherSeq = edgeInstructionSeqences.get(i);
+                if (otherSeq.isEmpty() || !same(op, last(otherSeq))) {
+                    return;
+                }
+            }
+
+            // insert the instruction at the beginning of the current block
+            block.lir().insertBefore(1, op);
+
+            // delete the instruction at the end of all predecessors
+            for (int i = 0; i < numPreds; i++) {
+                seq = edgeInstructionSeqences.get(i);
+                removeLast(seq);
+            }
+        }
+    }
+
+    /**
+     * Moves the longest {@linkplain #same common} subsequence at the start of all
+     * successors of {@code block} to the end of {@code block} just prior to the
+     * branch instruction ending {@code block}.
+     */
+    private void optimizeMovesAtBlockBegin(BlockBegin block) {
+
+        edgeInstructionSeqences.clear();
+        int numSux = block.numberOfSux();
+
+        List<LIRInstruction> instructions = block.lir().instructionsList();
+
+        assert numSux == 2 : "method should not be called otherwise";
+        assert instructions.get(instructions.size() - 1).code == LIROpcode.Branch : "block with successor must end with branch";
+        assert instructions.get(instructions.size() - 1) instanceof LIRBranch : "branch must be LIROpBranch";
+        assert ((LIRBranch) instructions.get(instructions.size() - 1)).cond() == Condition.TRUE : "block must end with unconditional branch";
+
+        if (instructions.get(instructions.size() - 1).info != null) {
+            // cannot optimize instructions when debug info is needed
+            return;
+        }
+
+        LIRInstruction branch = instructions.get(instructions.size() - 2);
+        if (branch.info != null || (branch.code != LIROpcode.Branch && branch.code != LIROpcode.CondFloatBranch)) {
+            // not a valid case for optimization
+            // currently, only blocks that end with two branches (conditional branch followed
+            // by unconditional branch) are optimized
+            return;
+        }
+
+        // now it is guaranteed that the block ends with two branch instructions.
+        // the instructions are inserted at the end of the block before these two branches
+        int insertIdx = instructions.size() - 2;
+
+        if (C1XOptions.DetailedAsserts) {
+            for (int i = insertIdx - 1; i >= 0; i--) {
+                LIRInstruction op = instructions.get(i);
+                if ((op.code == LIROpcode.Branch || op.code == LIROpcode.CondFloatBranch) && ((LIRBranch) op).block() != null) {
+                    throw new Error("block with two successors can have only two branch instructions");
+                }
+            }
+        }
+
+        // setup a list with the lir-instructions of all successors
+        for (int i = 0; i < numSux; i++) {
+            BlockBegin sux = block.suxAt(i);
+            List<LIRInstruction> suxInstructions = sux.lir().instructionsList();
+
+            assert suxInstructions.get(0).code == LIROpcode.Label : "block must start with label";
+
+            if (sux.numberOfPreds() != 1) {
+                // this can happen with switch-statements where multiple edges are between
+                // the same blocks.
+                return;
+            }
+            assert sux.predAt(0) == block : "invalid control flow";
+            assert !sux.checkBlockFlag(BlockBegin.BlockFlag.ExceptionEntry) : "exception handlers not allowed";
+
+            // ignore the label at the beginning of the block
+            List<LIRInstruction> seq = suxInstructions.subList(1, suxInstructions.size());
+            edgeInstructionSeqences.add(seq);
+        }
+
+        // process LIR instructions while all successors begin with the same instruction
+        while (true) {
+            List<LIRInstruction> seq = edgeInstructionSeqences.get(0);
+            if (seq.isEmpty()) {
+                return;
+            }
+
+            LIRInstruction op = first(seq);
+            for (int i = 1; i < numSux; i++) {
+                List<LIRInstruction> otherSeq = edgeInstructionSeqences.get(i);
+                if (otherSeq.isEmpty() || !same(op, first(otherSeq))) {
+                    // these instructions are different and cannot be optimized .
+                    // no further optimization possible
+                    return;
+                }
+            }
+
+            // insert instruction at end of current block
+            block.lir().insertBefore(insertIdx, op);
+            insertIdx++;
+
+            // delete the instructions at the beginning of all successors
+            for (int i = 0; i < numSux; i++) {
+                seq = edgeInstructionSeqences.get(i);
+                removeFirst(seq);
+            }
+        }
+    }
+
+    /**
+     * Gets the first element from a LIR instruction sequence.
+     */
+    private static LIRInstruction first(List<LIRInstruction> seq) {
+        return seq.get(0);
+    }
+
+    /**
+     * Gets the last element from a LIR instruction sequence.
+     */
+    private static LIRInstruction last(List<LIRInstruction> seq) {
+        return seq.get(seq.size() - 1);
+    }
+
+    /**
+     * Removes the first element from a LIR instruction sequence.
+     */
+    private static void removeFirst(List<LIRInstruction> seq) {
+        seq.remove(0);
+    }
+
+    /**
+     * Removes the last element from a LIR instruction sequence.
+     */
+    private static void removeLast(List<LIRInstruction> seq) {
+        seq.remove(seq.size() - 1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/src/com/sun/c1x/alloc/Interval.java	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,1173 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.c1x.alloc;
+
+import java.util.*;
+
+import com.sun.c1x.*;
+import com.sun.c1x.debug.*;
+import com.sun.c1x.lir.*;
+import com.sun.c1x.util.*;
+import com.sun.cri.ci.*;
+
+/**
+ * Represents an interval in the {@linkplain LinearScan linear scan register allocator}.
+ *
+ * @author Thomas Wuerthinger
+ * @author Doug Simon
+ */
+public final class Interval {
+
+    /**
+     * A pair of intervals.
+     */
+    static final class Pair {
+        public final Interval first;
+        public final Interval second;
+        public Pair(Interval first, Interval second) {
+            this.first = first;
+            this.second = second;
+        }
+    }
+
+    /**
+     * A set of interval lists, one per {@linkplain RegisterBinding binding} type.
+     */
+    static final class RegisterBindingLists {
+
+        /**
+         * List of intervals whose binding is currently {@link RegisterBinding#Fixed}.
+         */
+        public Interval fixed;
+
+        /**
+         * List of intervals whose binding is currently {@link RegisterBinding#Any}.
+         */
+        public Interval any;
+
+        public RegisterBindingLists(Interval fixed, Interval any) {
+            this.fixed = fixed;
+            this.any = any;
+        }
+
+        /**
+         * Gets the list for a specified binding.
+         *
+         * @param binding specifies the list to be returned
+         * @return the list of intervals whose binding is {@code binding}
+         */
+        public Interval get(RegisterBinding binding) {
+            if (binding == RegisterBinding.Any) {
+                return any;
+            }
+            assert binding == RegisterBinding.Fixed;
+            return fixed;
+        }
+
+        /**
+         * Sets the list for a specified binding.
+         *
+         * @param binding specifies the list to be replaced
+         * @param a list of intervals whose binding is {@code binding}
+         */
+        public void set(RegisterBinding binding, Interval list) {
+            assert list != null;
+            if (binding == RegisterBinding.Any) {
+                any = list;
+            } else {
+                assert binding == RegisterBinding.Fixed;
+                fixed = list;
+            }
+        }
+
+        /**
+         * Adds an interval to a list sorted by {@linkplain Interval#currentFrom() current from} positions.
+         *
+         * @param binding specifies the list to be updated
+         * @param interval the interval to add
+         */
+        public void addToListSortedByCurrentFromPositions(RegisterBinding binding, Interval interval) {
+            Interval list = get(binding);
+            Interval prev = null;
+            Interval cur = list;
+            while (cur.currentFrom() < interval.currentFrom()) {
+                prev = cur;
+                cur = cur.next;
+            }
+            Interval result = list;
+            if (prev == null) {
+                // add to head of list
+                result = interval;
+            } else {
+                // add before 'cur'
+                prev.next = interval;
+            }
+            interval.next = cur;
+            set(binding, result);
+        }
+
+        /**
+         * Adds an interval to a list sorted by {@linkplain Interval#from() start} positions and
+         * {@linkplain Interval#firstUsage(RegisterPriority) first usage} positions.
+         *
+         * @param binding specifies the list to be updated
+         * @param interval the interval to add
+         */
+        public void addToListSortedByStartAndUsePositions(RegisterBinding binding, Interval interval) {
+            Interval list = get(binding);
+            Interval prev = null;
+            Interval cur = list;
+            while (cur.from() < interval.from() || (cur.from() == interval.from() && cur.firstUsage(RegisterPriority.None) < interval.firstUsage(RegisterPriority.None))) {
+                prev = cur;
+                cur = cur.next;
+            }
+            if (prev == null) {
+                list = interval;
+            } else {
+                prev.next = interval;
+            }
+            interval.next = cur;
+            set(binding, list);
+        }
+
+        /**
+         * Removes an interval from a list.
+         *
+         * @param binding specifies the list to be updated
+         * @param interval the interval to remove
+         */
+        public void remove(RegisterBinding binding, Interval i) {
+            Interval list = get(binding);
+            Interval prev = null;
+            Interval cur = list;
+            while (cur != i) {
+                assert cur != null && cur != Interval.EndMarker : "interval has not been found in list: " + i;
+                prev = cur;
+                cur = cur.next;
+            }
+            if (prev == null) {
+                set(binding, cur.next);
+            } else {
+                prev.next = cur.next;
+            }
+        }
+    }
+
+    /**
+     * Constants denoting the register usage priority for an interval.
+     * The constants are declared in increasing order of priority are
+     * are used to optimize spilling when multiple overlapping intervals
+     * compete for limited registers.
+     */
+    enum RegisterPriority {
+        /**
+         * No special reason for an interval to be allocated a register.
+         */
+        None,
+
+        /**
+         * Priority level for intervals live at the end of a loop.
+         */
+        LiveAtLoopEnd,
+
+        /**
+         * Priority level for intervals that should be allocated to a register.
+         */
+        ShouldHaveRegister,
+
+        /**
+         * Priority level for intervals that must be allocated to a register.
+         */
+        MustHaveRegister;
+
+        public static final RegisterPriority[] VALUES = values();
+
+        /**
+         * Determines if this priority is higher than or equal to a given priority.
+         */
+        public boolean greaterEqual(RegisterPriority other) {
+            return ordinal() >= other.ordinal();
+        }
+
+        /**
+         * Determines if this priority is lower than a given priority.
+         */
+        public boolean lessThan(RegisterPriority other) {
+            return ordinal() < other.ordinal();
+        }
+    }
+
+    /**
+     * Constants denoting whether an interval is bound to a specific register. This models
+     * platform dependencies on register usage for certain instructions.
+     */
+    enum RegisterBinding {
+        /**
+         * Interval is bound to a specific register as required by the platform.
+         */
+        Fixed,
+
+        /**
+         * Interval has no specific register requirements.
+         */
+        Any;
+
+        public static final RegisterBinding[] VALUES = values();
+    }
+
+    /**
+     * Constants denoting the linear-scan states an interval may be in with respect to the
+     * {@linkplain Interval#from() start} {@code position} of the interval being processed.
+     */
+    enum State {
+        /**
+         * An interval that starts after {@code position}.
+         */
+        Unhandled,
+
+        /**
+         * An interval that {@linkplain Interval#covers covers} {@code position} and has an assigned register.
+         */
+        Active,
+
+        /**
+         * An interval that starts before and ends after {@code position} but does not
+         * {@linkplain Interval#covers cover} it due to a lifetime hole.
+         */
+        Inactive,
+
+        /**
+         * An interval that ends before {@code position} or is spilled to memory.
+         */
+        Handled;
+    }
+
+    /**
+     * Constants used in optimization of spilling of an interval.
+     */
+    enum SpillState {
+        /**
+         * Starting state of calculation: no definition found yet.
+         */
+        NoDefinitionFound,
+
+        /**
+         * One definition has already been found. Two consecutive definitions are treated as one
+         * (e.g. a consecutive move and add because of two-operand LIR form).
+         * The position of this definition is given by {@link Interval#spillDefinitionPos()}.
+         */
+        NoSpillStore,
+
+        /**
+         * One spill move has already been inserted.
+         */
+        OneSpillStore,
+
+        /**
+         * The interval should be stored immediately after its definition to prevent
+         * multiple redundant stores.
+         */
+        StoreAtDefinition,
+
+        /**
+         * The interval starts in memory (e.g. method parameter), so a store is never necessary.
+         */
+        StartInMemory,
+
+        /**
+         * The interval has more than one definition (e.g. resulting from phi moves), so stores
+         * to memory are not optimized.
+         */
+        NoOptimization
+    }
+
+    /**
+     * List of use positions. Each entry in the list records the use position and register
+     * priority associated with the use position. The entries in the list are in descending
+     * order of use position.
+     *
+     * @author Doug Simon
+     */
+    public static final class UsePosList {
+        private IntList list;
+
+        /**
+         * Creates a use list.
+         *
+         * @param initialCapacity the initial capacity of the list in terms of entries
+         */
+        public UsePosList(int initialCapacity) {
+            list = new IntList(initialCapacity * 2);
+        }
+
+        private UsePosList(IntList list) {
+            this.list = list;
+        }
+
+        /**
+         * Splits this list around a given position. All entries in this list with a use position greater or equal than
+         * {@code splitPos} are removed from this list and added to the returned list.
+         *
+         * @param splitPos the position for the split
+         * @return a use position list containing all entries removed from this list that have a use position greater or equal
+         *         than {@code splitPos}
+         */
+        public UsePosList splitAt(int splitPos) {
+            int i = size() - 1;
+            int len = 0;
+            while (i >= 0 && usePos(i) < splitPos) {
+                --i;
+                len += 2;
+            }
+            int listSplitIndex = (i + 1) * 2;
+            IntList childList = list;
+            list = IntList.copy(this.list, listSplitIndex, len);
+            childList.setSize(listSplitIndex);
+            UsePosList child = new UsePosList(childList);
+            return child;
+        }
+
+        /**
+         * Gets the use position at a specified index in this list.
+         *
+         * @param index the index of the entry for which the use position is returned
+         * @return the use position of entry {@code index} in this list
+         */
+        public int usePos(int index) {
+            return list.get(index << 1);
+        }
+
+        /**
+         * Gets the register priority for the use position at a specified index in this list.
+         *
+         * @param index the index of the entry for which the register priority is returned
+         * @return the register priority of entry {@code index} in this list
+         */
+        public RegisterPriority registerPriority(int index) {
+            return RegisterPriority.VALUES[list.get((index << 1) + 1)];
+        }
+
+        public void add(int usePos, RegisterPriority registerPriority) {
+            assert list.size() == 0 || usePos(size() - 1) > usePos;
+            list.add(usePos);
+            list.add(registerPriority.ordinal());
+        }
+
+        public int size() {
+            return list.size() >> 1;
+        }
+
+        public void removeLowestUsePos() {
+            list.setSize(list.size() - 2);
+        }
+
+        public void setRegisterPriority(int index, RegisterPriority registerPriority) {
+            list.set(index * 2, registerPriority.ordinal());
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder buf = new StringBuilder("[");
+            for (int i = size() - 1; i >= 0; --i) {
+                if (buf.length() != 1) {
+                    buf.append(", ");
+                }
+                RegisterPriority prio = registerPriority(i);
+                buf.append(usePos(i)).append(" -> ").append(prio.ordinal()).append(':').append(prio);
+            }
+            return buf.append("]").toString();
+        }
+    }
+
+    /**
+     * The {@linkplain CiRegisterValue register} or {@linkplain CiVariable variable} for this interval prior to register allocation.
+     */
+    public final CiValue operand;
+
+    /**
+     * The {@linkplain OperandPool#operandNumber(CiValue) operand number} for this interval's {@linkplain #operand operand}.
+     */
+    public final int operandNumber;
+
+    /**
+     * The {@linkplain CiRegisterValue register}, {@linkplain CiStackSlot spill slot} or {@linkplain CiAddress address} assigned to this interval.
+     */
+    private CiValue location;
+
+    /**
+     * The stack slot to which all splits of this interval are spilled if necessary.
+     */
+    private CiStackSlot spillSlot;
+
+    /**
+     * The kind of this interval.
+     * Only valid if this is a {@linkplain #isVariable() variable}.
+     */
+    private CiKind kind;
+
+    /**
+     * The head of the list of ranges describing this interval. This list is sorted by {@linkplain LIRInstruction#id instruction ids}.
+     */
+    private Range first;
+
+    /**
+     * List of (use-positions, register-priorities) pairs, sorted by use-positions.
+     */
+    private UsePosList usePosList;
+
+    /**
+     * Iterator used to traverse the ranges of an interval.
+     */
+    private Range current;
+
+    /**
+     * Link to next interval in a sorted list of intervals that ends with {@link #EndMarker}.
+     */
+    Interval next;
+
+    /**
+     * The linear-scan state of this interval.
+     */
+    State state;
+
+    private int cachedTo; // cached value: to of last range (-1: not cached)
+
+    /**
+     * The interval from which this one is derived. If this is a {@linkplain #isSplitParent() split parent}, it points to itself.
+     */
+    private Interval splitParent;
+
+    /**
+     * List of all intervals that are split off from this interval. This is only used if this is a {@linkplain #isSplitParent() split parent}.
+     */
+    private List<Interval> splitChildren = Collections.emptyList();
+
+    /**
+     * Current split child that has been active or inactive last (always stored in split parents).
+     */
+    private Interval currentSplitChild;
+
+    /**
+     * Specifies if move is inserted between currentSplitChild and this interval when interval gets active the first time.
+     */
+    private boolean insertMoveWhenActivated;
+
+    /**
+     * For spill move optimization.
+     */
+    private SpillState spillState;
+
+    /**
+     * Position where this interval is defined (if defined only once).
+     */
+    private int spillDefinitionPos;
+
+    /**
+     * This interval should be assigned the same location as the hint interval.
+     */
+    private Interval locationHint;
+
+    void assignLocation(CiValue location) {
+        if (location.isRegister()) {
+            assert this.location == null : "cannot re-assign location for " + this;
+            if (location.kind == CiKind.Illegal && kind != CiKind.Illegal) {
+                location = location.asRegister().asValue(kind);
+            }
+        } else {
+            assert this.location == null || this.location.isRegister() : "cannot re-assign location for " + this;
+            assert location.isStackSlot();
+            assert location.kind != CiKind.Illegal;
+            assert location.kind == this.kind;
+        }
+        this.location = location;
+    }
+
+    /**
+     * Gets the {@linkplain CiRegisterValue register}, {@linkplain CiStackSlot spill slot} or {@linkplain CiAddress address} assigned to this interval.
+     */
+    public CiValue location() {
+        return location;
+    }
+
+    public CiKind kind() {
+        assert !operand.isRegister() : "cannot access type for fixed interval";
+        return kind;
+    }
+
+    void setKind(CiKind kind) {
+        assert operand.isRegister() || this.kind == CiKind.Illegal || this.kind == kind : "overwriting existing type";
+        assert kind == kind.stackKind() || kind == CiKind.Short : "these kinds should have int type registers";
+        this.kind = kind;
+    }
+
+    public Range first() {
+        return first;
+    }
+
+    int from() {
+        return first.from;
+    }
+
+    int to() {
+        if (cachedTo == -1) {
+            cachedTo = calcTo();
+        }
+        assert cachedTo == calcTo() : "invalid cached value";
+        return cachedTo;
+    }
+
+    int numUsePositions() {
+        return usePosList.size();
+    }
+
+    void setLocationHint(Interval interval) {
+        locationHint = interval;
+    }
+
+    boolean isSplitParent() {
+        return splitParent == this;
+    }
+
+    boolean isSplitChild() {
+        return splitParent != this;
+    }
+
+    /**
+     * Gets the split parent for this interval.
+     */
+    public Interval splitParent() {
+        assert splitParent.isSplitParent() : "not a split parent: " + this;
+        return splitParent;
+    }
+
+    /**
+     * Gets the canonical spill slot for this interval.
+     */
+    CiStackSlot spillSlot() {
+        return splitParent().spillSlot;
+    }
+
+    void setSpillSlot(CiStackSlot slot) {
+        assert splitParent().spillSlot == null : "connot overwrite existing spill slot";
+        splitParent().spillSlot = slot;
+    }
+
+    Interval currentSplitChild() {
+        return splitParent().currentSplitChild;
+    }
+
+    void makeCurrentSplitChild() {
+        splitParent().currentSplitChild = this;
+    }
+
+    boolean insertMoveWhenActivated() {
+        return insertMoveWhenActivated;
+    }
+
+    void setInsertMoveWhenActivated(boolean b) {
+        insertMoveWhenActivated = b;
+    }
+
+    // for spill optimization
+    public SpillState spillState() {
+        return splitParent().spillState;
+    }
+
+    int spillDefinitionPos() {
+        return splitParent().spillDefinitionPos;
+    }
+
+    void setSpillState(SpillState state) {
+        assert state.ordinal() >= spillState().ordinal() : "state cannot decrease";
+        splitParent().spillState = state;
+    }
+
+    void setSpillDefinitionPos(int pos) {
+        assert spillDefinitionPos() == -1 : "cannot set the position twice";
+        splitParent().spillDefinitionPos = pos;
+    }
+
+    // returns true if this interval has a shadow copy on the stack that is always correct
+    boolean alwaysInMemory() {
+        return splitParent().spillState == SpillState.StoreAtDefinition || splitParent().spillState == SpillState.StartInMemory;
+    }
+
+    void removeFirstUsePos() {
+        usePosList.removeLowestUsePos();
+    }
+
+    // test intersection
+    boolean intersects(Interval i) {
+        return first.intersects(i.first);
+    }
+
+    int intersectsAt(Interval i) {
+        return first.intersectsAt(i.first);
+    }
+
+    // range iteration
+    void rewindRange() {
+        current = first;
+    }
+
+    void nextRange() {
+        assert this != EndMarker : "not allowed on sentinel";
+        current = current.next;
+    }
+
+    int currentFrom() {
+        return current.from;
+    }
+
+    int currentTo() {
+        return current.to;
+    }
+
+    boolean currentAtEnd() {
+        return current == Range.EndMarker;
+    }
+
+    boolean currentIntersects(Interval it) {
+        return current.intersects(it.current);
+    }
+
+    int currentIntersectsAt(Interval it) {
+        return current.intersectsAt(it.current);
+    }
+
+    /**
+     * Sentinel interval to denote the end of an interval list.
+     */
+    static final Interval EndMarker = new Interval(CiValue.IllegalValue, -1);
+
+    Interval(CiValue operand, int operandNumber) {
+        C1XMetrics.LSRAIntervalsCreated++;
+        assert operand != null;
+        this.operand = operand;
+        this.operandNumber = operandNumber;
+        if (operand.isRegister()) {
+            location = operand;
+        } else {
+            assert operand.isIllegal() || operand.isVariable();
+        }
+        this.kind = CiKind.Illegal;
+        this.first = Range.EndMarker;
+        this.usePosList = new UsePosList(4);
+        this.current = Range.EndMarker;
+        this.next = EndMarker;
+        this.cachedTo = -1;
+        this.spillState = SpillState.NoDefinitionFound;
+        this.spillDefinitionPos = -1;
+        splitParent = this;
+        currentSplitChild = this;
+    }
+
+    int calcTo() {
+        assert first != Range.EndMarker : "interval has no range";
+
+        Range r = first;
+        while (r.next != Range.EndMarker) {
+            r = r.next;
+        }
+        return r.to;
+    }
+
+    // consistency check of split-children
+    boolean checkSplitChildren() {
+        if (!splitChildren.isEmpty()) {
+            assert isSplitParent() : "only split parents can have children";
+
+            for (int i = 0; i < splitChildren.size(); i++) {
+                Interval i1 = splitChildren.get(i);
+
+                assert i1.splitParent() == this : "not a split child of this interval";
+                assert i1.kind() == kind() : "must be equal for all split children";
+                assert i1.spillSlot() == spillSlot() : "must be equal for all split children";
+
+                for (int j = i + 1; j < splitChildren.size(); j++) {
+                    Interval i2 = splitChildren.get(j);
+
+                    assert i1.operand != i2.operand : "same register number";
+
+                    if (i1.from() < i2.from()) {
+                        assert i1.to() <= i2.from() && i1.to() < i2.to() : "intervals overlapping";
+                    } else {
+                        assert i2.from() < i1.from() : "intervals start at same opId";
+                        assert i2.to() <= i1.from() && i2.to() < i1.to() : "intervals overlapping";
+                    }
+                }
+            }
+        }
+
+        return true;
+    }
+
+    public Interval locationHint(boolean searchSplitChild, LinearScan allocator) {
+        if (!searchSplitChild) {
+            return locationHint;
+        }
+
+        if (locationHint != null) {
+            assert locationHint.isSplitParent() : "ony split parents are valid hint registers";
+
+            if (locationHint.location != null && locationHint.location.isRegister()) {
+                return locationHint;
+            } else if (!locationHint.splitChildren.isEmpty()) {
+                // search the first split child that has a register assigned
+                int len = locationHint.splitChildren.size();
+                for (int i = 0; i < len; i++) {
+                    Interval interval = locationHint.splitChildren.get(i);
+                    if (interval.location != null && interval.location.isRegister()) {
+                        return interval;
+                    }
+                }
+            }
+        }
+
+        // no hint interval found that has a register assigned
+        return null;
+    }
+
+    Interval getSplitChildAtOpId(int opId, LIRInstruction.OperandMode mode, LinearScan allocator) {
+        assert isSplitParent() : "can only be called for split parents";
+        assert opId >= 0 : "invalid opId (method cannot be called for spill moves)";
+
+        if (splitChildren.isEmpty()) {
+            assert this.covers(opId, mode) : this + " does not cover " + opId;
+            return this;
+        } else {
+            Interval result = null;
+            int len = splitChildren.size();
+
+            // in outputMode, the end of the interval (opId == cur.to()) is not valid
+            int toOffset = (mode == LIRInstruction.OperandMode.Output ? 0 : 1);
+
+            int i;
+            for (i = 0; i < len; i++) {
+                Interval cur = splitChildren.get(i);
+                if (cur.from() <= opId && opId < cur.to() + toOffset) {
+                    if (i > 0) {
+                        // exchange current split child to start of list (faster access for next call)
+                        Util.atPutGrow(splitChildren, i, splitChildren.get(0), null);
+                        Util.atPutGrow(splitChildren, 0, cur, null);
+                    }
+
+                    // interval found
+                    result = cur;
+                    break;
+                }
+            }
+
+            assert checkSplitChild(result, opId, allocator, toOffset, mode);
+            return result;
+        }
+    }
+
+    private boolean checkSplitChild(Interval result, int opId, LinearScan allocator, int toOffset, LIRInstruction.OperandMode mode) {
+        if (result == null) {
+            // this is an error
+            StringBuilder msg = new StringBuilder(this.toString()).append(" has no child at ").append(opId);
+            if (!splitChildren.isEmpty()) {
+                Interval first = splitChildren.get(0);
+                Interval last = splitChildren.get(splitChildren.size() - 1);
+                msg.append(" (first = ").append(first).append(", last = ").append(last).append(")");
+            }
+            throw new CiBailout("Linear Scan Error: " + msg);
+        }
+
+        if (!splitChildren.isEmpty()) {
+            for (Interval interval : splitChildren) {
+                if (interval != result && interval.from() <= opId && opId < interval.to() + toOffset) {
+                    TTY.println(String.format("two valid result intervals found for opId %d: %d and %d", opId, result.operandNumber, interval.operandNumber));
+                    TTY.println(result.logString(allocator));
+                    TTY.println(interval.logString(allocator));
+                    throw new CiBailout("two valid result intervals found");
+                }
+            }
+        }
+        assert result.covers(opId, mode) : "opId not covered by interval";
+        return true;
+    }
+
+    // returns the last split child that ends before the given opId
+    Interval getSplitChildBeforeOpId(int opId) {
+        assert opId >= 0 : "invalid opId";
+
+        Interval parent = splitParent();
+        Interval result = null;
+
+        assert !parent.splitChildren.isEmpty() : "no split children available";
+        int len = parent.splitChildren.size();
+
+        for (int i = len - 1; i >= 0; i--) {
+            Interval cur = parent.splitChildren.get(i);
+            if (cur.to() <= opId && (result == null || result.to() < cur.to())) {
+                result = cur;
+            }
+        }
+
+        assert result != null : "no split child found";
+        return result;
+    }
+
+    // checks if opId is covered by any split child
+    boolean splitChildCovers(int opId, LIRInstruction.OperandMode mode) {
+        assert isSplitParent() : "can only be called for split parents";
+        assert opId >= 0 : "invalid opId (method can not be called for spill moves)";
+
+        if (splitChildren.isEmpty()) {
+            // simple case if interval was not split
+            return covers(opId, mode);
+
+        } else {
+            // extended case: check all split children
+            int len = splitChildren.size();
+            for (int i = 0; i < len; i++) {
+                Interval cur = splitChildren.get(i);
+                if (cur.covers(opId, mode)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    // Note: use positions are sorted descending . first use has highest index
+    int firstUsage(RegisterPriority minRegisterPriority) {
+        assert operand.isVariable() : "cannot access use positions for fixed intervals";
+
+        for (int i = usePosList.size() - 1; i >= 0; --i) {
+            RegisterPriority registerPriority = usePosList.registerPriority(i);
+            if (registerPriority.greaterEqual(minRegisterPriority)) {
+                return usePosList.usePos(i);
+            }
+        }
+        return Integer.MAX_VALUE;
+    }
+
+    int nextUsage(RegisterPriority minRegisterPriority, int from) {
+        assert operand.isVariable() : "cannot access use positions for fixed intervals";
+
+        for (int i = usePosList.size() - 1; i >= 0; --i) {
+            int usePos = usePosList.usePos(i);
+            if (usePos >= from && usePosList.registerPriority(i).greaterEqual(minRegisterPriority)) {
+                return usePos;
+            }
+        }
+        return Integer.MAX_VALUE;
+    }
+
+    int nextUsageExact(RegisterPriority exactRegisterPriority, int from) {
+        assert operand.isVariable() : "cannot access use positions for fixed intervals";
+
+        for (int i = usePosList.size() - 1; i >= 0; --i) {
+            int usePos = usePosList.usePos(i);
+            if (usePos >= from && usePosList.registerPriority(i) == exactRegisterPriority) {
+                return usePos;
+            }
+        }
+        return Integer.MAX_VALUE;
+    }
+
+    int previousUsage(RegisterPriority minRegisterPriority, int from) {
+        assert operand.isVariable() : "cannot access use positions for fixed intervals";
+
+        int prev = 0;
+        for (int i = usePosList.size() - 1; i >= 0; --i) {
+            int usePos = usePosList.usePos(i);
+            if (usePos > from) {
+                return prev;
+            }
+            if (usePosList.registerPriority(i).greaterEqual(minRegisterPriority)) {
+                prev = usePos;
+            }
+        }
+        return prev;
+    }
+
+    void addUsePos(int pos, RegisterPriority registerPriority) {
+        assert covers(pos, LIRInstruction.OperandMode.Input) : "use position not covered by live range";
+
+        // do not add use positions for precolored intervals because they are never used
+        if (registerPriority != RegisterPriority.None && operand.isVariable()) {
+            if (C1XOptions.DetailedAsserts) {
+                for (int i = 0; i < usePosList.size(); i++) {
+                    assert pos <= usePosList.usePos(i) : "already added a use-position with lower position";
+                    if (i > 0) {
+                        assert usePosList.usePos(i) < usePosList.usePos(i - 1) : "not sorted descending";
+                    }
+                }
+            }
+
+            // Note: addUse is called in descending order, so list gets sorted
+            // automatically by just appending new use positions
+            int len = usePosList.size();
+            if (len == 0 || usePosList.usePos(len - 1) > pos) {
+                usePosList.add(pos, registerPriority);
+            } else if (usePosList.registerPriority(len - 1).lessThan(registerPriority)) {
+                assert usePosList.usePos(len - 1) == pos : "list not sorted correctly";
+                usePosList.setRegisterPriority(len - 1, registerPriority);
+            }
+        }
+    }
+
+    void addRange(int from, int to) {
+        assert from < to : "invalid range";
+        assert first() == Range.EndMarker || to < first().next.from : "not inserting at begin of interval";
+        assert from <= first().to : "not inserting at begin of interval";
+
+        if (first.from <= to) {
+            assert first != Range.EndMarker;
+            // join intersecting ranges
+            first.from = Math.min(from, first().from);
+            first.to = Math.max(to, first().to);
+        } else {
+            // insert new range
+            first = new Range(from, to, first());
+        }
+    }
+
+    Interval newSplitChild(LinearScan allocator) {
+        // allocate new interval
+        Interval parent = splitParent();
+        Interval result = allocator.createDerivedInterval(parent);
+        result.setKind(kind());
+
+        result.splitParent = parent;
+        result.setLocationHint(parent);
+
+        // insert new interval in children-list of parent
+        if (parent.splitChildren.isEmpty()) {
+            assert isSplitParent() : "list must be initialized at first split";
+
+            // Create new non-shared list
+            parent.splitChildren = new ArrayList<Interval>(4);
+            parent.splitChildren.add(this);
+        }
+        parent.splitChildren.add(result);
+
+        return result;
+    }
+
+    /**
+     * Splits this interval at a specified position and returns the remainder as a new <i>child</i> interval
+     * of this interval's {@linkplain #splitParent() parent} interval.
+     * <p>
+     * When an interval is split, a bi-directional link is established between the original <i>parent</i>
+     * interval and the <i>children</i> intervals that are split off this interval.
+     * When a split child is split again, the new created interval is a direct child
+     * of the original parent. That is, there is no tree of split children stored, just a flat list.
+     * All split children are spilled to the same {@linkplain #spillSlot spill slot}.
+     *
+     * @param splitPos the position at which to split this interval
+     * @param allocator the register allocator context
+     * @return the child interval split off from this interval
+     */
+    Interval split(int splitPos, LinearScan allocator) {
+        assert operand.isVariable() : "cannot split fixed intervals";
+
+        // allocate new interval
+        Interval result = newSplitChild(allocator);
+
+        // split the ranges
+        Range prev = null;
+        Range cur = first;
+        while (cur != Range.EndMarker && cur.to <= splitPos) {
+            prev = cur;
+            cur = cur.next;
+        }
+        assert cur != Range.EndMarker : "split interval after end of last range";
+
+        if (cur.from < splitPos) {
+            result.first = new Range(splitPos, cur.to, cur.next);
+            cur.to = splitPos;
+            cur.next = Range.EndMarker;
+
+        } else {
+            assert prev != null : "split before start of first range";
+            result.first = cur;
+            prev.next = Range.EndMarker;
+        }
+        result.current = result.first;
+        cachedTo = -1; // clear cached value
+
+        // split list of use positions
+        result.usePosList = usePosList.splitAt(splitPos);
+
+        if (C1XOptions.DetailedAsserts) {
+            for (int i = 0; i < usePosList.size(); i++) {
+                assert usePosList.usePos(i) < splitPos;
+            }
+            for (int i = 0; i < result.usePosList.size(); i++) {
+                assert result.usePosList.usePos(i) >= splitPos;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Splits this interval at a specified position and returns
+     * the head as a new interval (this interval is the tail).
+     *
+     * Currently, only the first range can be split, and the new interval must not have split positions
+     */
+    Interval splitFromStart(int splitPos, LinearScan allocator) {
+        assert operand.isVariable() : "cannot split fixed intervals";
+        assert splitPos > from() && splitPos < to() : "can only split inside interval";
+        assert splitPos > first.from && splitPos <= first.to : "can only split inside first range";
+        assert firstUsage(RegisterPriority.None) > splitPos : "can not split when use positions are present";
+
+        // allocate new interval
+        Interval result = newSplitChild(allocator);
+
+        // the new interval has only one range (checked by assertion above,
+        // so the splitting of the ranges is very simple
+        result.addRange(first.from, splitPos);
+
+        if (splitPos == first.to) {
+            assert first.next != Range.EndMarker : "must not be at end";
+            first = first.next;
+        } else {
+            first.from = splitPos;
+        }
+
+        return result;
+    }
+
+    // returns true if the opId is inside the interval
+    boolean covers(int opId, LIRInstruction.OperandMode mode) {
+        Range cur = first;
+
+        while (cur != Range.EndMarker && cur.to < opId) {
+            cur = cur.next;
+        }
+        if (cur != Range.EndMarker) {
+            assert cur.to != cur.next.from : "ranges not separated";
+
+            if (mode == LIRInstruction.OperandMode.Output) {
+                return cur.from <= opId && opId < cur.to;
+            } else {
+                return cur.from <= opId && opId <= cur.to;
+            }
+        }
+        return false;
+    }
+
+    // returns true if the interval has any hole between holeFrom and holeTo
+    // (even if the hole has only the length 1)
+    boolean hasHoleBetween(int holeFrom, int holeTo) {
+        assert holeFrom < holeTo : "check";
+        assert from() <= holeFrom && holeTo <= to() : "index out of interval";
+
+        Range cur = first;
+        while (cur != Range.EndMarker) {
+            assert cur.to < cur.next.from : "no space between ranges";
+
+            // hole-range starts before this range . hole
+            if (holeFrom < cur.from) {
+                return true;
+
+                // hole-range completely inside this range . no hole
+            } else {
+                if (holeTo <= cur.to) {
+                    return false;
+
+                    // overlapping of hole-range with this range . hole
+                } else {
+                    if (holeFrom <= cur.to) {
+                        return true;
+                    }
+                }
+            }
+
+            cur = cur.next;
+        }
+
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        String from = "?";
+        String to = "?";
+        if (first != null && first != Range.EndMarker) {
+            from = String.valueOf(from());
+            to = String.valueOf(to());
+        }
+        String location = this.location == null ? "" : "@" + this.location.name();
+        return operandNumber + ":" + operand + (operand.isRegister() ? "" : location) + "[" + from + "," + to + "]";
+    }
+
+    /**
+     * Gets the use position information for this interval.
+     */
+    public UsePosList usePosList() {
+        return usePosList;
+    }
+
+    /**
+     * Gets a single line string for logging the details of this interval to a log stream.
+     *
+     * @param allocator the register allocator context
+     */
+    public String logString(LinearScan allocator) {
+        StringBuilder buf = new StringBuilder(100);
+        buf.append(operandNumber).append(':').append(operand).append(' ');
+        if (!operand.isRegister()) {
+            if (location != null) {
+                buf.append("location{").append(location).append("} ");
+            }
+        }
+
+        buf.append("hints{").append(splitParent.operandNumber);
+        Interval hint = locationHint(false, allocator);
+        if (hint != null && hint.operandNumber != splitParent.operandNumber) {
+            buf.append(", ").append(hint.operandNumber);
+        }
+        buf.append("} ranges{");
+
+        // print ranges
+        Range cur = first;
+        while (cur != Range.EndMarker) {
+            if (cur != first) {
+                buf.append(", ");
+            }
+            buf.append(cur);
+            cur = cur.next;
+            assert cur != null : "range list not closed with range sentinel";
+        }
+        buf.append("} uses{");
+
+        // print use positions
+        int prev = 0;
+        for (int i = usePosList.size() - 1; i >= 0; --i) {
+            assert prev < usePosList.usePos(i) : "use positions not sorted";
+            if (i != usePosList.size() - 1) {
+                buf.append(", ");
+            }
+            buf.append(usePosList.usePos(i)).append(':').append(usePosList.registerPriority(i));
+            prev = usePosList.usePos(i);
+        }
+        return buf.append("} spill-state{").append(spillState()).append("}").toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/src/com/sun/c1x/alloc/IntervalWalker.java	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.c1x.alloc;
+
+import com.sun.c1x.*;
+import com.sun.c1x.alloc.Interval.*;
+import com.sun.c1x.debug.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class IntervalWalker {
+
+    protected final C1XCompilation compilation;
+    protected final LinearScan allocator;
+
+    /**
+     * Sorted list of intervals, not live before the current position.
+     */
+    RegisterBindingLists unhandledLists;
+
+    /**
+     * Sorted list of intervals, live at the current position.
+     */
+    RegisterBindingLists activeLists;
+
+    /**
+     * Sorted list of intervals in a life time hole at the current position.
+     */
+    RegisterBindingLists inactiveLists;
+
+    /**
+     * The current interval (taken from the unhandled list) being processed.
+     */
+    protected Interval current;
+
+    /**
+     * The current position (intercept point through the intervals).
+     */
+    protected int currentPosition;
+
+    /**
+     * The binding of the current interval being processed.
+     */
+    protected RegisterBinding currentBinding;
+
+    /**
+     * Processes the {@linkplain #current} interval in an attempt to allocate a physical
+     * register to it and thus allow it to be moved to a list of {@linkplain #activeLists active} intervals.
+     *
+     * @return {@code true} if a register was allocated to the {@linkplain #current} interval
+     */
+    boolean activateCurrent() {
+        return true;
+    }
+
+    void walkBefore(int lirOpId) {
+        walkTo(lirOpId - 1);
+    }
+
+    void walk() {
+        walkTo(Integer.MAX_VALUE);
+    }
+
+    /**
+     * Creates a new interval walker.
+     *
+     * @param allocator the register allocator context
+     * @param unhandledFixed the list of unhandled {@linkplain RegisterBinding#Fixed fixed} intervals
+     * @param unhandledAny the list of unhandled {@linkplain RegisterBinding#Any non-fixed} intervals
+     */
+    IntervalWalker(LinearScan allocator, Interval unhandledFixed, Interval unhandledAny) {
+        this.compilation = allocator.compilation;
+        this.allocator = allocator;
+
+        unhandledLists = new RegisterBindingLists(unhandledFixed, unhandledAny);
+        activeLists = new RegisterBindingLists(Interval.EndMarker, Interval.EndMarker);
+        inactiveLists = new RegisterBindingLists(Interval.EndMarker, Interval.EndMarker);
+        currentPosition = -1;
+        current = null;
+        nextInterval();
+    }
+
+    void removeFromList(Interval interval) {
+        if (interval.state == State.Active) {
+            activeLists.remove(RegisterBinding.Any, interval);
+        } else {
+            assert interval.state == State.Inactive : "invalid state";
+            inactiveLists.remove(RegisterBinding.Any, interval);
+        }
+    }
+
+    void walkTo(State state, int from) {
+        assert state == State.Active || state == State.Inactive : "wrong state";
+        for (RegisterBinding binding : RegisterBinding.VALUES) {
+            Interval prevprev = null;
+            Interval prev = (state == State.Active) ? activeLists.get(binding) : inactiveLists.get(binding);
+            Interval next = prev;
+            while (next.currentFrom() <= from) {
+                Interval cur = next;
+                next = cur.next;
+
+                boolean rangeHasChanged = false;
+                while (cur.currentTo() <= from) {
+                    cur.nextRange();
+                    rangeHasChanged = true;
+                }
+
+                // also handle move from inactive list to active list
+                rangeHasChanged = rangeHasChanged || (state == State.Inactive && cur.currentFrom() <= from);
+
+                if (rangeHasChanged) {
+                    // remove cur from list
+                    if (prevprev == null) {
+                        if (state == State.Active) {
+                            activeLists.set(binding, next);
+                        } else {
+                            inactiveLists.set(binding, next);
+                        }
+                    } else {
+                        prevprev.next = next;
+                    }
+                    prev = next;
+                    if (cur.currentAtEnd()) {
+                        // move to handled state (not maintained as a list)
+                        cur.state = State.Handled;
+                        intervalMoved(cur, binding, state, State.Handled);
+                    } else if (cur.currentFrom() <= from) {
+                        // sort into active list
+                        activeLists.addToListSortedByCurrentFromPositions(binding, cur);
+                        cur.state = State.Active;
+                        if (prev == cur) {
+                            assert state == State.Active : "check";
+                            prevprev = prev;
+                            prev = cur.next;
+                        }
+                        intervalMoved(cur, binding, state, State.Active);
+                    } else {
+                        // sort into inactive list
+                        inactiveLists.addToListSortedByCurrentFromPositions(binding, cur);
+                        cur.state = State.Inactive;
+                        if (prev == cur) {
+                            assert state == State.Inactive : "check";
+                            prevprev = prev;
+                            prev = cur.next;
+                        }
+                        intervalMoved(cur, binding, state, State.Inactive);
+                    }
+                } else {
+                    prevprev = prev;
+                    prev = cur.next;
+                }
+            }
+        }
+    }
+
+    void nextInterval() {
+        RegisterBinding binding;
+        Interval any = unhandledLists.any;
+        Interval fixed = unhandledLists.fixed;
+
+        if (any != Interval.EndMarker) {
+            // intervals may start at same position . prefer fixed interval
+            binding = fixed != Interval.EndMarker && fixed.from() <= any.from() ? RegisterBinding.Fixed : RegisterBinding.Any;
+
+            assert binding == RegisterBinding.Fixed && fixed.from() <= any.from() || binding == RegisterBinding.Any && any.from() <= fixed.from() : "wrong interval!!!";
+            assert any == Interval.EndMarker || fixed == Interval.EndMarker || any.from() != fixed.from() || binding == RegisterBinding.Fixed : "if fixed and any-Interval start at same position, fixed must be processed first";
+
+        } else if (fixed != Interval.EndMarker) {
+            binding = RegisterBinding.Fixed;
+        } else {
+            current = null;
+            return;
+        }
+        currentBinding = binding;
+        current = unhandledLists.get(binding);
+        unhandledLists.set(binding, current.next);
+        current.next = Interval.EndMarker;
+        current.rewindRange();
+    }
+
+    void walkTo(int toOpId) {
+        assert currentPosition <= toOpId : "can not walk backwards";
+        while (current != null) {
+            boolean isActive = current.from() <= toOpId;
+            int opId = isActive ? current.from() : toOpId;
+
+            if (C1XOptions.TraceLinearScanLevel >= 2 && !TTY.isSuppressed()) {
+                if (currentPosition < opId) {
+                    TTY.println();
+                    TTY.println("walkTo(%d) *", opId);
+                }
+            }
+
+            // set currentPosition prior to call of walkTo
+            currentPosition = opId;
+
+            // call walkTo even if currentPosition == id
+            walkTo(State.Active, opId);
+            walkTo(State.Inactive, opId);
+
+            if (isActive) {
+                current.state = State.Active;
+                if (activateCurrent()) {
+                    activeLists.addToListSortedByCurrentFromPositions(currentBinding, current);
+                    intervalMoved(current, currentBinding, State.Unhandled, State.Active);
+                }
+
+                nextInterval();
+            } else {
+                return;
+            }
+        }
+    }
+
+    private void intervalMoved(Interval interval, RegisterBinding kind, State from, State to) {
+        // intervalMoved() is called whenever an interval moves from one interval list to another.
+        // In the implementation of this method it is prohibited to move the interval to any list.
+        if (C1XOptions.TraceLinearScanLevel >= 4 && !TTY.isSuppressed()) {
+            TTY.print(from.toString() + " to " + to.toString());
+            TTY.fillTo(23);
+            TTY.out().println(interval.logString(allocator));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/src/com/sun/c1x/alloc/LIRInsertionBuffer.java	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.c1x.alloc;
+
+import java.util.*;
+
+import com.sun.c1x.lir.*;
+import com.sun.c1x.util.*;
+import com.sun.cri.ci.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class LIRInsertionBuffer {
+
+    private LIRList lir; // the lir list where ops of this buffer should be inserted later (null when uninitialized)
+
+    // list of insertion points. index and count are stored alternately:
+    // indexAndCount[i * 2]: the index into lir list where "count" ops should be inserted
+    // indexAndCount[i * 2 + 1]: the number of ops to be inserted at index
+    private final IntList indexAndCount;
+
+    // the LIROps to be inserted
+    private final List<LIRInstruction> ops;
+
+    private void appendNew(int index, int count) {
+        indexAndCount.add(index);
+        indexAndCount.add(count);
+    }
+
+    private void setCountAt(int i, int value) {
+        indexAndCount.set((i << 1) + 1, value);
+    }
+
+    LIRInsertionBuffer() {
+        ops = new ArrayList<LIRInstruction>(8);
+        indexAndCount = new IntList(8);
+    }
+
+    // must be called before using the insertion buffer
+    void init(LIRList lir) {
+        assert !initialized() : "already initialized";
+        this.lir = lir;
+        indexAndCount.clear();
+        ops.clear();
+    }
+
+    boolean initialized() {
+        return lir != null;
+    }
+
+    // called automatically when the buffer is appended to the LIRList
+    public void finish() {
+        lir = null;
+    }
+
+    // accessors
+    public LIRList lirList() {
+        return lir;
+    }
+
+    public int numberOfInsertionPoints() {
+        return indexAndCount.size() >> 1;
+    }
+
+    public int indexAt(int i) {
+        return indexAndCount.get((i << 1));
+    }
+
+    public int countAt(int i) {
+        return indexAndCount.get((i << 1) + 1);
+    }
+
+    public int numberOfOps() {
+        return ops.size();
+    }
+
+    public LIRInstruction opAt(int i) {
+        return ops.get(i);
+    }
+
+    void move(int index, CiValue src, CiValue dst, LIRDebugInfo info) {
+        append(index, new LIROp1(LIROpcode.Move, src, dst, dst.kind, info));
+    }
+
+    // Implementation of LIRInsertionBuffer
+
+    private void append(int index, LIRInstruction op) {
+        assert indexAndCount.size() % 2 == 0 : "must have a count for each index";
+
+        int i = numberOfInsertionPoints() - 1;
+        if (i < 0 || indexAt(i) < index) {
+            appendNew(index, 1);
+        } else {
+            assert indexAt(i) == index : "can append LIROps in ascending order only";
+            assert countAt(i) > 0 : "check";
+            setCountAt(i, countAt(i) + 1);
+        }
+        ops.add(op);
+
+        assert verify();
+    }
+
+    private boolean verify() {
+        int sum = 0;
+        int prevIdx = -1;
+
+        for (int i = 0; i < numberOfInsertionPoints(); i++) {
+            assert prevIdx < indexAt(i) : "index must be ordered ascending";
+            sum += countAt(i);
+        }
+        assert sum == numberOfOps() : "wrong total sum";
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/src/com/sun/c1x/alloc/LinearScan.java	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,2559 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.c1x.alloc;
+
+import static com.sun.cri.ci.CiUtil.*;
+import static java.lang.reflect.Modifier.*;
+
+import java.util.*;
+
+import com.sun.c1x.*;
+import com.sun.c1x.alloc.Interval.*;
+import com.sun.c1x.debug.*;
+import com.sun.c1x.gen.*;
+import com.sun.c1x.graph.*;
+import com.sun.c1x.ir.*;
+import com.sun.c1x.ir.BlockBegin.BlockFlag;
+import com.sun.c1x.lir.*;
+import com.sun.c1x.lir.LIRInstruction.OperandMode;
+import com.sun.c1x.observer.*;
+import com.sun.c1x.util.*;
+import com.sun.c1x.value.*;
+import com.sun.c1x.value.FrameState.PhiProcedure;
+import com.sun.c1x.value.FrameState.ValueProcedure;
+import com.sun.cri.ci.*;
+import com.sun.cri.ri.*;
+
+/**
+ * An implementation of the linear scan register allocator algorithm described
+ * in <a href="http://doi.acm.org/10.1145/1064979.1064998">"Optimized Interval Splitting in a Linear Scan Register Allocator"</a>
+ * by Christian Wimmer and Hanspeter Moessenboeck.
+ *
+ * @author Christian Wimmer (original HotSpot implementation)
+ * @author Thomas Wuerthinger
+ * @author Doug Simon
+ */
+public final class LinearScan {
+
+    final C1XCompilation compilation;
+    final IR ir;
+    final LIRGenerator gen;
+    final FrameMap frameMap;
+    final RiRegisterAttributes[] registerAttributes;
+    final CiRegister[] registers;
+
+    private static final int INITIAL_SPLIT_INTERVALS_CAPACITY = 32;
+
+    /**
+     * List of blocks in linear-scan order. This is only correct as long as the CFG does not change.
+     */
+    final BlockBegin[] sortedBlocks;
+
+    final OperandPool operands;
+
+    /**
+     * Number of stack slots used for intervals allocated to memory.
+     */
+    int maxSpills;
+
+    /**
+     * Unused spill slot for a single-word value because of alignment of a double-word value.
+     */
+    CiStackSlot unusedSpillSlot;
+
+    /**
+     * Map from {@linkplain #operandNumber(CiValue) operand numbers} to intervals.
+     */
+    Interval[] intervals;
+
+    /**
+     * The number of valid entries in {@link #intervals}.
+     */
+    int intervalsSize;
+
+    /**
+     * The index of the first entry in {@link #intervals} for a {@linkplain #createDerivedInterval(Interval) derived interval}.
+     */
+    int firstDerivedIntervalIndex = -1;
+
+    /**
+     * Intervals sorted by {@link Interval#from()}.
+     */
+    Interval[] sortedIntervals;
+
+    /**
+     * Map from an instruction {@linkplain LIRInstruction#id id} to the instruction.
+     * Entries should be retrieved with {@link #instructionForId(int)} as the id is
+     * not simply an index into this array.
+     */
+    LIRInstruction[] opIdToInstructionMap;
+
+    /**
+     * Map from an instruction {@linkplain LIRInstruction#id id} to the {@linkplain
+     * BlockBegin block} containing the instruction. Entries should be retrieved with
+     * {@link #blockForId(int)} as the id is not simply an index into this array.
+     */
+    BlockBegin[] opIdToBlockMap;
+
+    /**
+     * Bit set for each variable that is contained in each loop.
+     */
+    BitMap2D intervalInLoop;
+
+    public LinearScan(C1XCompilation compilation, IR ir, LIRGenerator gen, FrameMap frameMap) {
+        this.compilation = compilation;
+        this.ir = ir;
+        this.gen = gen;
+        this.frameMap = frameMap;
+        this.maxSpills = frameMap.initialSpillSlot();
+        this.unusedSpillSlot = null;
+        this.sortedBlocks = ir.linearScanOrder().toArray(new BlockBegin[ir.linearScanOrder().size()]);
+        CiRegister[] allocatableRegisters = compilation.registerConfig.getAllocatableRegisters();
+        this.registers = new CiRegister[CiRegister.maxRegisterNumber(allocatableRegisters) + 1];
+        for (CiRegister reg : allocatableRegisters) {
+            registers[reg.number] = reg;
+        }
+        this.registerAttributes = compilation.registerConfig.getAttributesMap();
+        this.operands = gen.operands;
+    }
+
+    /**
+     * Converts an operand (variable or register) to an index in a flat address space covering all the
+     * {@linkplain CiVariable variables} and {@linkplain CiRegisterValue registers} being processed by this
+     * allocator.
+     */
+    int operandNumber(CiValue operand) {
+        return operands.operandNumber(operand);
+    }
+
+    static final IntervalPredicate IS_PRECOLORED_INTERVAL = new IntervalPredicate() {
+        @Override
+        public boolean apply(Interval i) {
+            return i.operand.isRegister();
+        }
+    };
+
+    static final IntervalPredicate IS_VARIABLE_INTERVAL = new IntervalPredicate() {
+        @Override
+        public boolean apply(Interval i) {
+            return i.operand.isVariable();
+        }
+    };
+
+    static final IntervalPredicate IS_OOP_INTERVAL = new IntervalPredicate() {
+        @Override
+        public boolean apply(Interval i) {
+            return !i.operand.isRegister() && i.kind() == CiKind.Object;
+        }
+    };
+
+    /**
+     * Gets an object describing the attributes of a given register according to this register configuration.
+     */
+    RiRegisterAttributes attributes(CiRegister reg) {
+        return registerAttributes[reg.number];
+    }
+
+    /**
+     * Allocates the next available spill slot for a value of a given kind.
+     */
+    CiStackSlot allocateSpillSlot(CiKind kind) {
+        CiStackSlot spillSlot;
+        if (numberOfSpillSlots(kind) == 2) {
+            if (isOdd(maxSpills)) {
+                // alignment of double-slot values
+                // the hole because of the alignment is filled with the next single-slot value
+                assert unusedSpillSlot == null : "wasting a spill slot";
+                unusedSpillSlot = CiStackSlot.get(kind, maxSpills);
+                maxSpills++;
+            }
+            spillSlot = CiStackSlot.get(kind, maxSpills);
+            maxSpills += 2;
+        } else if (unusedSpillSlot != null) {
+            // re-use hole that was the result of a previous double-word alignment
+            spillSlot = unusedSpillSlot;
+            unusedSpillSlot = null;
+        } else {
+            spillSlot = CiStackSlot.get(kind, maxSpills);
+            maxSpills++;
+        }
+
+        return spillSlot;
+    }
+
+    void assignSpillSlot(Interval interval) {
+        // assign the canonical spill slot of the parent (if a part of the interval
+        // is already spilled) or allocate a new spill slot
+        if (interval.spillSlot() != null) {
+            interval.assignLocation(interval.spillSlot());
+        } else {
+            CiStackSlot slot = allocateSpillSlot(interval.kind());
+            interval.setSpillSlot(slot);
+            interval.assignLocation(slot);
+        }
+    }
+
+    /**
+     * Creates a new interval.
+     *
+     * @param operand the operand for the interval
+     * @return the created interval
+     */
+    Interval createInterval(CiValue operand) {
+        assert isProcessed(operand);
+        assert operand.isLegal();
+        int operandNumber = operandNumber(operand);
+        Interval interval = new Interval(operand, operandNumber);
+        assert operandNumber < intervalsSize;
+        assert intervals[operandNumber] == null;
+        intervals[operandNumber] = interval;
+        return interval;
+    }
+
+    /**
+     * Creates an interval as a result of splitting or spilling another interval.
+     *
+     * @param source an interval being split of spilled
+     * @return a new interval derived from {@code source}
+     */
+    Interval createDerivedInterval(Interval source) {
+        if (firstDerivedIntervalIndex == -1) {
+            firstDerivedIntervalIndex = intervalsSize;
+        }
+        if (intervalsSize == intervals.length) {
+            intervals = Arrays.copyOf(intervals, intervals.length * 2);
+        }
+        intervalsSize++;
+        Interval interval = createInterval(operands.newVariable(source.kind()));
+        assert intervals[intervalsSize - 1] == interval;
+        return interval;
+    }
+
+    // copy the variable flags if an interval is split
+    void copyRegisterFlags(Interval from, Interval to) {
+        if (operands.mustBeByteRegister(from.operand)) {
+            operands.setMustBeByteRegister((CiVariable) to.operand);
+        }
+
+        // Note: do not copy the mustStartInMemory flag because it is not necessary for child
+        // intervals (only the very beginning of the interval must be in memory)
+    }
+
+    // access to block list (sorted in linear scan order)
+    int blockCount() {
+        assert sortedBlocks.length == ir.linearScanOrder().size() : "invalid cached block list";
+        return sortedBlocks.length;
+    }
+
+    BlockBegin blockAt(int index) {
+        assert sortedBlocks[index] == ir.linearScanOrder().get(index) : "invalid cached block list";
+        return sortedBlocks[index];
+    }
+
+    /**
+     * Gets the size of the {@link LIRBlock#liveIn} and {@link LIRBlock#liveOut} sets for a basic block. These sets do
+     * not include any operands allocated as a result of creating {@linkplain #createDerivedInterval(Interval) derived
+     * intervals}.
+     */
+    int liveSetSize() {
+        return firstDerivedIntervalIndex == -1 ? operands.size() : firstDerivedIntervalIndex;
+    }
+
+    int numLoops() {
+        return ir.numLoops();
+    }
+
+    boolean isIntervalInLoop(int interval, int loop) {
+        return intervalInLoop.at(interval, loop);
+    }
+
+    Interval intervalFor(CiValue operand) {
+        int operandNumber = operandNumber(operand);
+        assert operandNumber < intervalsSize;
+        return intervals[operandNumber];
+    }
+
+    /**
+     * Gets the highest instruction id allocated by this object.
+     */
+    int maxOpId() {
+        assert opIdToInstructionMap.length > 0 : "no operations";
+        return (opIdToInstructionMap.length - 1) << 1;
+    }
+
+    /**
+     * Converts an {@linkplain LIRInstruction#id instruction id} to an instruction index.
+     * All LIR instructions in a method have an index one greater than their linear-scan order predecesor
+     * with the first instruction having an index of 0.
+     */
+    static int opIdToIndex(int opId) {
+        return opId >> 1;
+    }
+
+    /**
+     * Retrieves the {@link LIRInstruction} based on its {@linkplain LIRInstruction#id id}.
+     *
+     * @param opId an instruction {@linkplain LIRInstruction#id id}
+     * @return the instruction whose {@linkplain LIRInstruction#id} {@code == id}
+     */
+    LIRInstruction instructionForId(int opId) {
+        assert isEven(opId) : "opId not even";
+        LIRInstruction instr = opIdToInstructionMap[opIdToIndex(opId)];
+        assert instr.id == opId;
+        return instr;
+    }
+
+    /**
+     * Gets the block containing a given instruction.
+     *
+     * @param opId an instruction {@linkplain LIRInstruction#id id}
+     * @return the block containing the instruction denoted by {@code opId}
+     */
+    BlockBegin blockForId(int opId) {
+        assert opIdToBlockMap.length > 0 && opId >= 0 && opId <= maxOpId() + 1 : "opId out of range";
+        return opIdToBlockMap[opIdToIndex(opId)];
+    }
+
+    boolean isBlockBegin(int opId) {
+        return opId == 0 || blockForId(opId) != blockForId(opId - 1);
+    }
+
+    boolean coversBlockBegin(int opId1, int opId2) {
+        return blockForId(opId1) != blockForId(opId2);
+    }
+
+    /**
+     * Determines if an {@link LIRInstruction} destroys all caller saved registers.
+     *
+     * @param opId an instruction {@linkplain LIRInstruction#id id}
+     * @return {@code true} if the instruction denoted by {@code id} destroys all caller saved registers.
+     */
+    boolean hasCall(int opId) {
+        assert isEven(opId) : "opId not even";
+        return instructionForId(opId).hasCall;
+    }
+
+    /**
+     * Eliminates moves from register to stack if the stack slot is known to be correct.
+     */
+    void changeSpillDefinitionPos(Interval interval, int defPos) {
+        assert interval.isSplitParent() : "can only be called for split parents";
+
+        switch (interval.spillState()) {
+            case NoDefinitionFound:
+                assert interval.spillDefinitionPos() == -1 : "must no be set before";
+                interval.setSpillDefinitionPos(defPos);
+                interval.setSpillState(SpillState.NoSpillStore);
+                break;
+
+            case NoSpillStore:
+                assert defPos <= interval.spillDefinitionPos() : "positions are processed in reverse order when intervals are created";
+                if (defPos < interval.spillDefinitionPos() - 2 || instructionForId(interval.spillDefinitionPos()).code == LIROpcode.Xir) {
+                    // second definition found, so no spill optimization possible for this interval
+                    interval.setSpillState(SpillState.NoOptimization);
+                } else {
+                    // two consecutive definitions (because of two-operand LIR form)
+                    assert blockForId(defPos) == blockForId(interval.spillDefinitionPos()) : "block must be equal";
+                }
+                break;
+
+            case NoOptimization:
+                // nothing to do
+                break;
+
+            default:
+                throw new CiBailout("other states not allowed at this time");
+        }
+    }
+
+    // called during register allocation
+    void changeSpillState(Interval interval, int spillPos) {
+        switch (interval.spillState()) {
+            case NoSpillStore: {
+                int defLoopDepth = blockForId(interval.spillDefinitionPos()).loopDepth();
+                int spillLoopDepth = blockForId(spillPos).loopDepth();
+
+                if (defLoopDepth < spillLoopDepth) {
+                    // the loop depth of the spilling position is higher then the loop depth
+                    // at the definition of the interval . move write to memory out of loop
+                    // by storing at definitin of the interval
+                    interval.setSpillState(SpillState.StoreAtDefinition);
+                } else {
+                    // the interval is currently spilled only once, so for now there is no
+                    // reason to store the interval at the definition
+                    interval.setSpillState(SpillState.OneSpillStore);
+                }
+                break;
+            }
+
+            case OneSpillStore: {
+                // the interval is spilled more then once, so it is better to store it to
+                // memory at the definition
+                interval.setSpillState(SpillState.StoreAtDefinition);
+                break;
+            }
+
+            case StoreAtDefinition:
+            case StartInMemory:
+            case NoOptimization:
+            case NoDefinitionFound:
+                // nothing to do
+                break;
+
+            default:
+                throw new CiBailout("other states not allowed at this time");
+        }
+    }
+
+    abstract static class IntervalPredicate {
+        abstract boolean apply(Interval i);
+    }
+
+    private static final IntervalPredicate mustStoreAtDefinition = new IntervalPredicate() {
+        @Override
+        public boolean apply(Interval i) {
+            return i.isSplitParent() && i.spillState() == SpillState.StoreAtDefinition;
+        }
+    };
+
+    // called once before assignment of register numbers
+    void eliminateSpillMoves() {
+        if (C1XOptions.TraceLinearScanLevel >= 3) {
+            TTY.println(" Eliminating unnecessary spill moves");
+        }
+
+        // collect all intervals that must be stored after their definition.
+        // the list is sorted by Interval.spillDefinitionPos
+        Interval interval;
+        interval = createUnhandledLists(mustStoreAtDefinition, null).first;
+        if (C1XOptions.DetailedAsserts) {
+            checkIntervals(interval);
+        }
+
+        LIRInsertionBuffer insertionBuffer = new LIRInsertionBuffer();
+        int numBlocks = blockCount();
+        for (int i = 0; i < numBlocks; i++) {
+            BlockBegin block = blockAt(i);
+            List<LIRInstruction> instructions = block.lir().instructionsList();
+            int numInst = instructions.size();
+            boolean hasNew = false;
+
+            // iterate all instructions of the block. skip the first because it is always a label
+            for (int j = 1; j < numInst; j++) {
+                LIRInstruction op = instructions.get(j);
+                int opId = op.id;
+
+                if (opId == -1) {
+                    CiValue resultOperand = op.result();
+                    // remove move from register to stack if the stack slot is guaranteed to be correct.
+                    // only moves that have been inserted by LinearScan can be removed.
+                    assert op.code == LIROpcode.Move : "only moves can have a opId of -1";
+                    assert resultOperand.isVariable() : "LinearScan inserts only moves to variables";
+
+                    LIROp1 op1 = (LIROp1) op;
+                    Interval curInterval = intervalFor(resultOperand);
+
+                    if (!curInterval.location().isRegister() && curInterval.alwaysInMemory()) {
+                        // move target is a stack slot that is always correct, so eliminate instruction
+                        if (C1XOptions.TraceLinearScanLevel >= 4) {
+                            TTY.println("eliminating move from interval %d to %d", operandNumber(op1.operand()), operandNumber(op1.result()));
+                        }
+                        instructions.set(j, null); // null-instructions are deleted by assignRegNum
+                    }
+
+                } else {
+                    // insert move from register to stack just after the beginning of the interval
+                    assert interval == Interval.EndMarker || interval.spillDefinitionPos() >= opId : "invalid order";
+                    assert interval == Interval.EndMarker || (interval.isSplitParent() && interval.spillState() == SpillState.StoreAtDefinition) : "invalid interval";
+
+                    while (interval != Interval.EndMarker && interval.spillDefinitionPos() == opId) {
+                        if (!hasNew) {
+                            // prepare insertion buffer (appended when all instructions of the block are processed)
+                            insertionBuffer.init(block.lir());
+                            hasNew = true;
+                        }
+
+                        CiValue fromLocation = interval.location();
+                        CiValue toLocation = canonicalSpillOpr(interval);
+
+                        assert fromLocation.isRegister() : "from operand must be a register but is: " + fromLocation + " toLocation=" + toLocation + " spillState=" + interval.spillState();
+                        assert toLocation.isStackSlot() : "to operand must be a stack slot";
+
+                        insertionBuffer.move(j, fromLocation, toLocation, null);
+
+                        if (C1XOptions.TraceLinearScanLevel >= 4) {
+                            CiStackSlot slot = interval.spillSlot();
+                            TTY.println("inserting move after definition of interval %d to stack slot %d%s at opId %d",
+                                            interval.operandNumber, slot.index(), slot.inCallerFrame() ? " in caller frame" : "", opId);
+                        }
+
+                        interval = interval.next;
+                    }
+                }
+            } // end of instruction iteration
+
+            if (hasNew) {
+                block.lir().append(insertionBuffer);
+            }
+        } // end of block iteration
+
+        assert interval == Interval.EndMarker : "missed an interval";
+    }
+
+    private void checkIntervals(Interval interval) {
+        Interval prev = null;
+        Interval temp = interval;
+        while (temp != Interval.EndMarker) {
+            assert temp.spillDefinitionPos() > 0 : "invalid spill definition pos";
+            if (prev != null) {
+                assert temp.from() >= prev.from() : "intervals not sorted";
+                assert temp.spillDefinitionPos() >= prev.spillDefinitionPos() : "when intervals are sorted by from :  then they must also be sorted by spillDefinitionPos";
+            }
+
+            assert temp.spillSlot() != null : "interval has no spill slot assigned";
+            assert temp.spillDefinitionPos() >= temp.from() : "invalid order";
+            assert temp.spillDefinitionPos() <= temp.from() + 2 : "only intervals defined once at their start-pos can be optimized";
+
+            if (C1XOptions.TraceLinearScanLevel >= 4) {
+                TTY.println("interval %d (from %d to %d) must be stored at %d", temp.operandNumber, temp.from(), temp.to(), temp.spillDefinitionPos());
+            }
+
+            prev = temp;
+            temp = temp.next;
+        }
+    }
+
+    /**
+     * Numbers all instructions in all blocks. The numbering follows the {@linkplain ComputeLinearScanOrder linear scan order}.
+     */
+    void numberInstructions() {
+        // Assign IDs to LIR nodes and build a mapping, lirOps, from ID to LIRInstruction node.
+        int numBlocks = blockCount();
+        int numInstructions = 0;
+        for (int i = 0; i < numBlocks; i++) {
+            numInstructions += blockAt(i).lir().instructionsList().size();
+        }
+
+        // initialize with correct length
+        opIdToInstructionMap = new LIRInstruction[numInstructions];
+        opIdToBlockMap = new BlockBegin[numInstructions];
+
+        int opId = 0;
+        int index = 0;
+
+        for (int i = 0; i < numBlocks; i++) {
+            BlockBegin block = blockAt(i);
+            block.setFirstLirInstructionId(opId);
+            List<LIRInstruction> instructions = block.lir().instructionsList();
+
+            int numInst = instructions.size();
+            for (int j = 0; j < numInst; j++) {
+                LIRInstruction op = instructions.get(j);
+                op.id = opId;
+
+                opIdToInstructionMap[index] = op;
+                opIdToBlockMap[index] = block;
+                assert instructionForId(opId) == op : "must match";
+
+                index++;
+                opId += 2; // numbering of lirOps by two
+            }
+            block.setLastLirInstructionId(opId - 2);
+        }
+        assert index == numInstructions : "must match";
+        assert (index << 1) == opId : "must match: " + (index << 1);
+    }
+
+    /**
+     * Computes local live sets (i.e. {@link LIRBlock#liveGen} and {@link LIRBlock#liveKill}) separately for each block.
+     */
+    void computeLocalLiveSets() {
+        int numBlocks = blockCount();
+        int liveSize = liveSetSize();
+
+        BitMap2D localIntervalInLoop = new BitMap2D(operands.size(), numLoops());
+
+        // iterate all blocks
+        for (int i = 0; i < numBlocks; i++) {
+            BlockBegin block = blockAt(i);
+            final CiBitMap liveGen = new CiBitMap(liveSize);
+            final CiBitMap liveKill = new CiBitMap(liveSize);
+
+            if (block.isExceptionEntry()) {
+                // Phi functions at the begin of an exception handler are
+                // implicitly defined (= killed) at the beginning of the block.
+                block.stateBefore().forEachLivePhi(block, new PhiProcedure() {
+                    public boolean doPhi(Phi phi) {
+                        liveKill.set(operandNumber(phi.operand()));
+                        return true;
+                    }
+                });
+            }
+
+            List<LIRInstruction> instructions = block.lir().instructionsList();
+            int numInst = instructions.size();
+
+            // iterate all instructions of the block. skip the first because it is always a label
+            assert !instructions.get(0).hasOperands() : "first operation must always be a label";
+            for (int j = 1; j < numInst; j++) {
+                final LIRInstruction op = instructions.get(j);
+
+                // iterate input operands of instruction
+                int n = op.operandCount(LIRInstruction.OperandMode.Input);
+                for (int k = 0; k < n; k++) {
+                    CiValue operand = op.operandAt(LIRInstruction.OperandMode.Input, k);
+
+                    if (operand.isVariable()) {
+                        int operandNum = operandNumber(operand);
+                        if (!liveKill.get(operandNum)) {
+                            liveGen.set(operandNum);
+                            if (C1XOptions.TraceLinearScanLevel >= 4) {
+                                TTY.println("  Setting liveGen for operand %d at instruction %d", operandNum, op.id);
+                            }
+                        }
+                        if (block.loopIndex() >= 0) {
+                            localIntervalInLoop.setBit(operandNum, block.loopIndex());
+                        }
+                    }
+
+                    if (C1XOptions.DetailedAsserts) {
+                        assert operand.isVariableOrRegister() : "visitor should only return register operands";
+                        verifyInput(block, liveKill, operand);
+                    }
+                }
+
+                // Add uses of live locals from interpreter's point of view for proper debug information generation
+                LIRDebugInfo info = op.info;
+                if (info != null) {
+                    info.state.forEachLiveStateValue(new ValueProcedure() {
+                        public void doValue(Value value) {
+                            CiValue operand = value.operand();
+                            if (operand.isVariable()) {
+                                int operandNum = operandNumber(operand);
+                                if (!liveKill.get(operandNum)) {
+                                    liveGen.set(operandNum);
+                                    if (C1XOptions.TraceLinearScanLevel >= 4) {
+                                        TTY.println("  Setting liveGen for value %s, LIR opId %d, operand %d", Util.valueString(value), op.id, operandNum);
+                                    }
+                                }
+                            } else if (operand.isRegister()) {
+                                assert !isProcessed(operand) && !operand.kind.isObject();
+                            } else {
+                                assert operand.isConstant() || operand.isIllegal() : "invalid operand for deoptimization value: " + value;
+                            }
+                        }
+                    });
+                }
+
+                // iterate temp operands of instruction
+                n = op.operandCount(LIRInstruction.OperandMode.Temp);
+                for (int k = 0; k < n; k++) {
+                    CiValue operand = op.operandAt(LIRInstruction.OperandMode.Temp, k);
+
+                    if (operand.isVariable()) {
+                        int varNum = operandNumber(operand);
+                        liveKill.set(varNum);
+                        if (block.loopIndex() >= 0) {
+                            localIntervalInLoop.setBit(varNum, block.loopIndex());
+                        }
+                    }
+
+                    if (C1XOptions.DetailedAsserts) {
+                        assert operand.isVariableOrRegister() : "visitor should only return register operands";
+                        verifyTemp(liveKill, operand);
+                    }
+                }
+
+                // iterate output operands of instruction
+                n = op.operandCount(LIRInstruction.OperandMode.Output);
+                for (int k = 0; k < n; k++) {
+                    CiValue operand = op.operandAt(LIRInstruction.OperandMode.Output, k);
+
+                    if (operand.isVariable()) {
+                        int varNum = operandNumber(operand);
+                        liveKill.set(varNum);
+                        if (block.loopIndex() >= 0) {
+                            localIntervalInLoop.setBit(varNum, block.loopIndex());
+                        }
+                    }
+
+                    if (C1XOptions.DetailedAsserts) {
+                        assert operand.isVariableOrRegister() : "visitor should only return register operands";
+                        // fixed intervals are never live at block boundaries, so
+                        // they need not be processed in live sets
+                        // process them only in debug mode so that this can be checked
+                        verifyTemp(liveKill, operand);
+                    }
+                }
+            } // end of instruction iteration
+
+            LIRBlock lirBlock = block.lirBlock();
+            lirBlock.liveGen = liveGen;
+            lirBlock.liveKill = liveKill;
+            lirBlock.liveIn = new CiBitMap(liveSize);
+            lirBlock.liveOut = new CiBitMap(liveSize);
+
+            if (C1XOptions.TraceLinearScanLevel >= 4) {
+                TTY.println("liveGen  B%d %s", block.blockID, block.lirBlock.liveGen);
+                TTY.println("liveKill B%d %s", block.blockID, block.lirBlock.liveKill);
+            }
+        } // end of block iteration
+
+        intervalInLoop = localIntervalInLoop;
+    }
+
+    private void verifyTemp(CiBitMap liveKill, CiValue operand) {
+        // fixed intervals are never live at block boundaries, so
+        // they need not be processed in live sets
+        // process them only in debug mode so that this can be checked
+        if (!operand.isVariable()) {
+            if (isProcessed(operand)) {
+                liveKill.set(operandNumber(operand));
+            }
+        }
+    }
+
+    private void verifyInput(BlockBegin block, CiBitMap liveKill, CiValue operand) {
+        // fixed intervals are never live at block boundaries, so
+        // they need not be processed in live sets.
+        // this is checked by these assertions to be sure about it.
+        // the entry block may have incoming
+        // values in registers, which is ok.
+        if (!operand.isVariable() && block != ir.startBlock) {
+            if (isProcessed(operand)) {
+                assert liveKill.get(operandNumber(operand)) : "using fixed register that is not defined in this block";
+            }
+        }
+    }
+
+    /**
+     * Performs a backward dataflow analysis to compute global live sets (i.e. {@link LIRBlock#liveIn} and
+     * {@link LIRBlock#liveOut}) for each block.
+     */
+    void computeGlobalLiveSets() {
+        int numBlocks = blockCount();
+        boolean changeOccurred;
+        boolean changeOccurredInBlock;
+        int iterationCount = 0;
+        CiBitMap liveOut = new CiBitMap(liveSetSize()); // scratch set for calculations
+
+        // Perform a backward dataflow analysis to compute liveOut and liveIn for each block.
+        // The loop is executed until a fixpoint is reached (no changes in an iteration)
+        // Exception handlers must be processed because not all live values are
+        // present in the state array, e.g. because of global value numbering
+        do {
+            changeOccurred = false;
+
+            // iterate all blocks in reverse order
+            for (int i = numBlocks - 1; i >= 0; i--) {
+                BlockBegin block = blockAt(i);
+                LIRBlock lirBlock = block.lirBlock();
+
+                changeOccurredInBlock = false;
+
+                // liveOut(block) is the union of liveIn(sux), for successors sux of block
+                int n = block.numberOfSux();
+                int e = block.numberOfExceptionHandlers();
+                if (n + e > 0) {
+                    // block has successors
+                    if (n > 0) {
+                        liveOut.setFrom(block.suxAt(0).lirBlock.liveIn);
+                        for (int j = 1; j < n; j++) {
+                            liveOut.setUnion(block.suxAt(j).lirBlock.liveIn);
+                        }
+                    } else {
+                        liveOut.clearAll();
+                    }
+                    for (int j = 0; j < e; j++) {
+                        liveOut.setUnion(block.exceptionHandlerAt(j).lirBlock.liveIn);
+                    }
+
+                    if (!lirBlock.liveOut.isSame(liveOut)) {
+                        // A change occurred. Swap the old and new live out sets to avoid copying.
+                        CiBitMap temp = lirBlock.liveOut;
+                        lirBlock.liveOut = liveOut;
+                        liveOut = temp;
+
+                        changeOccurred = true;
+                        changeOccurredInBlock = true;
+                    }
+                }
+
+                if (iterationCount == 0 || changeOccurredInBlock) {
+                    // liveIn(block) is the union of liveGen(block) with (liveOut(block) & !liveKill(block))
+                    // note: liveIn has to be computed only in first iteration or if liveOut has changed!
+                    CiBitMap liveIn = lirBlock.liveIn;
+                    liveIn.setFrom(lirBlock.liveOut);
+                    liveIn.setDifference(lirBlock.liveKill);
+                    liveIn.setUnion(lirBlock.liveGen);
+                }
+
+                if (C1XOptions.TraceLinearScanLevel >= 4) {
+                    traceLiveness(changeOccurredInBlock, iterationCount, block);
+                }
+            }
+            iterationCount++;
+
+            if (changeOccurred && iterationCount > 50) {
+                throw new CiBailout("too many iterations in computeGlobalLiveSets");
+            }
+        } while (changeOccurred);
+
+        if (C1XOptions.DetailedAsserts) {
+            verifyLiveness(numBlocks);
+        }
+
+        // check that the liveIn set of the first block is empty
+        CiBitMap liveInArgs = new CiBitMap(ir.startBlock.lirBlock.liveIn.size());
+        if (!ir.startBlock.lirBlock.liveIn.isSame(liveInArgs)) {
+            if (C1XOptions.DetailedAsserts) {
+                reportFailure(numBlocks);
+            }
+
+            // bailout of if this occurs in product mode.
+            throw new CiBailout("liveIn set of first block must be empty");
+        }
+    }
+
+    private void reportFailure(int numBlocks) {
+        TTY.println("Error: liveIn set of first block must be empty (when this fails, variables are used before they are defined)");
+        TTY.print("affected registers:");
+        TTY.println(ir.startBlock.lirBlock.liveIn.toString());
+
+        // print some additional information to simplify debugging
+        for (int operandNum = 0; operandNum < ir.startBlock.lirBlock.liveIn.size(); operandNum++) {
+            if (ir.startBlock.lirBlock.liveIn.get(operandNum)) {
+                CiValue operand = operands.operandFor(operandNum);
+                Value instr = operand.isVariable() ? gen.operands.instructionForResult(((CiVariable) operand)) : null;
+                TTY.println(" var %d (HIR instruction %s)", operandNum, instr == null ? " " : instr.toString());
+
+                for (int j = 0; j < numBlocks; j++) {
+                    BlockBegin block = blockAt(j);
+                    if (block.lirBlock.liveGen.get(operandNum)) {
+                        TTY.println("  used in block B%d", block.blockID);
+                    }
+                    if (block.lirBlock.liveKill.get(operandNum)) {
+                        TTY.println("  defined in block B%d", block.blockID);
+                    }
+                }
+            }
+        }
+    }
+
+    private void verifyLiveness(int numBlocks) {
+        // check that fixed intervals are not live at block boundaries
+        // (live set must be empty at fixed intervals)
+        for (int i = 0; i < numBlocks; i++) {
+            BlockBegin block = blockAt(i);
+            for (int j = 0; j <= operands.maxRegisterNumber(); j++) {
+                assert !block.lirBlock.liveIn.get(j) : "liveIn  set of fixed register must be empty";
+                assert !block.lirBlock.liveOut.get(j) : "liveOut set of fixed register must be empty";
+                assert !block.lirBlock.liveGen.get(j) : "liveGen set of fixed register must be empty";
+            }
+        }
+    }
+
+    private void traceLiveness(boolean changeOccurredInBlock, int iterationCount, BlockBegin block) {
+        char c = iterationCount == 0 || changeOccurredInBlock ? '*' : ' ';
+        TTY.print("(%d) liveIn%c  B%d ", iterationCount, c, block.blockID);
+        TTY.println(block.lirBlock.liveIn.toString());
+        TTY.print("(%d) liveOut%c B%d ", iterationCount, c, block.blockID);
+        TTY.println(block.lirBlock.liveOut.toString());
+    }
+
+    Interval addUse(CiValue operand, int from, int to, RegisterPriority registerPriority, CiKind kind) {
+        if (!isProcessed(operand)) {
+            return null;
+        }
+        if (C1XOptions.TraceLinearScanLevel >= 2 && kind == null) {
+            TTY.println(" use %s from %d to %d (%s)", operand, from, to, registerPriority.name());
+        }
+
+        if (kind == null) {
+            kind = operand.kind.stackKind();
+        }
+        Interval interval = intervalFor(operand);
+        if (interval == null) {
+            interval = createInterval(operand);
+        }
+
+        if (kind != CiKind.Illegal) {
+            interval.setKind(kind);
+        }
+
+        if (operand.isVariable() && gen.operands.mustStayInMemory((CiVariable) operand)) {
+            interval.addRange(from, maxOpId());
+        } else {
+            interval.addRange(from, to);
+        }
+
+        interval.addUsePos(to, registerPriority);
+        return interval;
+    }
+
+    void addTemp(CiValue operand, int tempPos, RegisterPriority registerPriority, CiKind kind) {
+        if (!isProcessed(operand)) {
+            return;
+        }
+        Interval interval = intervalFor(operand);
+        if (interval == null) {
+            interval = createInterval(operand);
+        }
+
+        if (kind != CiKind.Illegal) {
+            interval.setKind(kind);
+        }
+
+        interval.addRange(tempPos, tempPos + 1);
+        interval.addUsePos(tempPos, registerPriority);
+    }
+
+    boolean isProcessed(CiValue operand) {
+        return !operand.isRegister() || attributes(operand.asRegister()).isAllocatable;
+    }
+
+    void addDef(CiValue operand, int defPos, RegisterPriority registerPriority, CiKind kind) {
+        if (!isProcessed(operand)) {
+            return;
+        }
+        if (C1XOptions.TraceLinearScanLevel >= 2) {
+            TTY.println(" def %s defPos %d (%s)", operand, defPos, registerPriority.name());
+        }
+        Interval interval = intervalFor(operand);
+        if (interval != null) {
+
+            if (kind != CiKind.Illegal) {
+                interval.setKind(kind);
+            }
+
+            Range r = interval.first();
+            if (r.from <= defPos) {
+                // Update the starting point (when a range is first created for a use, its
+                // start is the beginning of the current block until a def is encountered.)
+                r.from = defPos;
+                interval.addUsePos(defPos, registerPriority);
+
+            } else {
+                // Dead value - make vacuous interval
+                // also add register priority for dead intervals
+                interval.addRange(defPos, defPos + 1);
+                interval.addUsePos(defPos, registerPriority);
+                if (C1XOptions.TraceLinearScanLevel >= 2) {
+                    TTY.println("Warning: def of operand %s at %d occurs without use", operand, defPos);
+                }
+            }
+
+        } else {
+            // Dead value - make vacuous interval
+            // also add register priority for dead intervals
+            interval = createInterval(operand);
+            if (kind != CiKind.Illegal) {
+                interval.setKind(kind);
+            }
+
+            interval.addRange(defPos, defPos + 1);
+            interval.addUsePos(defPos, registerPriority);
+            if (C1XOptions.TraceLinearScanLevel >= 2) {
+                TTY.println("Warning: dead value %s at %d in live intervals", operand, defPos);
+            }
+        }
+
+        changeSpillDefinitionPos(interval, defPos);
+        if (registerPriority == RegisterPriority.None && interval.spillState().ordinal() <= SpillState.StartInMemory.ordinal()) {
+            // detection of method-parameters and roundfp-results
+            // TODO: move this directly to position where use-kind is computed
+            interval.setSpillState(SpillState.StartInMemory);
+        }
+    }
+
+    /**
+     * Determines the register priority for an instruction's output/result operand.
+     */
+    RegisterPriority registerPriorityOfOutputOperand(LIRInstruction op, CiValue operand) {
+        if (op.code == LIROpcode.Move) {
+            LIROp1 move = (LIROp1) op;
+            CiValue res = move.result();
+            boolean resultInMemory = res.isVariable() && operands.mustStartInMemory((CiVariable) res);
+
+            if (resultInMemory) {
+                // Begin of an interval with mustStartInMemory set.
+                // This interval will always get a stack slot first, so return noUse.
+                return RegisterPriority.None;
+
+            } else if (move.operand().isStackSlot()) {
+                // method argument (condition must be equal to handleMethodArguments)
+                return RegisterPriority.None;
+
+            } else if (move.operand().isVariableOrRegister() && move.result().isVariableOrRegister()) {
+                // Move from register to register
+                if (blockForId(op.id).checkBlockFlag(BlockBegin.BlockFlag.OsrEntry)) {
+                    // special handling of phi-function moves inside osr-entry blocks
+                    // input operand must have a register instead of output operand (leads to better register
+                    // allocation)
+                    return RegisterPriority.ShouldHaveRegister;
+                }
+            }
+        }
+
+        if (operand.isVariable() && operands.mustStartInMemory((CiVariable) operand)) {
+            // result is a stack-slot, so prevent immediate reloading
+            return RegisterPriority.None;
+        }
+
+        // all other operands require a register
+        return RegisterPriority.MustHaveRegister;
+    }
+
+    /**
+     * Determines the priority which with an instruction's input operand will be allocated a register.
+     */
+    RegisterPriority registerPriorityOfInputOperand(LIRInstruction op, CiValue operand) {
+        if (op.code == LIROpcode.Move) {
+            LIROp1 move = (LIROp1) op;
+            CiValue res = move.result();
+            boolean resultInMemory = res.isVariable() && operands.mustStartInMemory((CiVariable) res);
+
+            if (resultInMemory) {
+                // Move to an interval with mustStartInMemory set.
+                // To avoid moves from stack to stack (not allowed) force the input operand to a register
+                return RegisterPriority.MustHaveRegister;
+
+            } else if (move.operand().isVariableOrRegister() && move.result().isVariableOrRegister()) {
+                // Move from register to register
+                if (blockForId(op.id).checkBlockFlag(BlockBegin.BlockFlag.OsrEntry)) {
+                    // special handling of phi-function moves inside osr-entry blocks
+                    // input operand must have a register instead of output operand (leads to better register
+                    // allocation)
+                    return RegisterPriority.MustHaveRegister;
+                }
+
+                // The input operand is not forced to a register (moves from stack to register are allowed),
+                // but it is faster if the input operand is in a register
+                return RegisterPriority.ShouldHaveRegister;
+            }
+        }
+
+        if (compilation.target.arch.isX86()) {
+            if (op.code == LIROpcode.Cmove) {
+                // conditional moves can handle stack operands
+                assert op.result().isVariableOrRegister();
+                return RegisterPriority.ShouldHaveRegister;
+            }
+
+            // optimizations for second input operand of arithmetic operations on Intel
+            // this operand is allowed to be on the stack in some cases
+            CiKind kind = operand.kind.stackKind();
+            if (kind == CiKind.Float || kind == CiKind.Double) {
+                // SSE float instruction (CiKind.Double only supported with SSE2)
+                switch (op.code) {
+                    case Cmp:
+                    case Add:
+                    case Sub:
+                    case Mul:
+                    case Div: {
+                        LIROp2 op2 = (LIROp2) op;
+                        if (op2.operand1() != op2.operand2() && op2.operand2() == operand) {
+                            assert (op2.result().isVariableOrRegister() || op.code == LIROpcode.Cmp) && op2.operand1().isVariableOrRegister() : "cannot mark second operand as stack if others are not in register";
+                            return RegisterPriority.ShouldHaveRegister;
+                        }
+                    }
+                }
+            } else if (kind != CiKind.Long) {
+                // integer instruction (note: long operands must always be in register)
+                switch (op.code) {
+                    case Cmp:
+                    case Add:
+                    case Sub:
+                    case LogicAnd:
+                    case LogicOr:
+                    case LogicXor: {
+                        LIROp2 op2 = (LIROp2) op;
+                        if (op2.operand1() != op2.operand2() && op2.operand2() == operand) {
+                            assert (op2.result().isVariableOrRegister() || op.code == LIROpcode.Cmp) && op2.operand1().isVariableOrRegister() : "cannot mark second operand as stack if others are not in register";
+                            return RegisterPriority.ShouldHaveRegister;
+                        }
+                    }
+                }
+            }
+        } // X86
+
+        // all other operands require a register
+        return RegisterPriority.MustHaveRegister;
+    }
+
+    /**
+     * Optimizes moves related to incoming stack based arguments.
+     * The interval for the destination of such moves is assigned
+     * the stack slot (which is in the caller's frame) as its
+     * spill slot.
+     */
+    void handleMethodArguments(LIRInstruction op) {
+        if (op.code == LIROpcode.Move) {
+            LIROp1 move = (LIROp1) op;
+
+            if (move.operand().isStackSlot()) {
+                CiStackSlot slot = (CiStackSlot) move.operand();
+                if (C1XOptions.DetailedAsserts) {
+                    int argSlots = compilation.method.signature().argumentSlots(!isStatic(compilation.method.accessFlags()));
+                    assert slot.index() >= 0 && slot.index() < argSlots;
+                    assert move.id > 0 : "invalid id";
+                    assert blockForId(move.id).numberOfPreds() == 0 : "move from stack must be in first block";
+                    assert move.result().isVariable() : "result of move must be a variable";
+
+                    if (C1XOptions.TraceLinearScanLevel >= 4) {
+                        TTY.println("found move from stack slot %s to %s", slot, move.result());
+                    }
+                }
+
+                Interval interval = intervalFor(move.result());
+                CiStackSlot copySlot = slot;
+                if (C1XOptions.CopyPointerStackArguments && slot.kind == CiKind.Object) {
+                    copySlot = allocateSpillSlot(slot.kind);
+                }
+                interval.setSpillSlot(copySlot);
+                interval.assignLocation(copySlot);
+            }
+        }
+    }
+
+    void addRegisterHints(LIRInstruction op) {
+        switch (op.code) {
+            case Move: // fall through
+            case Convert: {
+                LIROp1 move = (LIROp1) op;
+
+                CiValue moveFrom = move.operand();
+                CiValue moveTo = move.result();
+
+                if (moveTo.isVariableOrRegister() && moveFrom.isVariableOrRegister()) {
+                    Interval from = intervalFor(moveFrom);
+                    Interval to = intervalFor(moveTo);
+                    if (from != null && to != null) {
+                        to.setLocationHint(from);
+                        if (C1XOptions.TraceLinearScanLevel >= 4) {
+                            TTY.println("operation at opId %d: added hint from interval %d to %d", move.id, from.operandNumber, to.operandNumber);
+                        }
+                    }
+                }
+                break;
+            }
+            case Cmove: {
+                LIROp2 cmove = (LIROp2) op;
+
+                CiValue moveFrom = cmove.operand1();
+                CiValue moveTo = cmove.result();
+
+                if (moveTo.isVariableOrRegister() && moveFrom.isVariableOrRegister()) {
+                    Interval from = intervalFor(moveFrom);
+                    Interval to = intervalFor(moveTo);
+                    if (from != null && to != null) {
+                        to.setLocationHint(from);
+                        if (C1XOptions.TraceLinearScanLevel >= 4) {
+                            TTY.println("operation at opId %d: added hint from interval %d to %d", cmove.id, from.operandNumber, to.operandNumber);
+                        }
+                    }
+                }
+                break;
+            }
+        }
+    }
+
+    void buildIntervals() {
+        intervalsSize = operands.size();
+        intervals = new Interval[intervalsSize + INITIAL_SPLIT_INTERVALS_CAPACITY];
+
+        // create a list with all caller-save registers (cpu, fpu, xmm)
+        RiRegisterConfig registerConfig = compilation.registerConfig;
+        CiRegister[] callerSaveRegs = registerConfig.getCallerSaveRegisters();
+
+        // iterate all blocks in reverse order
+        for (int i = blockCount() - 1; i >= 0; i--) {
+            BlockBegin block = blockAt(i);
+            List<LIRInstruction> instructions = block.lir().instructionsList();
+            final int blockFrom = block.firstLirInstructionId();
+            int blockTo = block.lastLirInstructionId();
+
+            assert blockFrom == instructions.get(0).id;
+            assert blockTo == instructions.get(instructions.size() - 1).id;
+
+            // Update intervals for operands live at the end of this block;
+            CiBitMap live = block.lirBlock.liveOut;
+            for (int operandNum = live.nextSetBit(0); operandNum >= 0; operandNum = live.nextSetBit(operandNum + 1)) {
+                assert live.get(operandNum) : "should not stop here otherwise";
+                CiValue operand = operands.operandFor(operandNum);
+                if (C1XOptions.TraceLinearScanLevel >= 2) {
+                    TTY.println("live in %s to %d", operand, blockTo + 2);
+                }
+
+                addUse(operand, blockFrom, blockTo + 2, RegisterPriority.None, CiKind.Illegal);
+
+                // add special use positions for loop-end blocks when the
+                // interval is used anywhere inside this loop. It's possible
+                // that the block was part of a non-natural loop, so it might
+                // have an invalid loop index.
+                if (block.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopEnd) && block.loopIndex() != -1 && isIntervalInLoop(operandNum, block.loopIndex())) {
+                    intervalFor(operand).addUsePos(blockTo + 1, RegisterPriority.LiveAtLoopEnd);
+                }
+            }
+
+            // iterate all instructions of the block in reverse order.
+            // skip the first instruction because it is always a label
+            // definitions of intervals are processed before uses
+            assert !instructions.get(0).hasOperands() : "first operation must always be a label";
+            for (int j = instructions.size() - 1; j >= 1; j--) {
+                LIRInstruction op = instructions.get(j);
+                final int opId = op.id;
+
+                // add a temp range for each register if operation destroys caller-save registers
+                if (op.hasCall) {
+                    for (CiRegister r : callerSaveRegs) {
+                        if (attributes(r).isAllocatable) {
+                            addTemp(r.asValue(), opId, RegisterPriority.None, CiKind.Illegal);
+                        }
+                    }
+                    if (C1XOptions.TraceLinearScanLevel >= 4) {
+                        TTY.println("operation destroys all caller-save registers");
+                    }
+                }
+
+                // Add any platform dependent temps
+                pdAddTemps(op);
+
+                // visit definitions (output and temp operands)
+                int k;
+                int n;
+                n = op.operandCount(LIRInstruction.OperandMode.Output);
+                for (k = 0; k < n; k++) {
+                    CiValue operand = op.operandAt(LIRInstruction.OperandMode.Output, k);
+                    assert operand.isVariableOrRegister();
+                    addDef(operand, opId, registerPriorityOfOutputOperand(op, operand), operand.kind.stackKind());
+                }
+
+                n = op.operandCount(LIRInstruction.OperandMode.Temp);
+                for (k = 0; k < n; k++) {
+                    CiValue operand = op.operandAt(LIRInstruction.OperandMode.Temp, k);
+                    assert operand.isVariableOrRegister();
+                    if (C1XOptions.TraceLinearScanLevel >= 2) {
+                        TTY.println(" temp %s tempPos %d (%s)", operand, opId, RegisterPriority.MustHaveRegister.name());
+                    }
+                    addTemp(operand, opId, RegisterPriority.MustHaveRegister, operand.kind.stackKind());
+                }
+
+                // visit uses (input operands)
+                n = op.operandCount(LIRInstruction.OperandMode.Input);
+                for (k = 0; k < n; k++) {
+                    CiValue operand = op.operandAt(LIRInstruction.OperandMode.Input, k);
+                    assert operand.isVariableOrRegister();
+                    RegisterPriority p = registerPriorityOfInputOperand(op, operand);
+                    Interval interval = addUse(operand, blockFrom, opId, p, null);
+                    if (interval != null && op instanceof LIRXirInstruction) {
+                        Range range = interval.first();
+                        // (tw) Increase range by 1 in order to overlap the input with the temp and the output operand.
+                        if (range.to == opId) {
+                            range.to++;
+                        }
+                    }
+                }
+
+                // Add uses of live locals from interpreter's point of view for proper
+                // debug information generation
+                // Treat these operands as temp values (if the live range is extended
+                // to a call site, the value would be in a register at the call otherwise)
+                LIRDebugInfo info = op.info;
+                if (info != null) {
+                    info.state.forEachLiveStateValue(new ValueProcedure() {
+                        public void doValue(Value value) {
+                            CiValue operand = value.operand();
+                            if (operand.isVariableOrRegister()) {
+                                addUse(operand, blockFrom, (opId + 1), RegisterPriority.None, null);
+                            }
+                        }
+                    });
+                }
+
+                // special steps for some instructions (especially moves)
+                handleMethodArguments(op);
+                addRegisterHints(op);
+
+            } // end of instruction iteration
+
+            // (tw) Make sure that no spill store optimization is applied for phi instructions that flow into exception handlers.
+            if (block.isExceptionEntry()) {
+                FrameState stateBefore = block.stateBefore();
+                stateBefore.forEachLivePhi(block, new PhiProcedure() {
+                    @Override
+                    public boolean doPhi(Phi phi) {
+                        Interval interval = intervalFor(phi.operand());
+                        if (interval != null) {
+                            interval.setSpillState(SpillState.NoOptimization);
+                        }
+                        return true;
+                    }
+                });
+            }
+
+        } // end of block iteration
+
+        // add the range [0, 1] to all fixed intervals.
+        // the register allocator need not handle unhandled fixed intervals
+        for (Interval interval : intervals) {
+            if (interval != null && interval.operand.isRegister()) {
+                interval.addRange(0, 1);
+            }
+        }
+    }
+
+    // * Phase 5: actual register allocation
+
+    private void pdAddTemps(LIRInstruction op) {
+        // TODO Platform dependent!
+        assert compilation.target.arch.isX86();
+
+        switch (op.code) {
+            case Tan:
+            case Sin:
+            case Cos: {
+                // The slow path for these functions may need to save and
+                // restore all live registers but we don't want to save and
+                // restore everything all the time, so mark the xmms as being
+                // killed. If the slow path were explicit or we could propagate
+                // live register masks down to the assembly we could do better
+                // but we don't have any easy way to do that right now. We
+                // could also consider not killing all xmm registers if we
+                // assume that slow paths are uncommon but it's not clear that
+                // would be a good idea.
+                if (C1XOptions.TraceLinearScanLevel >= 2) {
+                    TTY.println("killing XMMs for trig");
+                }
+                int opId = op.id;
+
+                for (CiRegister r : compilation.registerConfig.getCallerSaveRegisters()) {
+                    if (r.isFpu()) {
+                        addTemp(r.asValue(), opId, RegisterPriority.None, CiKind.Illegal);
+                    }
+                }
+                break;
+            }
+        }
+
+    }
+
+    boolean isSorted(Interval[] intervals) {
+        int from = -1;
+        for (Interval interval : intervals) {
+            assert interval != null;
+            assert from <= interval.from();
+            from = interval.from();
+
+            // XXX: very slow!
+            assert Arrays.asList(this.intervals).contains(interval);
+        }
+        return true;
+    }
+
+    Interval addToList(Interval first, Interval prev, Interval interval) {
+        Interval newFirst = first;
+        if (prev != null) {
+            prev.next = interval;
+        } else {
+            newFirst = interval;
+        }
+        return newFirst;
+    }
+
+    Interval.Pair createUnhandledLists(IntervalPredicate isList1, IntervalPredicate isList2) {
+        assert isSorted(sortedIntervals) : "interval list is not sorted";
+
+        Interval list1 = Interval.EndMarker;
+        Interval list2 = Interval.EndMarker;
+
+        Interval list1Prev = null;
+        Interval list2Prev = null;
+        Interval v;
+
+        int n = sortedIntervals.length;
+        for (int i = 0; i < n; i++) {
+            v = sortedIntervals[i];
+            if (v == null) {
+                continue;
+            }
+
+            if (isList1.apply(v)) {
+                list1 = addToList(list1, list1Prev, v);
+                list1Prev = v;
+            } else if (isList2 == null || isList2.apply(v)) {
+                list2 = addToList(list2, list2Prev, v);
+                list2Prev = v;
+            }
+        }
+
+        if (list1Prev != null) {
+            list1Prev.next = Interval.EndMarker;
+        }
+        if (list2Prev != null) {
+            list2Prev.next = Interval.EndMarker;
+        }
+
+        assert list1Prev == null || list1Prev.next == Interval.EndMarker : "linear list ends not with sentinel";
+        assert list2Prev == null || list2Prev.next == Interval.EndMarker : "linear list ends not with sentinel";
+
+        return new Interval.Pair(list1, list2);
+    }
+
+    void sortIntervalsBeforeAllocation() {
+        int sortedLen = 0;
+        for (Interval interval : intervals) {
+            if (interval != null) {
+                sortedLen++;
+            }
+        }
+
+        Interval[] sortedList = new Interval[sortedLen];
+        int sortedIdx = 0;
+        int sortedFromMax = -1;
+
+        // special sorting algorithm: the original interval-list is almost sorted,
+        // only some intervals are swapped. So this is much faster than a complete QuickSort
+        for (Interval interval : intervals) {
+            if (interval != null) {
+                int from = interval.from();
+
+                if (sortedFromMax <= from) {
+                    sortedList[sortedIdx++] = interval;
+                    sortedFromMax = interval.from();
+                } else {
+                    // the assumption that the intervals are already sorted failed,
+                    // so this interval must be sorted in manually
+                    int j;
+                    for (j = sortedIdx - 1; j >= 0 && from < sortedList[j].from(); j--) {
+                        sortedList[j + 1] = sortedList[j];
+                    }
+                    sortedList[j + 1] = interval;
+                    sortedIdx++;
+                }
+            }
+        }
+        sortedIntervals = sortedList;
+    }
+
+    void sortIntervalsAfterAllocation() {
+        if (firstDerivedIntervalIndex == -1) {
+            // no intervals have been added during allocation, so sorted list is already up to date
+            return;
+        }
+
+        Interval[] oldList = sortedIntervals;
+        Interval[] newList = Arrays.copyOfRange(intervals, firstDerivedIntervalIndex, intervalsSize);
+        int oldLen = oldList.length;
+        int newLen = newList.length;
+
+        // conventional sort-algorithm for new intervals
+        Arrays.sort(newList, INTERVAL_COMPARATOR);
+
+        // merge old and new list (both already sorted) into one combined list
+        Interval[] combinedList = new Interval[oldLen + newLen];
+        int oldIdx = 0;
+        int newIdx = 0;
+
+        while (oldIdx + newIdx < combinedList.length) {
+            if (newIdx >= newLen || (oldIdx < oldLen && oldList[oldIdx].from() <= newList[newIdx].from())) {
+                combinedList[oldIdx + newIdx] = oldList[oldIdx];
+                oldIdx++;
+            } else {
+                combinedList[oldIdx + newIdx] = newList[newIdx];
+                newIdx++;
+            }
+        }
+
+        sortedIntervals = combinedList;
+    }
+
+    private static final Comparator<Interval> INTERVAL_COMPARATOR = new Comparator<Interval>() {
+
+        public int compare(Interval a, Interval b) {
+            if (a != null) {
+                if (b != null) {
+                    return a.from() - b.from();
+                } else {
+                    return -1;
+                }
+            } else {
+                if (b != null) {
+                    return 1;
+                } else {
+                    return 0;
+                }
+            }
+        }
+    };
+
+    public void allocateRegisters() {
+        Interval precoloredIntervals;
+        Interval notPrecoloredIntervals;
+
+        Interval.Pair result = createUnhandledLists(IS_PRECOLORED_INTERVAL, IS_VARIABLE_INTERVAL);
+        precoloredIntervals = result.first;
+        notPrecoloredIntervals = result.second;
+
+        // allocate cpu registers
+        LinearScanWalker lsw = new LinearScanWalker(this, precoloredIntervals, notPrecoloredIntervals);
+        lsw.walk();
+        lsw.finishAllocation();
+    }
+
+    // * Phase 6: resolve data flow
+    // (insert moves at edges between blocks if intervals have been split)
+
+    // wrapper for Interval.splitChildAtOpId that performs a bailout in product mode
+    // instead of returning null
+    Interval splitChildAtOpId(Interval interval, int opId, LIRInstruction.OperandMode mode) {
+        Interval result = interval.getSplitChildAtOpId(opId, mode, this);
+
+        if (result != null) {
+            if (C1XOptions.TraceLinearScanLevel >= 4) {
+                TTY.println("Split child at pos " + opId + " of interval " + interval.toString() + " is " + result.toString());
+            }
+            return result;
+        }
+
+        throw new CiBailout("LinearScan: interval is null");
+    }
+
+    Interval intervalAtBlockBegin(BlockBegin block, CiValue operand) {
+        assert operand.isVariable() : "register number out of bounds";
+        assert intervalFor(operand) != null : "no interval found";
+
+        return splitChildAtOpId(intervalFor(operand), block.firstLirInstructionId(), LIRInstruction.OperandMode.Output);
+    }
+
+    Interval intervalAtBlockEnd(BlockBegin block, CiValue operand) {
+        assert operand.isVariable() : "register number out of bounds";
+        assert intervalFor(operand) != null : "no interval found";
+
+        return splitChildAtOpId(intervalFor(operand), block.lastLirInstructionId() + 1, LIRInstruction.OperandMode.Output);
+    }
+
+    Interval intervalAtOpId(CiValue operand, int opId) {
+        assert operand.isVariable() : "register number out of bounds";
+        assert intervalFor(operand) != null : "no interval found";
+
+        return splitChildAtOpId(intervalFor(operand), opId, LIRInstruction.OperandMode.Input);
+    }
+
+    void resolveCollectMappings(BlockBegin fromBlock, BlockBegin toBlock, MoveResolver moveResolver) {
+        assert moveResolver.checkEmpty();
+
+        int numOperands = operands.size();
+        CiBitMap liveAtEdge = toBlock.lirBlock.liveIn;
+
+        // visit all variables for which the liveAtEdge bit is set
+        for (int operandNum = liveAtEdge.nextSetBit(0); operandNum >= 0; operandNum = liveAtEdge.nextSetBit(operandNum + 1)) {
+            assert operandNum < numOperands : "live information set for not exisiting interval";
+            assert fromBlock.lirBlock.liveOut.get(operandNum) && toBlock.lirBlock.liveIn.get(operandNum) : "interval not live at this edge";
+
+            CiValue liveOperand = operands.operandFor(operandNum);
+            Interval fromInterval = intervalAtBlockEnd(fromBlock, liveOperand);
+            Interval toInterval = intervalAtBlockBegin(toBlock, liveOperand);
+
+            if (fromInterval != toInterval && (fromInterval.location() != toInterval.location())) {
+                // need to insert move instruction
+                moveResolver.addMapping(fromInterval, toInterval);
+            }
+        }
+    }
+
+    void resolveFindInsertPos(BlockBegin fromBlock, BlockBegin toBlock, MoveResolver moveResolver) {
+        if (fromBlock.numberOfSux() <= 1) {
+            if (C1XOptions.TraceLinearScanLevel >= 4) {
+                TTY.println("inserting moves at end of fromBlock B%d", fromBlock.blockID);
+            }
+
+            List<LIRInstruction> instructions = fromBlock.lir().instructionsList();
+            LIRInstruction instr = instructions.get(instructions.size() - 1);
+            if (instr instanceof LIRBranch) {
+                LIRBranch branch = (LIRBranch) instr;
+                // insert moves before branch
+                assert branch.cond() == Condition.TRUE : "block does not end with an unconditional jump";
+                moveResolver.setInsertPosition(fromBlock.lir(), instructions.size() - 2);
+            } else {
+                moveResolver.setInsertPosition(fromBlock.lir(), instructions.size() - 1);
+            }
+
+        } else {
+            if (C1XOptions.TraceLinearScanLevel >= 4) {
+                TTY.println("inserting moves at beginning of toBlock B%d", toBlock.blockID);
+            }
+
+            if (C1XOptions.DetailedAsserts) {
+                assert fromBlock.lir().instructionsList().get(0) instanceof LIRLabel : "block does not start with a label";
+
+                // because the number of predecessor edges matches the number of
+                // successor edges, blocks which are reached by switch statements
+                // may have be more than one predecessor but it will be guaranteed
+                // that all predecessors will be the same.
+                for (int i = 0; i < toBlock.numberOfPreds(); i++) {
+                    assert fromBlock == toBlock.predAt(i) : "all critical edges must be broken";
+                }
+            }
+
+            moveResolver.setInsertPosition(toBlock.lir(), 0);
+        }
+    }
+
+    /**
+     * Inserts necessary moves (spilling or reloading) at edges between blocks for intervals that
+     * have been split.
+     */
+    void resolveDataFlow() {
+        int numBlocks = blockCount();
+        MoveResolver moveResolver = new MoveResolver(this);
+        CiBitMap blockCompleted = new CiBitMap(numBlocks);
+        CiBitMap alreadyResolved = new CiBitMap(numBlocks);
+
+        int i;
+        for (i = 0; i < numBlocks; i++) {
+            BlockBegin block = blockAt(i);
+
+            // check if block has only one predecessor and only one successor
+            if (block.numberOfPreds() == 1 && block.numberOfSux() == 1 && block.numberOfExceptionHandlers() == 0 && !block.isExceptionEntry()) {
+                List<LIRInstruction> instructions = block.lir().instructionsList();
+                assert instructions.get(0).code == LIROpcode.Label : "block must start with label";
+                assert instructions.get(instructions.size() - 1).code == LIROpcode.Branch : "block with successors must end with branch";
+                assert ((LIRBranch) instructions.get(instructions.size() - 1)).cond() == Condition.TRUE : "block with successor must end with unconditional branch";
+
+                // check if block is empty (only label and branch)
+                if (instructions.size() == 2) {
+                    BlockBegin pred = block.predAt(0);
+                    BlockBegin sux = block.suxAt(0);
+
+                    // prevent optimization of two consecutive blocks
+                    if (!blockCompleted.get(pred.linearScanNumber()) && !blockCompleted.get(sux.linearScanNumber())) {
+                        if (C1XOptions.TraceLinearScanLevel >= 3) {
+                            TTY.println(" optimizing empty block B%d (pred: B%d, sux: B%d)", block.blockID, pred.blockID, sux.blockID);
+                        }
+                        blockCompleted.set(block.linearScanNumber());
+
+                        // directly resolve between pred and sux (without looking at the empty block between)
+                        resolveCollectMappings(pred, sux, moveResolver);
+                        if (moveResolver.hasMappings()) {
+                            moveResolver.setInsertPosition(block.lir(), 0);
+                            moveResolver.resolveAndAppendMoves();
+                        }
+                    }
+                }
+            }
+        }
+
+        for (i = 0; i < numBlocks; i++) {
+            if (!blockCompleted.get(i)) {
+                BlockBegin fromBlock = blockAt(i);
+                alreadyResolved.setFrom(blockCompleted);
+
+                int numSux = fromBlock.numberOfSux();
+                for (int s = 0; s < numSux; s++) {
+                    BlockBegin toBlock = fromBlock.suxAt(s);
+
+                    // check for duplicate edges between the same blocks (can happen with switch blocks)
+                    if (!alreadyResolved.get(toBlock.linearScanNumber())) {
+                        if (C1XOptions.TraceLinearScanLevel >= 3) {
+                            TTY.println(" processing edge between B%d and B%d", fromBlock.blockID, toBlock.blockID);
+                        }
+                        alreadyResolved.set(toBlock.linearScanNumber());
+
+                        // collect all intervals that have been split between fromBlock and toBlock
+                        resolveCollectMappings(fromBlock, toBlock, moveResolver);
+                        if (moveResolver.hasMappings()) {
+                            resolveFindInsertPos(fromBlock, toBlock, moveResolver);
+                            moveResolver.resolveAndAppendMoves();
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    void resolveExceptionEntry(BlockBegin block, CiValue operand, MoveResolver moveResolver) {
+        if (intervalFor(operand) == null) {
+            // if a phi function is never used, no interval is created . ignore this
+            return;
+        }
+
+        Interval interval = intervalAtBlockBegin(block, operand);
+        CiValue location = interval.location();
+
+        if (location.isRegister() && interval.alwaysInMemory()) {
+            // the interval is split to get a short range that is located on the stack
+            // in the following two cases:
+            // * the interval started in memory (e.g. method parameter), but is currently in a register
+            // this is an optimization for exception handling that reduces the number of moves that
+            // are necessary for resolving the states when an exception uses this exception handler
+            // * the interval would be on the fpu stack at the begin of the exception handler
+            // this is not allowed because of the complicated fpu stack handling on Intel
+
+            // range that will be spilled to memory
+            int fromOpId = block.firstLirInstructionId();
+            int toOpId = fromOpId + 1; // short live range of length 1
+            assert interval.from() <= fromOpId && interval.to() >= toOpId : "no split allowed between exception entry and first instruction";
+
+            if (interval.from() != fromOpId) {
+                // the part before fromOpId is unchanged
+                interval = interval.split(fromOpId, this);
+                interval.assignLocation(location);
+            }
+            assert interval.from() == fromOpId : "must be true now";
+
+            Interval spilledPart = interval;
+            if (interval.to() != toOpId) {
+                // the part after toOpId is unchanged
+                spilledPart = interval.splitFromStart(toOpId, this);
+                moveResolver.addMapping(spilledPart, interval);
+            }
+            assignSpillSlot(spilledPart);
+
+            assert spilledPart.from() == fromOpId && spilledPart.to() == toOpId : "just checking";
+        }
+    }
+
+    void resolveExceptionEntry(final BlockBegin block, final MoveResolver moveResolver) {
+        assert block.checkBlockFlag(BlockBegin.BlockFlag.ExceptionEntry) : "should not call otherwise";
+        assert moveResolver.checkEmpty();
+
+        // visit all registers where the liveIn bit is set
+        for (int operandNum = block.lirBlock.liveIn.nextSetBit(0); operandNum >= 0; operandNum = block.lirBlock.liveIn.nextSetBit(operandNum + 1)) {
+            resolveExceptionEntry(block, operands.operandFor(operandNum), moveResolver);
+        }
+
+        // the liveIn bits are not set for phi functions of the xhandler entry, so iterate them separately
+        block.stateBefore().forEachLivePhi(block, new PhiProcedure() {
+            public boolean doPhi(Phi phi) {
+                resolveExceptionEntry(block, phi.operand(), moveResolver);
+                return true;
+            }
+        });
+
+        if (moveResolver.hasMappings()) {
+            // insert moves after first instruction
+            moveResolver.setInsertPosition(block.lir(), 0);
+            moveResolver.resolveAndAppendMoves();
+        }
+    }
+
+    void resolveExceptionEdge(ExceptionHandler handler, int throwingOpId, CiValue operand, Phi phi, MoveResolver moveResolver) {
+        if (intervalFor(operand) == null) {
+            // if a phi function is never used, no interval is created . ignore this
+            return;
+        }
+
+        // the computation of toInterval is equal to resolveCollectMappings,
+        // but fromInterval is more complicated because of phi functions
+        BlockBegin toBlock = handler.entryBlock();
+        Interval toInterval = intervalAtBlockBegin(toBlock, operand);
+
+        if (phi != null) {
+            // phi function of the exception entry block
+            // no moves are created for this phi function in the LIRGenerator, so the
+            // interval at the throwing instruction must be searched using the operands
+            // of the phi function
+            Value fromValue = phi.inputAt(handler.phiOperand());
+            Constant con = null;
+            if (fromValue instanceof Constant) {
+                con = (Constant) fromValue;
+            }
+            if (con != null && (con.operand().isIllegal() || con.operand().isConstant())) {
+                // unpinned constants may have no register, so add mapping from constant to interval
+                moveResolver.addMapping(con.asConstant(), toInterval);
+            } else {
+                // search split child at the throwing opId
+                Interval fromInterval = intervalAtOpId(fromValue.operand(), throwingOpId);
+                if (fromInterval != toInterval) {
+                    moveResolver.addMapping(fromInterval, toInterval);
+                    // with phi functions it can happen that the same fromValue is used in
+                    // multiple mappings, so notify move-resolver that this is allowed
+                    moveResolver.setMultipleReadsAllowed();
+                }
+            }
+        } else {
+            // no phi function, so use regNum also for fromInterval
+            // search split child at the throwing opId
+            Interval fromInterval = intervalAtOpId(operand, throwingOpId);
+            if (fromInterval != toInterval) {
+                // optimization to reduce number of moves: when toInterval is on stack and
+                // the stack slot is known to be always correct, then no move is necessary
+                if (!fromInterval.alwaysInMemory() || fromInterval.spillSlot() != toInterval.location()) {
+                    moveResolver.addMapping(fromInterval, toInterval);
+                }
+            }
+        }
+    }
+
+    void resolveExceptionEdge(final ExceptionHandler handler, final int throwingOpId, final MoveResolver moveResolver) {
+        if (C1XOptions.TraceLinearScanLevel >= 4) {
+            TTY.println("resolving exception handler B%d: throwingOpId=%d", handler.entryBlock().blockID, throwingOpId);
+        }
+
+        assert moveResolver.checkEmpty();
+        assert handler.lirOpId() == -1 : "already processed this xhandler";
+        handler.setLirOpId(throwingOpId);
+        assert handler.entryCode() == null : "code already present";
+
+        // visit all registers where the liveIn bit is set
+        BlockBegin block = handler.entryBlock();
+        for (int operandNum = block.lirBlock.liveIn.nextSetBit(0); operandNum >= 0; operandNum = block.lirBlock.liveIn.nextSetBit(operandNum + 1)) {
+            resolveExceptionEdge(handler, throwingOpId, operands.operandFor(operandNum), null, moveResolver);
+        }
+
+        // the liveIn bits are not set for phi functions of the xhandler entry, so iterate them separately
+        block.stateBefore().forEachLivePhi(block, new PhiProcedure() {
+            public boolean doPhi(Phi phi) {
+                resolveExceptionEdge(handler, throwingOpId, phi.operand(), phi, moveResolver);
+                return true;
+            }
+        });
+
+        if (moveResolver.hasMappings()) {
+            LIRList entryCode = new LIRList(gen);
+            moveResolver.setInsertPosition(entryCode, 0);
+            moveResolver.resolveAndAppendMoves();
+
+            entryCode.jump(handler.entryBlock());
+            handler.setEntryCode(entryCode);
+        }
+    }
+
+    void resolveExceptionHandlers() {
+        MoveResolver moveResolver = new MoveResolver(this);
+        //LIRVisitState visitor = new LIRVisitState();
+        int numBlocks = blockCount();
+
+        int i;
+        for (i = 0; i < numBlocks; i++) {
+            BlockBegin block = blockAt(i);
+            if (block.checkBlockFlag(BlockFlag.ExceptionEntry)) {
+                resolveExceptionEntry(block, moveResolver);
+            }
+        }
+
+        for (i = 0; i < numBlocks; i++) {
+            BlockBegin block = blockAt(i);
+            LIRList ops = block.lir();
+            int numOps = ops.length();
+
+            // iterate all instructions of the block. skip the first because it is always a label
+            assert !ops.at(0).hasOperands() : "first operation must always be a label";
+            for (int j = 1; j < numOps; j++) {
+                LIRInstruction op = ops.at(j);
+                int opId = op.id;
+
+                if (opId != -1 && op.info != null) {
+                    // visit operation to collect all operands
+                    for (ExceptionHandler handler : op.exceptionEdges()) {
+                        resolveExceptionEdge(handler, opId, moveResolver);
+                    }
+
+                } else if (C1XOptions.DetailedAsserts) {
+                    assert op.exceptionEdges().size() == 0 : "missed exception handler";
+                }
+            }
+        }
+    }
+
+    // * Phase 7: assign register numbers back to LIR
+    // (includes computation of debug information and oop maps)
+
+    boolean verifyAssignedLocation(Interval interval, CiValue location) {
+        CiKind kind = interval.kind();
+
+        assert location.isRegister() || location.isStackSlot();
+
+        if (location.isRegister()) {
+            CiRegister reg = location.asRegister();
+
+            // register
+            switch (kind) {
+                case Byte:
+                case Char:
+                case Short:
+                case Jsr:
+                case Word:
+                case Object:
+                case Int: {
+                    assert reg.isCpu() : "not cpu register";
+                    break;
+                }
+
+                case Long: {
+                    assert reg.isCpu() : "not cpu register";
+                    break;
+                }
+
+                case Float: {
+                    assert !compilation.target.arch.isX86() || reg.isFpu() : "not xmm register: " + reg;
+                    break;
+                }
+
+                case Double: {
+                    assert !compilation.target.arch.isX86() || reg.isFpu() : "not xmm register: " + reg;
+                    break;
+                }
+
+                default: {
+                    throw Util.shouldNotReachHere();
+                }
+            }
+        }
+        return true;
+    }
+
+    CiStackSlot canonicalSpillOpr(Interval interval) {
+        assert interval.spillSlot() != null : "canonical spill slot not set";
+        return interval.spillSlot();
+    }
+
+    /**
+     * Assigns the allocated location for an LIR instruction operand back into the instruction.
+     *
+     * @param operand an LIR instruction operand
+     * @param opId the id of the LIR instruction using {@code operand}
+     * @param mode the usage mode for {@code operand} by the instruction
+     * @return the location assigned for the operand
+     */
+    private CiValue colorLirOperand(CiVariable operand, int opId, OperandMode mode) {
+        Interval interval = intervalFor(operand);
+        assert interval != null : "interval must exist";
+
+        if (opId != -1) {
+            if (C1XOptions.DetailedAsserts) {
+                BlockBegin block = blockForId(opId);
+                if (block.numberOfSux() <= 1 && opId == block.lastLirInstructionId()) {
+                    // check if spill moves could have been appended at the end of this block, but
+                    // before the branch instruction. So the split child information for this branch would
+                    // be incorrect.
+                    LIRInstruction instr = block.lir().instructionsList().get(block.lir().instructionsList().size() - 1);
+                    if (instr instanceof LIRBranch) {
+                        LIRBranch branch = (LIRBranch) instr;
+                        if (block.lirBlock.liveOut.get(operandNumber(operand))) {
+                            assert branch.cond() == Condition.TRUE : "block does not end with an unconditional jump";
+                            throw new CiBailout("can't get split child for the last branch of a block because the information would be incorrect (moves are inserted before the branch in resolveDataFlow)");
+                        }
+                    }
+                }
+            }
+
+            // operands are not changed when an interval is split during allocation,
+            // so search the right interval here
+            interval = splitChildAtOpId(interval, opId, mode);
+        }
+
+        return interval.location();
+    }
+
+    IntervalWalker initComputeOopMaps() {
+        // setup lists of potential oops for walking
+        Interval oopIntervals;
+        Interval nonOopIntervals;
+
+        oopIntervals = createUnhandledLists(IS_OOP_INTERVAL, null).first;
+
+        // intervals that have no oops inside need not to be processed.
+        // to ensure a walking until the last instruction id, add a dummy interval
+        // with a high operation id
+        nonOopIntervals = new Interval(CiValue.IllegalValue, -1);
+        nonOopIntervals.addRange(Integer.MAX_VALUE - 2, Integer.MAX_VALUE - 1);
+
+        return new IntervalWalker(this, oopIntervals, nonOopIntervals);
+    }
+
+    void computeOopMap(IntervalWalker iw, LIRInstruction op, LIRDebugInfo info, boolean isCallSite, CiBitMap frameRefMap, CiBitMap regRefMap) {
+        if (C1XOptions.TraceLinearScanLevel >= 3) {
+            TTY.println("creating oop map at opId %d", op.id);
+        }
+
+        // walk before the current operation . intervals that start at
+        // the operation (i.e. output operands of the operation) are not
+        // included in the oop map
+        iw.walkBefore(op.id);
+
+        // Iterate through active intervals
+        for (Interval interval = iw.activeLists.get(RegisterBinding.Fixed); interval != Interval.EndMarker; interval = interval.next) {
+            CiValue operand = interval.operand;
+
+            assert interval.currentFrom() <= op.id && op.id <= interval.currentTo() : "interval should not be active otherwise";
+            assert interval.operand.isVariable() : "fixed interval found";
+
+            // Check if this range covers the instruction. Intervals that
+            // start or end at the current operation are not included in the
+            // oop map, except in the case of patching moves. For patching
+            // moves, any intervals which end at this instruction are included
+            // in the oop map since we may safepoint while doing the patch
+            // before we've consumed the inputs.
+            if (op.id < interval.currentTo()) {
+                // caller-save registers must not be included into oop-maps at calls
+                assert !isCallSite || !operand.isRegister() || !isCallerSave(operand) : "interval is in a caller-save register at a call . register will be overwritten";
+
+                CiValue location = interval.location();
+                if (location.isStackSlot()) {
+                    location = frameMap.toStackAddress((CiStackSlot) location);
+                }
+                info.setOop(location, compilation, frameRefMap, regRefMap);
+
+                // Spill optimization: when the stack value is guaranteed to be always correct,
+                // then it must be added to the oop map even if the interval is currently in a register
+                if (interval.alwaysInMemory() && op.id > interval.spillDefinitionPos() && !interval.location().equals(interval.spillSlot())) {
+                    assert interval.spillDefinitionPos() > 0 : "position not set correctly";
+                    assert interval.spillSlot() != null : "no spill slot assigned";
+                    assert !interval.operand.isRegister() : "interval is on stack :  so stack slot is registered twice";
+                    info.setOop(frameMap.toStackAddress(interval.spillSlot()), compilation, frameRefMap, regRefMap);
+                }
+            }
+        }
+    }
+
+    private boolean isCallerSave(CiValue operand) {
+        return attributes(operand.asRegister()).isCallerSave;
+    }
+
+    void computeOopMap(IntervalWalker iw, LIRInstruction op, LIRDebugInfo info, CiBitMap frameRefMap, CiBitMap regRefMap) {
+        computeOopMap(iw, op, info, op.hasCall, frameRefMap, regRefMap);
+        if (op instanceof LIRCall) {
+            List<CiValue> pointerSlots = ((LIRCall) op).pointerSlots;
+            if (pointerSlots != null) {
+                for (CiValue v : pointerSlots) {
+                    info.setOop(v, compilation, frameRefMap, regRefMap);
+                }
+            }
+        } else if (op instanceof LIRXirInstruction) {
+            List<CiValue> pointerSlots = ((LIRXirInstruction) op).pointerSlots;
+            if (pointerSlots != null) {
+                for (CiValue v : pointerSlots) {
+                    info.setOop(v, compilation, frameRefMap, regRefMap);
+                }
+            }
+        }
+    }
+
+    CiValue toCiValue(int opId, Value value) {
+        if (value != null && value.operand() != CiValue.IllegalValue) {
+            CiValue operand = value.operand();
+            Constant con = null;
+            if (value instanceof Constant) {
+                con = (Constant) value;
+            }
+
+            assert con == null || operand.isVariable() || operand.isConstant() || operand.isIllegal() : "Constant instructions have only constant operands (or illegal if constant is optimized away)";
+
+            if (con != null && !con.isLive() && !operand.isConstant()) {
+                // Unpinned constants may have a variable operand for a part of the lifetime
+                // or may be illegal when it was optimized away,
+                // so always use a constant operand
+                operand = con.asConstant();
+            }
+
+            if (operand.isVariable()) {
+                OperandMode mode = OperandMode.Input;
+                BlockBegin block = blockForId(opId);
+                if (block.numberOfSux() == 1 && opId == block.lastLirInstructionId()) {
+                    // generating debug information for the last instruction of a block.
+                    // if this instruction is a branch, spill moves are inserted before this branch
+                    // and so the wrong operand would be returned (spill moves at block boundaries are not
+                    // considered in the live ranges of intervals)
+                    // Solution: use the first opId of the branch target block instead.
+                    final LIRInstruction instr = block.lir().instructionsList().get(block.lir().instructionsList().size() - 1);
+                    if (instr instanceof LIRBranch) {
+                        if (block.lirBlock.liveOut.get(operandNumber(operand))) {
+                            opId = block.suxAt(0).firstLirInstructionId();
+                            mode = OperandMode.Output;
+                        }
+                    }
+                }
+
+                // Get current location of operand
+                // The operand must be live because debug information is considered when building the intervals
+                // if the interval is not live, colorLirOperand will cause an assert on failure
+                operand = colorLirOperand((CiVariable) operand, opId, mode);
+                assert !hasCall(opId) || operand.isStackSlot() || !isCallerSave(operand) : "cannot have caller-save register operands at calls";
+                return operand;
+            } else if (operand.isRegister()) {
+                assert value instanceof LoadRegister;
+                return operand;
+            } else {
+                assert value instanceof Constant;
+                assert operand.isConstant() : "operand must be constant";
+                return operand;
+            }
+        } else {
+            // return a dummy value because real value not needed
+            return CiValue.IllegalValue;
+        }
+    }
+
+    CiFrame computeFrameForState(int opId, FrameState state, CiBitMap frameRefMap) {
+        CiFrame callerFrame = null;
+
+        FrameState callerState = state.callerState();
+        if (callerState != null) {
+            // process recursively to compute outermost scope first
+            callerFrame = computeFrameForState(opId, callerState, frameRefMap);
+        }
+
+        CiValue[] values = new CiValue[state.valuesSize() + state.locksSize()];
+        int valueIndex = 0;
+
+        for (int i = 0; i < state.valuesSize(); i++) {
+            values[valueIndex++] = toCiValue(opId, state.valueAt(i));
+        }
+
+        for (int i = 0; i < state.locksSize(); i++) {
+            if (compilation.runtime.sizeOfBasicObjectLock() != 0) {
+                CiStackSlot monitorAddress = frameMap.toMonitorBaseStackAddress(i);
+                values[valueIndex++] = monitorAddress;
+                assert frameRefMap != null;
+                CiStackSlot objectAddress = frameMap.toMonitorObjectStackAddress(i);
+                LIRDebugInfo.setBit(frameRefMap, objectAddress.index());
+            } else {
+                Value lock = state.lockAt(i);
+                if (lock.isConstant() && compilation.runtime.asJavaClass(lock.asConstant()) != null) {
+                   // lock on class for synchronized static method
+                   values[valueIndex++] = lock.asConstant();
+                } else {
+                   values[valueIndex++] = toCiValue(opId, lock);
+                }
+            }
+        }
+
+        return new CiFrame(callerFrame, state.scope().method, state.bci, values, state.localsSize(), state.stackSize(), state.locksSize());
+    }
+
+    private void computeDebugInfo(IntervalWalker iw, LIRInstruction op) {
+        assert iw != null : "interval walker needed for debug information";
+        computeDebugInfo(iw, op, op.info);
+
+        if (op instanceof LIRXirInstruction) {
+            LIRXirInstruction xir = (LIRXirInstruction) op;
+            if (xir.infoAfter != null) {
+                computeDebugInfo(iw, op, xir.infoAfter);
+            }
+        }
+    }
+
+
+    private void computeDebugInfo(IntervalWalker iw, LIRInstruction op, LIRDebugInfo info) {
+        if (info != null) {
+            if (info.debugInfo == null) {
+                int frameSize = compilation.frameMap().frameSize();
+                int frameWords = frameSize / compilation.target.spillSlotSize;
+                CiBitMap frameRefMap = new CiBitMap(frameWords);
+                CiBitMap regRefMap = !op.hasCall ? new CiBitMap(compilation.target.arch.registerReferenceMapBitCount) : null;
+                CiFrame frame = compilation.placeholderState != null ? null : computeFrame(info.state, op.id, frameRefMap);
+                computeOopMap(iw, op, info, frameRefMap, regRefMap);
+                info.debugInfo = new CiDebugInfo(frame, regRefMap, frameRefMap);
+            } else if (C1XOptions.DetailedAsserts) {
+                assert info.debugInfo.frame().equals(computeFrame(info.state, op.id, new CiBitMap(info.debugInfo.frameRefMap.size())));
+            }
+        }
+    }
+
+    CiFrame computeFrame(FrameState state, int opId, CiBitMap frameRefMap) {
+        if (C1XOptions.TraceLinearScanLevel >= 3) {
+            TTY.println("creating debug information at opId %d", opId);
+        }
+        return computeFrameForState(opId, state, frameRefMap);
+    }
+
+    private void assignLocations(List<LIRInstruction> instructions, IntervalWalker iw) {
+        int numInst = instructions.size();
+        boolean hasDead = false;
+
+        for (int j = 0; j < numInst; j++) {
+            LIRInstruction op = instructions.get(j);
+            if (op == null) { // this can happen when spill-moves are removed in eliminateSpillMoves
+                hasDead = true;
+                continue;
+            }
+
+            // iterate all modes of the visitor and process all virtual operands
+            for (LIRInstruction.OperandMode mode : LIRInstruction.OPERAND_MODES) {
+                int n = op.operandCount(mode);
+                for (int k = 0; k < n; k++) {
+                    CiValue operand = op.operandAt(mode, k);
+                    if (operand.isVariable()) {
+                        op.setOperandAt(mode, k, colorLirOperand((CiVariable) operand, op.id, mode));
+                    }
+                }
+            }
+
+            if (op.info != null) {
+                // exception handling
+                if (compilation.hasExceptionHandlers()) {
+                    for (ExceptionHandler handler : op.exceptionEdges()) {
+                        if (handler.entryCode() != null) {
+                            assignLocations(handler.entryCode().instructionsList(), null);
+                        }
+                    }
+                }
+
+                // compute reference map and debug information
+                computeDebugInfo(iw, op);
+            }
+
+            // make sure we haven't made the op invalid.
+            assert op.verify();
+
+            // remove useless moves
+            if (op.code == LIROpcode.Move) {
+                CiValue src = op.operand(0);
+                CiValue dst = op.result();
+                if (dst == src || src.equals(dst)) {
+                    // TODO: what about o.f = o.f and exceptions?
+                    instructions.set(j, null);
+                    hasDead = true;
+                }
+            }
+        }
+
+        if (hasDead) {
+            // iterate all instructions of the block and remove all null-values.
+            int insertPoint = 0;
+            for (int j = 0; j < numInst; j++) {
+                LIRInstruction op = instructions.get(j);
+                if (op != null) {
+                    if (insertPoint != j) {
+                        instructions.set(insertPoint, op);
+                    }
+                    insertPoint++;
+                }
+            }
+            Util.truncate(instructions, insertPoint);
+        }
+    }
+
+    private void assignLocations() {
+        IntervalWalker iw = initComputeOopMaps();
+        for (BlockBegin block : sortedBlocks) {
+            assignLocations(block.lir().instructionsList(), iw);
+        }
+    }
+
+    public void allocate() {
+        if (C1XOptions.PrintTimers) {
+            C1XTimers.LIFETIME_ANALYSIS.start();
+        }
+
+        numberInstructions();
+
+        printLir("Before register allocation", true);
+
+        computeLocalLiveSets();
+        computeGlobalLiveSets();
+
+        buildIntervals();
+        sortIntervalsBeforeAllocation();
+
+        if (C1XOptions.PrintTimers) {
+            C1XTimers.LIFETIME_ANALYSIS.stop();
+            C1XTimers.LINEAR_SCAN.start();
+        }
+
+        printIntervals("Before register allocation");
+
+        allocateRegisters();
+
+        if (C1XOptions.PrintTimers) {
+            C1XTimers.LINEAR_SCAN.stop();
+            C1XTimers.RESOLUTION.start();
+        }
+
+        resolveDataFlow();
+        if (compilation.hasExceptionHandlers()) {
+            resolveExceptionHandlers();
+        }
+
+        if (C1XOptions.PrintTimers) {
+            C1XTimers.RESOLUTION.stop();
+            C1XTimers.DEBUG_INFO.start();
+        }
+
+        C1XMetrics.LSRASpills += (maxSpills - frameMap.initialSpillSlot());
+
+        // fill in number of spill slots into frameMap
+        frameMap.finalizeFrame(maxSpills);
+
+        printIntervals("After register allocation");
+        printLir("After register allocation", true);
+
+        sortIntervalsAfterAllocation();
+
+        if (C1XOptions.DetailedAsserts) {
+            verify();
+        }
+
+        eliminateSpillMoves();
+        assignLocations();
+
+        if (C1XOptions.DetailedAsserts) {
+            verifyIntervals();
+        }
+
+        if (C1XOptions.PrintTimers) {
+            C1XTimers.DEBUG_INFO.stop();
+            C1XTimers.CODE_CREATE.start();
+        }
+
+        printLir("After register number assignment", true);
+
+        EdgeMoveOptimizer.optimize(ir.linearScanOrder());
+        if (C1XOptions.OptControlFlow) {
+            ControlFlowOptimizer.optimize(ir);
+        }
+
+        printLir("After control flow optimization", false);
+    }
+
+    void printIntervals(String label) {
+        if (C1XOptions.TraceLinearScanLevel >= 1) {
+            int i;
+            TTY.println();
+            TTY.println(label);
+
+            for (Interval interval : intervals) {
+                if (interval != null) {
+                    TTY.out().println(interval.logString(this));
+                }
+            }
+
+            TTY.println();
+            TTY.println("--- Basic Blocks ---");
+            for (i = 0; i < blockCount(); i++) {
+                BlockBegin block = blockAt(i);
+                TTY.print("B%d [%d, %d, %d, %d] ", block.blockID, block.firstLirInstructionId(), block.lastLirInstructionId(), block.loopIndex(), block.loopDepth());
+            }
+            TTY.println();
+            TTY.println();
+        }
+
+        if (compilation.compiler.isObserved()) {
+            compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, label, this, intervals, intervalsSize));
+        }
+    }
+
+    void printLir(String label, boolean hirValid) {
+        if (C1XOptions.TraceLinearScanLevel >= 1 && !TTY.isSuppressed()) {
+            TTY.println();
+            TTY.println(label);
+            LIRList.printLIR(ir.linearScanOrder());
+            TTY.println();
+        }
+
+        if (compilation.compiler.isObserved()) {
+            compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, label, compilation.hir().startBlock, hirValid, true));
+        }
+    }
+
+    boolean verify() {
+        // (check that all intervals have a correct register and that no registers are overwritten)
+        if (C1XOptions.TraceLinearScanLevel >= 2) {
+            TTY.println(" verifying intervals *");
+        }
+        verifyIntervals();
+
+        if (C1XOptions.TraceLinearScanLevel >= 2) {
+            TTY.println(" verifying that no oops are in fixed intervals *");
+        }
+        //verifyNoOopsInFixedIntervals();
+
+        if (C1XOptions.TraceLinearScanLevel >= 2) {
+            TTY.println(" verifying that unpinned constants are not alive across block boundaries");
+        }
+        verifyConstants();
+
+        if (C1XOptions.TraceLinearScanLevel >= 2) {
+            TTY.println(" verifying register allocation *");
+        }
+        verifyRegisters();
+
+        if (C1XOptions.TraceLinearScanLevel >= 2) {
+            TTY.println(" no errors found *");
+        }
+
+        return true;
+    }
+
+    private void verifyRegisters() {
+        RegisterVerifier verifier = new RegisterVerifier(this);
+        verifier.verify(blockAt(0));
+    }
+
+    void verifyIntervals() {
+        int len = intervalsSize;
+
+        for (int i = 0; i < len; i++) {
+            Interval i1 = intervals[i];
+            if (i1 == null) {
+                continue;
+            }
+
+            i1.checkSplitChildren();
+
+            if (i1.operandNumber != i) {
+                TTY.println("Interval %d is on position %d in list", i1.operandNumber, i);
+                TTY.println(i1.logString(this));
+                throw new CiBailout("");
+            }
+
+            if (i1.operand.isVariable() && i1.kind() == CiKind.Illegal) {
+                TTY.println("Interval %d has no type assigned", i1.operandNumber);
+                TTY.println(i1.logString(this));
+                throw new CiBailout("");
+            }
+
+            if (i1.location() == null) {
+                TTY.println("Interval %d has no register assigned", i1.operandNumber);
+                TTY.println(i1.logString(this));
+                throw new CiBailout("");
+            }
+
+            if (!isProcessed(i1.location())) {
+                TTY.println("Can not have an Interval for an ignored register " + i1.location());
+                TTY.println(i1.logString(this));
+                throw new CiBailout("");
+            }
+
+            if (i1.first() == Range.EndMarker) {
+                TTY.println("Interval %d has no Range", i1.operandNumber);
+                TTY.println(i1.logString(this));
+                throw new CiBailout("");
+            }
+
+            for (Range r = i1.first(); r != Range.EndMarker; r = r.next) {
+                if (r.from >= r.to) {
+                    TTY.println("Interval %d has zero length range", i1.operandNumber);
+                    TTY.println(i1.logString(this));
+                    throw new CiBailout("");
+                }
+            }
+
+            for (int j = i + 1; j < len; j++) {
+                Interval i2 = intervals[j];
+                if (i2 == null) {
+                    continue;
+                }
+
+                // special intervals that are created in MoveResolver
+                // . ignore them because the range information has no meaning there
+                if (i1.from() == 1 && i1.to() == 2) {
+                    continue;
+                }
+                if (i2.from() == 1 && i2.to() == 2) {
+                    continue;
+                }
+                CiValue l1 = i1.location();
+                CiValue l2 = i2.location();
+                if (i1.intersects(i2) && (l1.equals(l2))) {
+                    if (C1XOptions.DetailedAsserts) {
+                        TTY.println("Intervals %d and %d overlap and have the same register assigned", i1.operandNumber, i2.operandNumber);
+                        TTY.println(i1.logString(this));
+                        TTY.println(i2.logString(this));
+                    }
+                    throw new CiBailout("");
+                }
+            }
+        }
+    }
+
+    void verifyNoOopsInFixedIntervals() {
+        Interval fixedIntervals;
+        Interval otherIntervals;
+        fixedIntervals = createUnhandledLists(IS_PRECOLORED_INTERVAL, null).first;
+        // to ensure a walking until the last instruction id, add a dummy interval
+        // with a high operation id
+        otherIntervals = new Interval(CiValue.IllegalValue, -1);
+        otherIntervals.addRange(Integer.MAX_VALUE - 2, Integer.MAX_VALUE - 1);
+        IntervalWalker iw = new IntervalWalker(this, fixedIntervals, otherIntervals);
+
+        for (int i = 0; i < blockCount(); i++) {
+            BlockBegin block = blockAt(i);
+
+            List<LIRInstruction> instructions = block.lir().instructionsList();
+
+            for (int j = 0; j < instructions.size(); j++) {
+                LIRInstruction op = instructions.get(j);
+
+                if (op.info != null) {
+                    iw.walkBefore(op.id);
+                    boolean checkLive = true;
+
+                    // Make sure none of the fixed registers is live across an
+                    // oopmap since we can't handle that correctly.
+                    if (checkLive) {
+                        for (Interval interval = iw.activeLists.get(RegisterBinding.Fixed); interval != Interval.EndMarker; interval = interval.next) {
+                            if (interval.currentTo() > op.id + 1) {
+                                // This interval is live out of this op so make sure
+                                // that this interval represents some value that's
+                                // referenced by this op either as an input or output.
+                                boolean ok = false;
+                                for (LIRInstruction.OperandMode mode : LIRInstruction.OPERAND_MODES) {
+                                    int n = op.operandCount(mode);
+                                    for (int k = 0; k < n; k++) {
+                                        CiValue operand = op.operandAt(mode, k);
+                                        if (operand.isRegister()) {
+                                            if (intervalFor(operand) == interval) {
+                                                ok = true;
+                                                break;
+                                            }
+                                        }
+                                    }
+                                }
+                                assert ok : "fixed intervals should never be live across an oopmap point";
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    void verifyConstants() {
+        int numBlocks = blockCount();
+
+        for (int i = 0; i < numBlocks; i++) {
+            BlockBegin block = blockAt(i);
+            CiBitMap liveAtEdge = block.lirBlock.liveIn;
+
+            // visit all operands where the liveAtEdge bit is set
+            for (int operandNum = liveAtEdge.nextSetBit(0); operandNum >= 0; operandNum = liveAtEdge.nextSetBit(operandNum + 1)) {
+                if (C1XOptions.TraceLinearScanLevel >= 4) {
+                    TTY.println("checking interval %d of block B%d", operandNum, block.blockID);
+                }
+                CiValue operand = operands.operandFor(operandNum);
+                assert operand.isVariable() : "value must have variable operand";
+                Value value = gen.operands.instructionForResult(((CiVariable) operand));
+                assert value != null : "all intervals live across block boundaries must have Value";
+                // TKR assert value.asConstant() == null || value.isPinned() :
+                // "only pinned constants can be alive accross block boundaries";
+            }
+        }
+    }
+
+    public int numberOfSpillSlots(CiKind kind) {
+        return compilation.target.spillSlots(kind);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/Compiler/src/com/sun/c1x/alloc/LinearScanWalker.java	Wed Apr 27 11:43:22 2011 +0200
@@ -0,0 +1,984 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.c1x.alloc;
+
+import static com.sun.cri.ci.CiUtil.*;
+
+import java.util.*;
+
+import com.sun.c1x.*;
+import com.sun.c1x.alloc.Interval.RegisterBinding;
+import com.sun.c1x.alloc.Interval.RegisterPriority;
+import com.sun.c1x.alloc.Interval.SpillState;
+import com.sun.c1x.alloc.Interval.State;
+import com.sun.c1x.debug.*;
+import com.sun.c1x.ir.*;
+import com.sun.c1x.lir.*;
+import com.sun.c1x.util.*;
+import com.sun.cri.ci.*;
+import com.sun.cri.ci.CiRegister.RegisterFlag;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+final class LinearScanWalker extends IntervalWalker {
+
+    private CiRegister[] availableRegs;
+
+    private final int[] usePos;
+    private final int[] blockPos;
+
+    private List<Interval>[] spillIntervals;
+
+    private MoveResolver moveResolver; // for ordering spill moves
+
+    // accessors mapped to same functions in class LinearScan
+    int blockCount() {
+        return allocator.blockCount();
+    }
+
+    BlockBegin blockAt(int idx) {
+        return allocator.blockAt(idx);
+    }
+
+    BlockBegin blockOfOpWithId(int opId) {
+        return allocator.blockForId(opId);
+    }
+
+    LinearScanWalker(LinearScan allocator, Interval unhandledFixedFirst, Interval unhandledAnyFirst) {
+        super(allocator, unhandledFixedFirst, unhandledAnyFirst);
+        moveResolver = new MoveResolver(allocator);
+        spillIntervals = Util.uncheckedCast(new List[allocator.registers.length]);
+        for (int i = 0; i < allocator.registers.length; i++) {
+            spillIntervals[i] = new ArrayList<Interval>(2);
+        }
+        usePos = new int[allocator.registers.length];
+        blockPos = new int[allocator.registers.length];
+    }
+
+    void initUseLists(boolean onlyProcessUsePos) {
+        for (CiRegister register : availableRegs) {
+            int i = register.number;
+            usePos[i] = Integer.MAX_VALUE;
+
+            if (!onlyProcessUsePos) {
+                blockPos[i] = Integer.MAX_VALUE;
+                spillIntervals[i].clear();
+            }
+        }
+    }
+
+    void excludeFromUse(Interval i) {
+        CiValue location = i.location();
+        int i1 = location.asRegister().number;
+        if (i1 >= availableRegs[0].number && i1 <= availableRegs[availableRegs.length - 1].number) {
+            usePos[i1] = 0;
+        }
+    }
+
+    void setUsePos(Interval interval, int usePos, boolean onlyProcessUsePos) {
+        if (usePos != -1) {
+            assert usePos != 0 : "must use excludeFromUse to set usePos to 0";
+            int i = interval.location().asRegister().number;
+            if (i >= availableRegs[0].number && i <= availableRegs[availableRegs.length - 1].number) {
+                if (this.usePos[i] > usePos) {
+                    this.usePos[i] = usePos;
+                }
+                if (!onlyProcessUsePos) {
+                    spillIntervals[i].add(interval);
+                }
+            }
+        }
+    }
+
+    void setBlockPos(Interval i, int blockPos) {
+        if (blockPos != -1) {
+            int reg = i.location().asRegister().number;
+            if (reg >= availableRegs[0].number && reg <= availableRegs[availableRegs.length - 1].number) {
+                if (this.blockPos[reg] > blockPos) {
+                    this.blockPos[reg] = blockPos;
+                }
+                if (usePos[reg] > blockPos) {
+                    usePos[reg] = blockPos;
+                }
+            }
+        }
+    }
+
+    void freeExcludeActiveFixed() {
+        Interval interval = activeLists.get(RegisterBinding.Fixed);
+        while (interval != Interval.EndMarker) {
+            assert interval.location().isRegister() : "active interval must have a register assigned";
+            excludeFromUse(interval);
+            interval = interval.next;
+        }
+    }
+
+    void freeExcludeActiveAny() {
+        Interval interval = activeLists.get(RegisterBinding.Any);
+        while (interval != Interval.EndMarker) {
+            assert interval.location().isRegister() : "active interval must have a register assigned";
+            excludeFromUse(interval);
+            interval = interval.next;
+        }
+    }
+
+    void freeCollectInactiveFixed(Interval current) {
+        Interval interval = inactiveLists.get(RegisterBinding.Fixed);
+        while (interval != Interval.EndMarker) {
+            if (current.to() <= interval.currentFrom()) {
+                assert interval.currentIntersectsAt(current) == -1 : "must not intersect";
+                setUsePos(interval, interval.currentFrom(), true);
+            } else {
+                setUsePos(interval, interval.currentIntersectsAt(current), true);
+            }
+            interval = interval.next;
+        }
+    }
+
+    void freeCollectInactiveAny(Interval current) {
+        Interval interval = inactiveLists.get(RegisterBinding.Any);
+        while (interval != Interval.EndMarker) {
+            setUsePos(interval, interval.currentIntersectsAt(current), true);
+            interval = interval.next;
+        }
+    }
+
+    void freeCollectUnhandled(RegisterBinding kind, Interval current) {
+        Interval interval = unhandledLists.get(kind);
+        while (interval != Interval.EndMarker) {
+            setUsePos(interval, interval.intersectsAt(current), true);
+            if (kind == RegisterBinding.Fixed && current.to() <= interval.from()) {
+                setUsePos(interval, interval.from(), true);
+            }
+            interval = interval.next;
+        }
+    }
+
+    void spillExcludeActiveFixed() {
+        Interval interval = activeLists.get(RegisterBinding.Fixed);
+        while (interval != Interval.EndMarker) {
+            excludeFromUse(interval);
+            interval = interval.next;
+        }
+    }
+
+    void spillBlockUnhandledFixed(Interval current) {
+        Interval interval = unhandledLists.get(RegisterBinding.Fixed);
+        while (interval != Interval.EndMarker) {
+            setBlockPos(interval, interval.intersectsAt(current));
+            interval = interval.next;
+        }
+    }
+
+    void spillBlockInactiveFixed(Interval current) {
+        Interval interval = inactiveLists.get(RegisterBinding.Fixed);
+        while (interval != Interval.EndMarker) {
+            if (current.to() > interval.currentFrom()) {
+                setBlockPos(interval, interval.currentIntersectsAt(current));
+            } else {
+                assert interval.currentIntersectsAt(current) == -1 : "invalid optimization: intervals intersect";
+            }
+
+            interval = interval.next;
+        }
+    }
+
+    void spillCollectActiveAny() {
+        Interval interval = activeLists.get(RegisterBinding.Any);
+        while (interval != Interval.EndMarker) {
+            setUsePos(interval, Math.min(interval.nextUsage(RegisterPriority.LiveAtLoopEnd, currentPosition), interval.to()), false);
+            interval = interval.next;
+        }
+    }
+
+    void spillCollectInactiveAny(Interval current) {
+        Interval interval = inactiveLists.get(RegisterBinding.Any);
+        while (interval != Interval.EndMarker) {
+            if (interval.currentIntersects(current)) {
+                setUsePos(interval, Math.min(interval.nextUsage(RegisterPriority.LiveAtLoopEnd, currentPosition), interval.to()), false);
+            }
+            interval = interval.next;
+        }
+    }
+
+    void insertMove(int opId, Interval srcIt, Interval dstIt) {
+        // output all moves here. When source and target are equal, the move is
+        // optimized away later in assignRegNums
+
+        opId = (opId + 1) & ~1;
+        BlockBegin opBlock = allocator.blockForId(opId);
+        assert opId > 0 && allocator.blockForId(opId - 2) == opBlock : "cannot insert move at block boundary";
+
+        // calculate index of instruction inside instruction list of current block
+        // the minimal index (for a block with no spill moves) can be calculated because the
+        // numbering of instructions is known.
+        // When the block already contains spill moves, the index must be increased until the
+        // correct index is reached.
+        List<LIRInstruction> list = opBlock.lir().instructionsList();
+        int index = (opId - list.get(0).id) >> 1;
+        assert list.get(index).id <= opId : "error in calculation";
+
+        while (list.get(index).id != opId) {
+            index++;
+            assert 0 <= index && index < list.size() : "index out of bounds";
+        }
+        assert 1 <= index && index < list.size() : "index out of bounds";
+        assert list.get(index).id == opId : "error in calculation";
+
+        // insert new instruction before instruction at position index
+        moveResolver.moveInsertPosition(opBlock.lir(), index - 1);
+        moveResolver.addMapping(srcIt, dstIt);
+    }
+
+    int findOptimalSplitPos(BlockBegin minBlock, BlockBegin maxBlock, int maxSplitPos) {
+        int fromBlockNr = minBlock.linearScanNumber();
+        int toBlockNr = maxBlock.linearScanNumber();
+
+        assert 0 <= fromBlockNr && fromBlockNr < blockCount() : "out of range";
+        assert 0 <= toBlockNr && toBlockNr < blockCount() : "out of range";
+        assert fromBlockNr < toBlockNr : "must cross block boundary";
+
+        // Try to split at end of maxBlock. If this would be after
+        // maxSplitPos, then use the begin of maxBlock
+        int optimalSplitPos = maxBlock.lastLirInstructionId() + 2;
+        if (optimalSplitPos > maxSplitPos) {
+            optimalSplitPos = maxBlock.firstLirInstructionId();
+        }
+
+        int minLoopDepth = maxBlock.loopDepth();
+        for (int i = toBlockNr - 1; i >= fromBlockNr; i--) {
+            BlockBegin cur = blockAt(i);
+
+            if (cur.loopDepth() < minLoopDepth) {
+                // block with lower loop-depth found . split at the end of this block
+                minLoopDepth = cur.loopDepth();
+                optimalSplitPos = cur.lastLirInstructionId() + 2;
+            }
+        }
+        assert optimalSplitPos > allocator.maxOpId() || allocator.isBlockBegin(optimalSplitPos) : "algorithm must move split pos to block boundary";
+
+        return optimalSplitPos;
+    }
+
+    int findOptimalSplitPos(Interval interval, int minSplitPos, int maxSplitPos, boolean doLoopOptimization) {
+        int optimalSplitPos = -1;
+        if (minSplitPos == maxSplitPos) {
+            // trivial case, no optimization of split position possible
+            if (C1XOptions.TraceLinearScanLevel >= 4) {
+                TTY.println("      min-pos and max-pos are equal, no optimization possible");
+            }
+            optimalSplitPos = minSplitPos;
+
+        } else {
+            assert minSplitPos < maxSplitPos : "must be true then";
+            assert minSplitPos > 0 : "cannot access minSplitPos - 1 otherwise";
+
+            // reason for using minSplitPos - 1: when the minimal split pos is exactly at the
+            // beginning of a block, then minSplitPos is also a possible split position.
+            // Use the block before as minBlock, because then minBlock.lastLirInstructionId() + 2 == minSplitPos
+            BlockBegin minBlock = allocator.blockForId(minSplitPos - 1);
+
+            // reason for using maxSplitPos - 1: otherwise there would be an assert on failure
+            // when an interval ends at the end of the last block of the method
+            // (in this case, maxSplitPos == allocator().maxLirOpId() + 2, and there is no
+            // block at this opId)
+            BlockBegin maxBlock = allocator.blockForId(maxSplitPos - 1);
+
+            assert minBlock.linearScanNumber() <= maxBlock.linearScanNumber() : "invalid order";
+            if (minBlock == maxBlock) {
+                // split position cannot be moved to block boundary : so split as late as possible
+                if (C1XOptions.TraceLinearScanLevel >= 4) {
+                    TTY.println("      cannot move split pos to block boundary because minPos and maxPos are in same block");
+                }
+                optimalSplitPos = maxSplitPos;
+
+            } else {
+                if (interval.hasHoleBetween(maxSplitPos - 1, maxSplitPos) && !allocator.isBlockBegin(maxSplitPos)) {
+                    // Do not move split position if the interval has a hole before maxSplitPos.
+                    // Intervals resulting from Phi-Functions have more than one definition (marked
+                    // as mustHaveRegister) with a hole before each definition. When the register is needed
+                    // for the second definition : an earlier reloading is unnecessary.
+                    if (C1XOptions.TraceLinearScanLevel >= 4) {
+                        TTY.println("      interval has hole just before maxSplitPos, so splitting at maxSplitPos");
+                    }
+                    optimalSplitPos = maxSplitPos;
+
+                } else {
+                    // seach optimal block boundary between minSplitPos and maxSplitPos
+                    if (C1XOptions.TraceLinearScanLevel >= 4) {
+                        TTY.println("      moving split pos to optimal block boundary between block B%d and B%d", minBlock.blockID, maxBlock.blockID);
+                    }
+
+                    if (doLoopOptimization) {
+                        // Loop optimization: if a loop-end marker is found between min- and max-position :
+                        // then split before this loop
+                        int loopEndPos = interval.nextUsageExact(RegisterPriority.LiveAtLoopEnd, minBlock.lastLirInstructionId() + 2);
+                        if (C1XOptions.TraceLinearScanLevel >= 4) {
+                            TTY.println("      loop optimization: loop end found at pos %d", loopEndPos);
+                        }
+
+                        assert loopEndPos > minSplitPos : "invalid order";
+                        if (loopEndPos < maxSplitPos) {
+                            // loop-end marker found between min- and max-position
+                            // if it is not the end marker for the same loop as the min-position : then move
+                            // the max-position to this loop block.
+                            // Desired result: uses tagged as shouldHaveRegister inside a loop cause a reloading
+                            // of the interval (normally, only mustHaveRegister causes a reloading)
+                            BlockBegin loopBlock = allocator.blockForId(loopEndPos);
+
+                            if (C1XOptions.TraceLinearScanLevel >= 4) {
+                                TTY.println("      interval is used in loop that ends in block B%d, so trying to move maxBlock back from B%d to B%d", loopBlock.blockID, maxBlock.blockID, loopBlock.blockID);
+                            }
+                            assert loopBlock != minBlock : "loopBlock and minBlock must be different because block boundary is needed between";
+
+                            optimalSplitPos = findOptimalSplitPos(minBlock, loopBlock, loopBlock.lastLirInstructionId() + 2);
+                            if (optimalSplitPos == loopBlock.lastLirInstructionId() + 2) {
+                                optimalSplitPos = -1;
+                                if (C1XOptions.TraceLinearScanLevel >= 4) {
+                                    TTY.println("      loop optimization not necessary");
+                                }
+                            } else {
+                                if (C1XOptions.TraceLinearScanLevel >= 4) {
+                                    TTY.println("      loop optimization successful");
+                                }
+                            }
+                        }
+                    }
+
+                    if (optimalSplitPos == -1) {
+                        // not calculated by loop optimization
+                        optimalSplitPos = findOptimalSplitPos(minBlock, maxBlock, maxSplitPos);
+                    }
+                }
+            }
+        }
+        if (C1XOptions.TraceLinearScanLevel >= 4) {
+            TTY.println("      optimal split position: %d", optimalSplitPos);
+        }
+
+        return optimalSplitPos;
+    }
+
+    // split an interval at the optimal position between minSplitPos and
+    // maxSplitPos in two parts:
+    // 1) the left part has already a location assigned
+    // 2) the right part is sorted into to the unhandled-list
+    void splitBeforeUsage(Interval interval, int minSplitPos, int maxSplitPos) {
+        if (C1XOptions.TraceLinearScanLevel >= 2) {
+            TTY.println("----- splitting interval: ");
+        }
+        if (C1XOptions.TraceLinearScanLevel >= 4) {
+            TTY.println(interval.logString(allocator));
+        }
+        if (C1XOptions.TraceLinearScanLevel >= 2) {
+            TTY.println("      between %d and %d", minSplitPos, maxSplitPos);
+        }
+
+        assert interval.from() < minSplitPos : "cannot split at start of interval";
+        assert currentPosition < minSplitPos : "cannot split before current position";
+        assert minSplitPos <= maxSplitPos : "invalid order";
+        assert maxSplitPos <= interval.to() : "cannot split after end of interval";
+
+        int optimalSplitPos = findOptimalSplitPos(interval, minSplitPos, maxSplitPos, true);
+
+        assert minSplitPos <= optimalSplitPos && optimalSplitPos <= maxSplitPos : "out of range";
+        assert optimalSplitPos <= interval.to() : "cannot split after end of interval";
+        assert optimalSplitPos > interval.from() : "cannot split at start of interval";
+
+        if (optimalSplitPos == interval.to() && interval.nextUsage(RegisterPriority.MustHaveRegister, minSplitPos) == Integer.MAX_VALUE) {
+            // the split position would be just before the end of the interval
+            // . no split at all necessary
+            if (C1XOptions.TraceLinearScanLevel >= 4) {
+                TTY.println("      no split necessary because optimal split position is at end of interval");
+            }
+            return;
+        }
+
+        // must calculate this before the actual split is performed and before split position is moved to odd opId
+        boolean moveNecessary = !allocator.isBlockBegin(optimalSplitPos) && !interval.hasHoleBetween(optimalSplitPos - 1, optimalSplitPos);
+
+        if (!allocator.isBlockBegin(optimalSplitPos)) {
+            // move position before actual instruction (odd opId)
+            optimalSplitPos = (optimalSplitPos - 1) | 1;
+        }
+
+        if (C1XOptions.TraceLinearScanLevel >= 4) {
+            TTY.println("      splitting at position %d", optimalSplitPos);
+        }
+        assert allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 1) : "split pos must be odd when not on block boundary";
+        assert !allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 0) : "split pos must be even on block boundary";
+
+        Interval splitPart = interval.split(optimalSplitPos, allocator);
+
+        allocator.copyRegisterFlags(interval, splitPart);
+        splitPart.setInsertMoveWhenActivated(moveNecessary);
+
+        assert splitPart.from() >= current.currentFrom() : "cannot append new interval before current walk position";
+        unhandledLists.addToListSortedByStartAndUsePositions(RegisterBinding.Any, splitPart);
+
+        if (C1XOptions.TraceLinearScanLevel >= 2) {
+            TTY.println("      split interval in two parts (insertMoveWhenActivated: %b)", moveNecessary);
+        }
+        if (C1XOptions.TraceLinearScanLevel >= 2) {
+            TTY.print("      ");
+            TTY.println(interval.logString(allocator));
+            TTY.print("      ");
+            TTY.println(splitPart.logString(allocator));
+        }
+    }
+
+// split an interval at the optimal position between minSplitPos and
+// maxSplitPos in two parts:
+// 1) the left part has already a location assigned
+// 2) the right part is always on the stack and therefore ignored in further processing
+
+    void splitForSpilling(Interval interval) {
+        // calculate allowed range of splitting position
+        int maxSplitPos = currentPosition;
+        int minSplitPos = Math.max(interval.previousUsage(RegisterPriority.ShouldHaveRegister, maxSplitPos) + 1, interval.from());
+
+        if (C1XOptions.TraceLinearScanLevel >= 2) {
+            TTY.print("----- splitting and spilling interval: ");
+            TTY.println(interval.logString(allocator));
+            TTY.println("      between %d and %d", minSplitPos, maxSplitPos);
+        }
+
+        assert interval.state == State.Active : "why spill interval that is not active?";
+        assert interval.from() <= minSplitPos : "cannot split before start of interval";
+        assert minSplitPos <= maxSplitPos : "invalid order";
+        assert maxSplitPos < interval.to() : "cannot split at end end of interval";
+        assert currentPosition < interval.to() : "interval must not end before current position";
+
+        if (minSplitPos == interval.from()) {
+            // the whole interval is never used, so spill it entirely to memory
+            if (C1XOptions.TraceLinearScanLevel >= 2) {
+                TTY.println("      spilling entire interval because split pos is at beginning of interval");
+                TTY.println("      use positions: " + interval.usePosList().size());
+            }
+            assert interval.firstUsage(RegisterPriority.ShouldHaveRegister) > currentPosition : "interval must not have use position before currentPosition";
+
+            allocator.assignSpillSlot(interval);
+            allocator.changeSpillState(interval, minSplitPos);
+
+            // Also kick parent intervals out of register to memory when they have no use
+            // position. This avoids short interval in register surrounded by intervals in
+            // memory . avoid useless moves from memory to register and back
+            Interval parent = interval;
+            while (parent != null && parent.isSplitChild()) {
+                parent = parent.getSplitChildBeforeOpId(parent.from());
+
+                if (parent.location().isRegister()) {
+                    if (parent.firstUsage(RegisterPriority.ShouldHaveRegister) == Integer.MAX_VALUE) {
+                        // parent is never used, so kick it out of its assigned register
+                        if (C1XOptions.TraceLinearScanLevel >= 4) {
+                            TTY.println("      kicking out interval %d out of its register because it is never used", parent.operandNumber);
+                        }
+                        allocator.assignSpillSlot(parent);
+                    } else {
+                        // do not go further back because the register is actually used by the interval
+                        parent = null;
+                    }
+                }
+            }
+
+        } else {
+            // search optimal split pos, split interval and spill only the right hand part
+            int optimalSplitPos = findOptimalSplitPos(interval, minSplitPos, maxSplitPos, false);
+
+            assert minSplitPos <= optimalSplitPos && optimalSplitPos <= maxSplitPos : "out of range";
+            assert optimalSplitPos < interval.to() : "cannot split at end of interval";
+            assert optimalSplitPos >= interval.from() : "cannot split before start of interval";
+
+            if (!allocator.isBlockBegin(optimalSplitPos)) {
+                // move position before actual instruction (odd opId)
+                optimalSplitPos = (optimalSplitPos - 1) | 1;
+            }
+
+            if (C1XOptions.TraceLinearScanLevel >= 4) {
+                TTY.println("      splitting at position %d", optimalSplitPos);
+            }
+            assert allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 1) : "split pos must be odd when not on block boundary";
+            assert !allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 0) : "split pos must be even on block boundary";
+
+            Interval spilledPart = interval.split(optimalSplitPos, allocator);
+            allocator.assignSpillSlot(spilledPart);
+            allocator.changeSpillState(spilledPart, optimalSplitPos);
+
+            if (!allocator.isBlockBegin(optimalSplitPos)) {
+                if (C1XOptions.TraceLinearScanLevel >= 4) {
+                    TTY.println("      inserting move from interval %d to %d", interval.operandNumber, spilledPart.operandNumber);
+                }
+                insertMove(optimalSplitPos, interval, spilledPart);
+            }
+
+            // the currentSplitChild is needed later when moves are inserted for reloading
+            assert spilledPart.currentSplitChild() == interval : "overwriting wrong currentSplitChild";
+            spilledPart.makeCurrentSplitChild();
+
+            if (C1XOptions.TraceLinearScanLevel >= 2) {
+                TTY.println("      split interval in two parts");
+                TTY.print("      ");
+                TTY.println(interval.logString(allocator));
+                TTY.print("      ");
+                TTY.println(spilledPart.logString(allocator));
+            }
+        }
+    }
+
+    void splitStackInterval(Interval interval) {
+        int minSplitPos = currentPosition + 1;
+        int maxSplitPos = Math.min(interval.firstUsage(RegisterPriority.ShouldHaveRegister), interval.to());
+
+        splitBeforeUsage(interval, minSplitPos, maxSplitPos);
+    }
+
+    void splitWhenPartialRegisterAvailable(Interval interval, int registerAvailableUntil) {
+        int minSplitPos = Math.max(interval.previousUsage(RegisterPriority.ShouldHaveRegister, registerAvailableUntil), interval.from() + 1);
+        splitBeforeUsage(interval, minSplitPos, registerAvailableUntil);
+    }
+
+    void splitAndSpillInterval(Interval interval) {
+        assert interval.state == State.Active || interval.state == State.Inactive : "other states not allowed";
+
+        int currentPos = currentPosition;