# HG changeset patch # User Josef Eisl # Date 1395863051 -3600 # Node ID fbae9be45c9561134eba63b325ae36cebde5cf2c # Parent 97a0878202c2ede16abcbb35b074b0a8c41e4069# Parent 5823c399e28f174b0232ac938603acc899f505ed Merge. diff -r 97a0878202c2 -r fbae9be45c95 .hgtags --- a/.hgtags Wed Mar 26 17:02:45 2014 +0100 +++ b/.hgtags Wed Mar 26 20:44:11 2014 +0100 @@ -408,3 +408,4 @@ 050a626a88951140df874f7b163e304d07b6c296 jdk9-b01 b188446de75bda5fc52d102cddf242c3ef5ecbdf jdk9-b02 b2fee789d23f3cdabb3db4e51af43038e5692d3a jdk9-b03 +483d05bf77a7c2a762aca1e06c4191bc06647176 graal-0.2 diff -r 97a0878202c2 -r fbae9be45c95 CHANGELOG.md --- a/CHANGELOG.md Wed Mar 26 17:02:45 2014 +0100 +++ b/CHANGELOG.md Wed Mar 26 20:44:11 2014 +0100 @@ -2,30 +2,42 @@ ## `tip` ### Graal -* New methods for querying memory usage of individual objects and object graphs in Graal API (MetaAccessProvider#getMemorySize, MetaUtil#getMemorySizeRecursive). -* New (tested) invariant that equality comparisons for JavaType/JavaMethod/JavaField values use .equals() instead of '=='. +* ... +### Truffle +* ... + +## Version 0.2 +25-Mar-2014, [Repository Revision](http://hg.openjdk.java.net/graal/graal/rev/graal-0.2) + +### Graal +* Use HotSpot stubs for certain array copy operations. +* New methods for querying memory usage of individual objects and object graphs in Graal API (`MetaAccessProvider#getMemorySize`, `MetaUtil#getMemorySizeRecursive`). +* Added tiered configuration (C1 + Graal). +* Initial security model for Graal [GRAAL-22](https://bugs.openjdk.java.net/browse/GRAAL-22). +* New (tested) invariant that equality comparisons for `JavaType`/`JavaMethod`/`JavaField` values use `.equals()` instead of `==`. * Made graph caching compilation-local. +* Added AllocSpy tool for analyzing allocation in Graal using the [Java Allocation Instrumenter](https://code.google.com/p/java-allocation-instrumenter/). +* Initial support for memory arithmetic operations on x86 ### Truffle -* New API TruffleRuntime#createCallNode to create call nodes and to give the runtime system control over its implementation. -* New API RootNode#getCachedCallNodes to get a weak set of CallNodes that have registered to call the RootNode. -* New API to split the AST of a call-site context sensitively. CallNode#split, CallNode#isSplittable, CallNode#getSplitCallTarget, CallNode#getCurrentCallTarget, RootNode#isSplittable, RootNode#split. -* New API to inline a call-site into the call-graph. CallNode#isInlinable, CallNode#inline, CallNode#isInlined. -* New API for the runtime environment to register CallTargets as caller to the RootNode. CallNode#registerCallTarget. -* Improved API for counting nodes in Truffle ASTS. NodeUtil#countNodes can be used with a NodeFilter filter Nodes. -* New API to declare the cost of a Node for use in runtime environment specific heuristics. See NodeCost, Node#getCost() and NodeInfo#cost(). -* Removed old API for NodeInfo#Kind and NodeInfo#kind(). As a replacement the new Node cost API can be used. -* Changed Node#replace reason parameter type to CharSequence (to allow for lazy string building) -* Deprecated Node#adoptChild and Node#adoptChild, no longer needed in node constructor -* New Node#insert method for inserting new nodes into the tree (formerly adoptChild) -* New Node#adoptChildren() helper method that adopts all (direct and indirect) children of a node -* New API Node#atomic for atomic tree operations -* Made Node#replace thread-safe - +* New API `TruffleRuntime#createCallNode` to create call nodes and to give the runtime system control over its implementation. +* New API `RootNode#getCachedCallNodes` to get a weak set of `CallNode`s that have registered to call the `RootNode`. +* New API to split the AST of a call-site context sensitively. `CallNode#split`, `CallNode#isSplittable`, `CallNode#getSplitCallTarget`, `CallNode#getCurrentCallTarget`, `RootNode#isSplittable`, `RootNode#split`. +* New API to inline a call-site into the call-graph. `CallNode#isInlinable`, `CallNode#inline`, `CallNode#isInlined`. +* New API for the runtime environment to register `CallTarget`s as caller to the `RootNode`. `CallNode#registerCallTarget`. +* Improved API for counting nodes in Truffle ASTs. `NodeUtil#countNodes` can be used with a `NodeFilter`. +* New API to declare the cost of a Node for use in runtime environment specific heuristics. See `NodeCost`, `Node#getCost` and `NodeInfo#cost`. +* Removed old API for `NodeInfo#Kind` and `NodeInfo#kind`. As a replacement the new `NodeCost` API can be used. +* Changed `Node#replace` reason parameter type to `CharSequence` (to enable lazy string building) +* Deprecated `Node#adoptChild` and `Node#adoptChild`, no longer needed in node constructor +* New `Node#insert` method for inserting new nodes into the tree (formerly `adoptChild`) +* New `Node#adoptChildren` helper method that adopts all (direct and indirect) children of a node +* New API `Node#atomic` for atomic tree operations +* Made `Node#replace` thread-safe ## Version 0.1 -5-Feb-2014, [Repository Revision](http://hg.openjdk.java.net/graal/graal/rev/b124e22eb772) +5-Feb-2014, [Repository Revision](http://hg.openjdk.java.net/graal/graal/rev/graal-0.1) ### Graal diff -r 97a0878202c2 -r fbae9be45c95 README.md --- a/README.md Wed Mar 26 17:02:45 2014 +0100 +++ b/README.md Wed Mar 26 20:44:11 2014 +0100 @@ -23,10 +23,11 @@ Compilation with Graal is only done by explicit requests to the Graal API. This is how Truffle uses Graal. -2. The 'graal' configuration is a VM where all compilation is performed - by Graal and no other compilers are built into the VM binary. This - VM will bootstrap Graal itself at startup unless the -XX:-BootstrapGraal - VM option is given. +2. The 'graal' configuration is a VM where normal compilations are performed + by Graal. This VM will bootstrap Graal itself at startup unless the + -XX:-BootstrapGraal. Note that if tiered compilation is enabled, Graal + will be used at the last tier while C1 will be used for the first compiled + tiers. Unless you use the --vm option with the build command, you will be presented with a dialogue to choose one of the above VM configurations for the build @@ -78,5 +79,3 @@ These configurations aim to match as closely as possible the VM(s) included in the OpenJDK binaries one can download. - No newline at end of file - diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Wed Mar 26 20:44:11 2014 +0100 @@ -160,68 +160,79 @@ public abstract void emit(TargetDescription target, ByteBuffer buffer); } + public abstract static class ConstantData extends Data { + + private final Constant constant; + + protected ConstantData(Constant constant, int alignment) { + super(alignment); + this.constant = constant; + } + + public Constant getConstant() { + return constant; + } + } + /** * Represents a Java primitive value used in a {@link DataPatch}. This implementation uses * {@link Kind#getByteCount()} bytes to encode each value. */ - public static final class PrimitiveData extends Data { - - public final Constant constant; + public static final class PrimitiveData extends ConstantData { public PrimitiveData(Constant constant, int alignment) { - super(alignment); + super(constant, alignment); assert constant.getKind().isPrimitive(); - this.constant = constant; } @Override public int getSize(TargetDescription target) { - return constant.getKind().getByteCount(); + return getConstant().getKind().getByteCount(); } @Override public Kind getKind() { - return constant.getKind(); + return getConstant().getKind(); } @Override public void emit(TargetDescription target, ByteBuffer buffer) { - switch (constant.getKind()) { + switch (getConstant().getKind()) { case Boolean: - buffer.put(constant.asBoolean() ? (byte) 1 : (byte) 0); + buffer.put(getConstant().asBoolean() ? (byte) 1 : (byte) 0); break; case Byte: - buffer.put((byte) constant.asInt()); + buffer.put((byte) getConstant().asInt()); break; case Char: - buffer.putChar((char) constant.asInt()); + buffer.putChar((char) getConstant().asInt()); break; case Short: - buffer.putShort((short) constant.asInt()); + buffer.putShort((short) getConstant().asInt()); break; case Int: - buffer.putInt(constant.asInt()); + buffer.putInt(getConstant().asInt()); break; case Long: - buffer.putLong(constant.asLong()); + buffer.putLong(getConstant().asLong()); break; case Float: - buffer.putFloat(constant.asFloat()); + buffer.putFloat(getConstant().asFloat()); break; case Double: - buffer.putDouble(constant.asDouble()); + buffer.putDouble(getConstant().asDouble()); break; } } @Override public String toString() { - return constant.toString(); + return getConstant().toString(); } @Override public int hashCode() { - return constant.hashCode(); + return getConstant().hashCode(); } @Override @@ -231,7 +242,7 @@ } if (obj instanceof PrimitiveData) { PrimitiveData other = (PrimitiveData) obj; - return constant.equals(other.constant); + return getConstant().equals(other.getConstant()); } else { return false; } @@ -591,7 +602,15 @@ addInfopoint(new Infopoint(codePos, debugInfo, reason)); } - private void addInfopoint(Infopoint infopoint) { + /** + * Records a custom infopoint in the code section. + * + * Compiler implementations can use this method to record non-standard infopoints, which are not + * handled by the dedicated methods like {@link #recordCall}. + * + * @param infopoint the infopoint to record, usually a derived class from {@link Infopoint} + */ + public void addInfopoint(Infopoint infopoint) { // The infopoints list must always be sorted if (!infopoints.isEmpty() && infopoints.get(infopoints.size() - 1).pcOffset >= infopoint.pcOffset) { // This re-sorting should be very rare diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java --- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Wed Mar 26 20:44:11 2014 +0100 @@ -1213,6 +1213,7 @@ emitByte(0xD0 | encode); } + @Override public final void ensureUniquePC() { nop(); } @@ -1669,6 +1670,13 @@ emitInt(imm32); } + public final void testl(AMD64Address dst, int imm32) { + prefixq(dst); + emitByte(0xF7); + emitOperandHelper(0, dst); + emitInt(imm32); + } + public final void testl(Register dst, Register src) { prefixAndEncode(dst.encoding, src.encoding); emitArith(0x85, 0xC0, dst, src); @@ -2064,6 +2072,13 @@ emitOperandHelper(dst, src); } + public final void cmpq(AMD64Address dst, int imm32) { + prefixq(dst); + emitByte(0x81); + emitOperandHelper(7, dst); + emitInt(imm32); + } + public final void cmpq(Register dst, int imm32) { prefixqAndEncode(dst.encoding); emitArith(0x81, 0xF8, dst, imm32); @@ -2410,6 +2425,13 @@ emitOperandHelper(dst, src); } + public final void testq(AMD64Address dst, int imm32) { + prefixq(dst); + emitByte(0xF7); + emitOperandHelper(0, dst); + emitInt(imm32); + } + public final void xorq(Register dst, int imm32) { prefixqAndEncode(dst.encoding); emitArith(0x81, 0xF0, dst, imm32); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java --- a/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java Wed Mar 26 20:44:11 2014 +0100 @@ -68,6 +68,11 @@ return null; } + @Override + public final void ensureUniquePC() { + throw GraalInternalError.unimplemented(); + } + public final void undefined(String str) { emitString("undefined operation " + str); } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java --- a/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java Wed Mar 26 20:44:11 2014 +0100 @@ -696,6 +696,11 @@ } @Override + public final void ensureUniquePC() { + throw GraalInternalError.unimplemented(); + } + + @Override public void jmp(Label l) { String str = nameOf(l); bra(str); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Wed Mar 26 20:44:11 2014 +0100 @@ -74,6 +74,7 @@ return Placeholder; } + @Override public final void ensureUniquePC() { new Nop().emit(this); } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Assembler.java --- a/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Assembler.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Assembler.java Wed Mar 26 20:44:11 2014 +0100 @@ -183,4 +183,9 @@ * Returns a target specific placeholder address that can be used for code patching. */ public abstract AbstractAddress getPlaceholder(); + + /** + * Emits a NOP instruction to advance the current PC. + */ + public abstract void ensureUniquePC(); } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java --- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java Wed Mar 26 20:44:11 2014 +0100 @@ -771,7 +771,7 @@ if (!currentBlock.jsrScope.isEmpty()) { sb.append(' ').append(currentBlock.jsrScope); } - Debug.log(sb.toString()); + Debug.log("%s", sb); } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Wed Mar 26 20:44:11 2014 +0100 @@ -41,6 +41,7 @@ import com.oracle.graal.lir.StandardOp.JumpOp; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.amd64.AMD64Arithmetic.BinaryCommutative; +import com.oracle.graal.lir.amd64.AMD64Arithmetic.BinaryMemory; import com.oracle.graal.lir.amd64.AMD64Arithmetic.BinaryRegConst; import com.oracle.graal.lir.amd64.AMD64Arithmetic.BinaryRegReg; import com.oracle.graal.lir.amd64.AMD64Arithmetic.BinaryRegStack; @@ -48,7 +49,9 @@ import com.oracle.graal.lir.amd64.AMD64Arithmetic.DivRemOp; import com.oracle.graal.lir.amd64.AMD64Arithmetic.FPDivRemOp; import com.oracle.graal.lir.amd64.AMD64Arithmetic.Unary1Op; +import com.oracle.graal.lir.amd64.AMD64Arithmetic.Unary2MemoryOp; import com.oracle.graal.lir.amd64.AMD64Arithmetic.Unary2Op; +import com.oracle.graal.lir.amd64.AMD64Compare.CompareMemoryOp; import com.oracle.graal.lir.amd64.AMD64Compare.CompareOp; import com.oracle.graal.lir.amd64.AMD64ControlFlow.BranchOp; import com.oracle.graal.lir.amd64.AMD64ControlFlow.CondMoveOp; @@ -58,6 +61,7 @@ import com.oracle.graal.lir.amd64.AMD64ControlFlow.StrategySwitchOp; import com.oracle.graal.lir.amd64.AMD64ControlFlow.TableSwitchOp; import com.oracle.graal.lir.amd64.AMD64Move.LeaOp; +import com.oracle.graal.lir.amd64.AMD64Move.LoadOp; import com.oracle.graal.lir.amd64.AMD64Move.MembarOp; import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp; import com.oracle.graal.lir.amd64.AMD64Move.MoveToRegOp; @@ -327,10 +331,46 @@ } } + protected void emitCompareMemoryConOp(Kind kind, AMD64AddressValue left, Value right, LIRFrameState state) { + assert kind == right.getKind(); + switch (kind) { + case Int: + append(new CompareMemoryOp(ICMP, left, right, state)); + break; + case Long: + append(new CompareMemoryOp(LCMP, left, right, state)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + protected void emitCompareRegMemoryOp(Kind kind, Value left, AMD64AddressValue right, LIRFrameState state) { + switch (kind) { + case Int: + append(new CompareMemoryOp(ICMP, left, right, state)); + break; + case Long: + append(new CompareMemoryOp(LCMP, left, right, state)); + break; + case Object: + append(new CompareMemoryOp(ACMP, left, right, state)); + break; + case Float: + append(new CompareMemoryOp(FCMP, left, right, state)); + break; + case Double: + append(new CompareMemoryOp(DCMP, left, right, state)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + /** * This method emits the compare instruction, and may reorder the operands. It returns true if * it did so. - * + * * @param a the left operand of the comparison * @param b the right operand of the comparison * @return true if the left and right operands were switched, false otherwise @@ -492,6 +532,27 @@ } } + protected Value emitBinaryMemory(AMD64Arithmetic op, Kind kind, AllocatableValue a, AMD64AddressValue location, LIRFrameState state) { + Variable result = newVariable(a.getKind()); + append(new BinaryMemory(op, kind, result, a, location, state)); + return result; + } + + protected Value emitConvert2MemoryOp(PlatformKind kind, AMD64Arithmetic op, AMD64AddressValue address, LIRFrameState state) { + Variable result = newVariable(kind); + append(new Unary2MemoryOp(op, result, address, state)); + return result; + } + + protected Value emitZeroExtendMemory(Kind memoryKind, int resultBits, AMD64AddressValue address, LIRFrameState state) { + assert memoryKind.isUnsigned(); + // Issue a zero extending load of the proper bit size and set the result to + // the proper kind. + Variable result = newVariable(resultBits == 32 ? Kind.Int : Kind.Long); + append(new LoadOp(memoryKind, result, address, state)); + return result; + } + private void emitDivRem(AMD64Arithmetic op, Value a, Value b, LIRFrameState state) { AllocatableValue rax = AMD64.rax.asValue(a.getPlatformKind()); emitMove(rax, a); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MemoryPeephole.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MemoryPeephole.java Wed Mar 26 20:44:11 2014 +0100 @@ -0,0 +1,482 @@ +/* + * Copyright (c) 2014, 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.oracle.graal.compiler.amd64; + +import static com.oracle.graal.lir.amd64.AMD64Arithmetic.*; +import static com.oracle.graal.nodes.ConstantNode.*; +import static com.oracle.graal.phases.GraalOptions.*; + +import java.util.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.amd64.AMD64ControlFlow.BranchOp; +import com.oracle.graal.lir.amd64.AMD64ControlFlow.FloatBranchOp; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.calc.FloatConvertNode.FloatConvert; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +public class AMD64MemoryPeephole implements MemoryArithmeticLIRLowerer { + protected final AMD64NodeLIRGenerator gen; + protected List deferredNodes; + + protected AMD64MemoryPeephole(AMD64NodeLIRGenerator gen) { + this.gen = gen; + } + + public Value setResult(ValueNode x, Value operand) { + return gen.setResult(x, operand); + } + + @Override + public boolean memoryPeephole(Access access, MemoryArithmeticLIRLowerable operation, List deferred) { + this.deferredNodes = deferred; + boolean result = operation.generate(this, access); + if (result) { + Debug.log("merge %s %s with %1s %s %s", access, access.asNode().stamp(), operation, result, access.asNode().graph().method()); + } else { + Debug.log("can't merge %s %s with %1s", access, access.asNode().stamp(), operation); + } + this.deferredNodes = null; + return result; + } + + protected LIRFrameState getState(Access access) { + if (access instanceof DeoptimizingNode) { + return gen.state((DeoptimizingNode) access); + } + return null; + } + + protected AMD64AddressValue makeAddress(Access access) { + return (AMD64AddressValue) access.nullCheckLocation().generateAddress(gen, gen.operand(access.object())); + } + + protected Value emitBinaryMemory(AMD64Arithmetic op, boolean commutative, ValueNode x, ValueNode y, Access access) { + ValueNode other = x; + if (other == access) { + if (commutative) { + other = y; + } else { + return null; + } + } + ensureEvaluated(other); + return gen.getLIRGenerator().emitBinaryMemory(op, access.nullCheckLocation().getValueKind(), gen.getLIRGeneratorTool().asAllocatable(gen.operand(other)), makeAddress(access), getState(access)); + } + + /** + * Constants with multiple users need to be evaluated in the right location so that later users + * can pick up the operand. Make sure that happens when it needs to. + */ + protected void ensureEvaluated(ValueNode node) { + evaluateDeferred(node); + evaluateDeferred(); + } + + protected void evaluateDeferred(ValueNode node) { + // Ensure the other input value has a generated value. + if (ConstantNodeRecordsUsages) { + if (!gen.hasOperand(node)) { + assert node instanceof ConstantNode : node; + ((ConstantNode) node).generate(gen); + } + } + } + + protected void evaluateDeferred() { + if (deferredNodes != null) { + for (ValueNode node : deferredNodes) { + evaluateDeferred(node); + } + } + } + + protected Value emitConvert2MemoryOp(PlatformKind kind, AMD64Arithmetic op, Access access) { + AMD64AddressValue address = makeAddress(access); + LIRFrameState state = getState(access); + evaluateDeferred(); + return gen.getLIRGenerator().emitConvert2MemoryOp(kind, op, address, state); + } + + @Override + public Value emitAddMemory(ValueNode x, ValueNode y, Access access) { + switch (access.nullCheckLocation().getValueKind()) { + case Int: + return emitBinaryMemory(IADD, true, x, y, access); + case Long: + return emitBinaryMemory(LADD, true, x, y, access); + case Float: + return emitBinaryMemory(FADD, true, x, y, access); + case Double: + return emitBinaryMemory(DADD, true, x, y, access); + default: + return null; + } + } + + @Override + public Value emitSubMemory(ValueNode x, ValueNode y, Access access) { + switch (access.nullCheckLocation().getValueKind()) { + case Int: + return emitBinaryMemory(ISUB, false, x, y, access); + case Long: + return emitBinaryMemory(LSUB, false, x, y, access); + case Float: + return emitBinaryMemory(FSUB, false, x, y, access); + case Double: + return emitBinaryMemory(DSUB, false, x, y, access); + default: + return null; + } + } + + @Override + public Value emitMulMemory(ValueNode x, ValueNode y, Access access) { + switch (access.nullCheckLocation().getValueKind()) { + case Int: + return emitBinaryMemory(IMUL, true, x, y, access); + case Long: + return emitBinaryMemory(LMUL, true, x, y, access); + case Float: + return emitBinaryMemory(FMUL, true, x, y, access); + case Double: + return emitBinaryMemory(DMUL, true, x, y, access); + default: + return null; + } + } + + @Override + public Value emitDivMemory(ValueNode x, ValueNode y, Access access) { + return null; + } + + @Override + public Value emitRemMemory(ValueNode x, ValueNode y, Access access) { + return null; + } + + @Override + public Value emitAndMemory(ValueNode x, ValueNode y, Access access) { + Kind kind = access.nullCheckLocation().getValueKind(); + switch (kind) { + case Int: + return emitBinaryMemory(IAND, true, x, y, access); + case Long: + return emitBinaryMemory(LAND, true, x, y, access); + case Short: { + ValueNode other = x == access ? y : x; + Constant constant = other instanceof ConstantNode ? ((ConstantNode) other).asConstant() : null; + if (constant != null && constant.asInt() == IntegerStamp.defaultMask(kind.getBitCount())) { + // Convert to unsigned load + ensureEvaluated(other); + return emitZeroExtendMemory(16, 32, access); + } + return null; + } + case Byte: { + if (OptFoldMemory.getValue()) { + return null; + } + ValueNode other = x == access ? y : x; + Constant constant = other instanceof ConstantNode ? ((ConstantNode) other).asConstant() : null; + if (constant != null && constant.asInt() == IntegerStamp.defaultMask(kind.getBitCount())) { + // Convert to unsigned load + ensureEvaluated(other); + return emitConvert2MemoryOp(Kind.Int, MOV_B2UI, access); + } + return null; + } + + default: + return null; + } + } + + @Override + public Value emitOrMemory(ValueNode x, ValueNode y, Access access) { + switch (access.nullCheckLocation().getValueKind()) { + case Int: + return emitBinaryMemory(IOR, true, x, y, access); + case Long: + return emitBinaryMemory(LOR, true, x, y, access); + default: + return null; + } + } + + @Override + public Value emitXorMemory(ValueNode x, ValueNode y, Access access) { + switch (access.nullCheckLocation().getValueKind()) { + case Int: + return emitBinaryMemory(IXOR, true, x, y, access); + case Long: + return emitBinaryMemory(LXOR, true, x, y, access); + default: + return null; + } + } + + @Override + public Value emitReinterpretMemory(Stamp stamp, Access access) { + PlatformKind to = gen.getLIRGenerator().getPlatformKind(stamp); + Kind from = access.nullCheckLocation().getValueKind(); + assert to != from : "should have been eliminated"; + + /* + * Conversions between integer to floating point types require moves between CPU and FPU + * registers. + */ + switch ((Kind) to) { + case Int: + switch (from) { + case Float: + return emitConvert2MemoryOp(to, MOV_F2I, access); + } + break; + case Long: + switch (from) { + case Double: + return emitConvert2MemoryOp(to, MOV_D2L, access); + } + break; + case Float: + switch (from) { + case Int: + return emitConvert2MemoryOp(to, MOV_I2F, access); + } + break; + case Double: + switch (from) { + case Long: + return emitConvert2MemoryOp(to, MOV_L2D, access); + } + break; + } + throw GraalInternalError.shouldNotReachHere(); + } + + @Override + public Value emitFloatConvertMemory(FloatConvert op, Access access) { + switch (op) { + case D2F: + return emitConvert2MemoryOp(Kind.Float, D2F, access); + case D2I: + return emitConvert2MemoryOp(Kind.Int, D2I, access); + case D2L: + return emitConvert2MemoryOp(Kind.Long, D2L, access); + case F2D: + return emitConvert2MemoryOp(Kind.Double, F2D, access); + case F2I: + return emitConvert2MemoryOp(Kind.Int, F2I, access); + case F2L: + return emitConvert2MemoryOp(Kind.Long, F2L, access); + case I2D: + return emitConvert2MemoryOp(Kind.Double, I2D, access); + case I2F: + return emitConvert2MemoryOp(Kind.Float, I2F, access); + case L2D: + return emitConvert2MemoryOp(Kind.Double, L2D, access); + case L2F: + return emitConvert2MemoryOp(Kind.Float, L2F, access); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + @Override + public Value emitSignExtendMemory(Access access, int fromBits, int toBits) { + assert fromBits <= toBits && toBits <= 64; + if (fromBits == toBits) { + return null; + } else if (toBits > 32) { + // sign extend to 64 bits + switch (fromBits) { + case 8: + return emitConvert2MemoryOp(Kind.Long, B2L, access); + case 16: + return emitConvert2MemoryOp(Kind.Long, S2L, access); + case 32: + return emitConvert2MemoryOp(Kind.Long, I2L, access); + default: + throw GraalInternalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)"); + } + } else { + + // sign extend to 32 bits (smaller values are internally represented as 32 bit values) + switch (fromBits) { + case 8: + return emitConvert2MemoryOp(Kind.Int, B2I, access); + case 16: + return emitConvert2MemoryOp(Kind.Int, S2I, access); + case 32: + return null; + default: + throw GraalInternalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)"); + } + } + } + + @Override + public Value emitNarrowMemory(int resultBits, Access access) { + // TODO + return null; + } + + @Override + public Value emitZeroExtendMemory(int inputBits, int resultBits, Access access) { + assert resultBits == 32 || resultBits == 64; + Kind memoryKind = access.nullCheckLocation().getValueKind(); + if (memoryKind.getBitCount() != inputBits && !memoryKind.isUnsigned()) { + // The memory being read from is signed and smaller than the result size so + // this is a sign extension to inputBits followed by a zero extension to resultBits + // which can't be expressed in a memory operation. + return null; + } + if (memoryKind == Kind.Short) { + memoryKind = Kind.Char; + } + evaluateDeferred(); + return gen.getLIRGenerator().emitZeroExtendMemory(memoryKind, resultBits, makeAddress(access), getState(access)); + } + + public boolean emitIfMemory(IfNode x, Access access) { + return emitBranchMemory(x.condition(), access, gen.getLIRBlock(x.trueSuccessor()), gen.getLIRBlock(x.falseSuccessor()), x.probability(x.trueSuccessor())); + } + + private boolean emitBranchMemory(LogicNode node, Access access, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) { + if (node instanceof IsNullNode) { + // can't do anything interesting. + return false; + } else if (node instanceof CompareNode) { + CompareNode compare = (CompareNode) node; + return emitCompareBranchMemory(compare, access, trueSuccessor, falseSuccessor, trueSuccessorProbability); + } else if (node instanceof LogicConstantNode) { + return false; + } else if (node instanceof IntegerTestNode) { + return emitIntegerTestBranchMemory((IntegerTestNode) node, access, trueSuccessor, falseSuccessor, trueSuccessorProbability); + } else { + throw GraalInternalError.unimplemented(node.toString()); + } + } + + public boolean emitCompareBranchMemory(CompareNode compare, Access access, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) { + return emitCompareBranchMemory(compare.x(), compare.y(), access, compare.condition(), compare.unorderedIsTrue(), trueSuccessor, falseSuccessor, trueSuccessorProbability); + } + + public boolean emitIntegerTestBranchMemory(IntegerTestNode test, Access access, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) { + return emitIntegerTestBranchMemory(test.x(), test.y(), access, trueSuccessor, falseSuccessor, trueSuccessorProbability); + } + + private boolean emitIntegerTestBranchMemory(ValueNode left, ValueNode right, Access access, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) { + assert left == access || right == access; + ValueNode other = left == access ? right : left; + Kind kind = access.nullCheckLocation().getValueKind(); + if (other.isConstant()) { + Constant constant = other.asConstant(); + if (kind == Kind.Long && !NumUtil.isInt(constant.asLong())) { + // Only imm32 as long + return false; + } + ensureEvaluated(other); + gen.append(new AMD64TestMemoryOp(makeAddress(access), constant, getState(access))); + } else { + evaluateDeferred(); + gen.append(new AMD64TestMemoryOp(makeAddress(access), gen.operand(other), getState(access))); + } + + gen.append(new BranchOp(Condition.EQ, trueLabel, falseLabel, trueLabelProbability)); + return true; + } + + protected boolean emitCompareBranchMemory(ValueNode left, ValueNode right, Access access, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel, + double trueLabelProbability) { + assert left == access || right == access; + ValueNode other = left == access ? right : left; + Kind kind = access.nullCheckLocation().getValueKind(); + boolean mirrored = false; + + if (other.isConstant()) { + Constant constant = other.asConstant(); + if (kind == Kind.Long && !NumUtil.isInt(constant.asLong())) { + // Only imm32 as long + return false; + } + if (kind.isNumericFloat()) { + Debug.log("Skipping constant compares for float kinds"); + return false; + } + if (kind == Kind.Object) { + if (!access.isCompressible() && !constant.isNull()) { + Debug.log("Skipping constant compares for Object kinds"); + return false; + } + } + if (kind != kind.getStackKind()) { + Debug.log("Skipping constant compares for stack kinds"); + return false; + } + ensureEvaluated(other); + gen.getLIRGenerator().emitCompareMemoryConOp(kind, makeAddress(access), constant, getState(access)); + mirrored = right == access; + } else { + if (kind != kind.getStackKind()) { + // Register compares only work for stack kinds + Debug.log("Register compares only work for stack kinds"); + return false; + } else if (kind == Kind.Object) { + // Can't compare against objects since they require encode/decode + Debug.log("Skipping compares for Object kinds"); + return false; + } + + evaluateDeferred(); + gen.getLIRGenerator().emitCompareRegMemoryOp(kind, gen.operand(other), makeAddress(access), getState(access)); + mirrored = left == access; + } + + Condition finalCondition = mirrored ? cond.mirror() : cond; + switch (kind.getStackKind()) { + case Long: + case Int: + case Object: + gen.append(new BranchOp(finalCondition, trueLabel, falseLabel, trueLabelProbability)); + return true; + case Float: + case Double: + gen.append(new FloatBranchOp(finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability)); + return true; + default: + throw GraalInternalError.shouldNotReachHere("" + kind.getStackKind()); + } + } +} diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRGenerator.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRGenerator.java Wed Mar 26 20:44:11 2014 +0100 @@ -31,6 +31,7 @@ import com.oracle.graal.lir.amd64.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; public abstract class AMD64NodeLIRGenerator extends NodeLIRGenerator { @@ -38,6 +39,17 @@ super(graph, res, gen); } + protected MemoryArithmeticLIRLowerer memoryPeephole; + + @Override + public MemoryArithmeticLIRLowerer getMemoryLowerer() { + if (memoryPeephole == null) { + // Use the generic one + memoryPeephole = new AMD64MemoryPeephole(this); + } + return memoryPeephole; + } + @Override protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { AllocatableValue targetAddress = AMD64.rax.asValue(); @@ -93,4 +105,9 @@ public void visitInfopointNode(InfopointNode i) { append(new InfopointOp(stateFor(i.getState()), i.reason)); } + + @Override + public AMD64LIRGenerator getLIRGenerator() { + return (AMD64LIRGenerator) gen; + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java --- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Wed Mar 26 20:44:11 2014 +0100 @@ -113,6 +113,10 @@ } } + public void emitData(AllocatableValue dst, byte[] data) { + throw GraalInternalError.unimplemented(); + } + public HSAILAddressValue asAddressValue(Value address) { if (address instanceof HSAILAddressValue) { return (HSAILAddressValue) address; diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ObjectPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ObjectPTXTest.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ObjectPTXTest.java Wed Mar 26 20:44:11 2014 +0100 @@ -66,6 +66,7 @@ return a.i + i; } + @Ignore("com.oracle.graal.graph.GraalInternalError: should not reach here: unhandled register type v3|z") @Test public void test2() { A a = new A(); @@ -79,6 +80,7 @@ return a.z; } + @Ignore("[CUDA] Check for malformed PTX kernel or incorrect PTX compilation options") @Test public void test3() { for (byte b : new byte[]{Byte.MIN_VALUE, -10, 0, 1, 2, 10, Byte.MAX_VALUE}) { @@ -92,6 +94,7 @@ return a.b + b; } + @Ignore("com.oracle.graal.graph.GraalInternalError: should not reach here: unhandled register type v5|s") @Test public void test4() { for (short s : new short[]{Short.MIN_VALUE, -10, 0, 1, 2, 10, Short.MAX_VALUE}) { diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Wed Mar 26 20:44:11 2014 +0100 @@ -167,6 +167,11 @@ } @Override + public void emitData(AllocatableValue dst, byte[] data) { + throw GraalInternalError.unimplemented(); + } + + @Override public PTXAddressValue emitAddress(Value base, long displacement, Value index, int scale) { AllocatableValue baseRegister; long finalDisp = displacement; diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Wed Mar 26 20:44:11 2014 +0100 @@ -130,6 +130,11 @@ } @Override + public void emitData(AllocatableValue dst, byte[] data) { + throw GraalInternalError.unimplemented(); + } + + @Override public SPARCAddressValue emitAddress(Value base, long displacement, Value index, int scale) { AllocatableValue baseRegister; long finalDisp = displacement; diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Wed Mar 26 20:44:11 2014 +0100 @@ -321,6 +321,7 @@ Assumptions assumptions = new Assumptions(false); HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); + canonicalizer.apply(graph, context); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); if (loopPeeling) { new LoopTransformHighPhase().apply(graph); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Wed Mar 26 20:44:11 2014 +0100 @@ -158,6 +158,7 @@ new VerifyUsageWithEquals(JavaType.class).apply(graph, context); new VerifyUsageWithEquals(JavaMethod.class).apply(graph, context); new VerifyUsageWithEquals(JavaField.class).apply(graph, context); + new VerifyDebugUsage().apply(graph, context); } private static boolean matches(String[] filters, String s) { diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfReorderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfReorderTest.java Wed Mar 26 20:44:11 2014 +0100 @@ -0,0 +1,54 @@ +/* + * 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.oracle.graal.compiler.test; + +import java.io.*; +import java.util.*; + +import org.junit.*; + +public class IfReorderTest extends GraalCompilerTest { + + private static Object fieldA = Integer.class; + private static Object fieldB = Double.class; + + @Test + public void test1() { + test("test1Snippet", new ArrayList<>()); + } + + public static Object test1Snippet(Object o) { + /* + * Serializable and List are not mutually exclusive, so these two IFs should never be + * reordered. + */ + if (branchProbability(0.1, o instanceof Serializable)) { + return fieldA; + } + if (branchProbability(0.9, o instanceof List)) { + return fieldB; + } + return null; + } + +} diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IntegerEqualsCanonicalizerTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IntegerEqualsCanonicalizerTest.java Wed Mar 26 20:44:11 2014 +0100 @@ -0,0 +1,123 @@ +/* + * 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.oracle.graal.compiler.test; + +import org.junit.*; + +import com.oracle.graal.nodes.*; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; + +public class IntegerEqualsCanonicalizerTest extends GraalCompilerTest { + + @Test + public void testShiftEquals() { + /* + * tests the canonicalization of (x >>> const) == 0 to x |test| (-1 << const) + */ + test("testShiftEqualsSnippet", "testShiftEqualsReference"); + } + + @SuppressWarnings("unused") private static int field; + + public static void testShiftEqualsSnippet(int x, int[] array, int y) { + // optimize + field = (x >>> 10) == 0 ? 1 : 0; + field = (array.length >> 10) == 0 ? 1 : 0; + field = (x << 10) == 0 ? 1 : 0; + // don't optimize + field = (x >> 10) == 0 ? 1 : 0; + field = (x >>> y) == 0 ? 1 : 0; + field = (x >> y) == 0 ? 1 : 0; + field = (x << y) == 0 ? 1 : 0; + field = (x >>> y) == 1 ? 1 : 0; + field = (x >> y) == 1 ? 1 : 0; + field = (x << y) == 1 ? 1 : 0; + } + + public static void testShiftEqualsReference(int x, int[] array, int y) { + field = (x & 0xfffffc00) == 0 ? 1 : 0; + field = (array.length & 0xfffffc00) == 0 ? 1 : 0; + field = (x & 0x3fffff) == 0 ? 1 : 0; + // don't optimize signed right shifts + field = (x >> 10) == 0 ? 1 : 0; + // don't optimize no-constant shift amounts + field = (x >>> y) == 0 ? 1 : 0; + field = (x >> y) == 0 ? 1 : 0; + field = (x << y) == 0 ? 1 : 0; + // don't optimize non-zero comparisons + field = (x >>> y) == 1 ? 1 : 0; + field = (x >> y) == 1 ? 1 : 0; + field = (x << y) == 1 ? 1 : 0; + } + + @Test + public void testCompare() { + test("testCompareSnippet", "testCompareReference"); + } + + public static void testCompareSnippet(int x, int y, int[] array1, int[] array2) { + int tempX = x; + int array1Length = array1.length; + int array2Length = array2.length; + // optimize + field = x == tempX ? 1 : 0; + field = x != tempX ? 1 : 0; + field = array1Length != (-1 - array2Length) ? 1 : 0; + field = array1Length == (-1 - array2Length) ? 1 : 0; + // don't optimize + field = x == y ? 1 : 0; + field = array1Length == array2Length ? 1 : 0; + field = array1Length == (-array2Length) ? 1 : 0; + } + + public static void testCompareReference(int x, int y, int[] array1, int[] array2) { + int array1Length = array1.length; + int array2Length = array2.length; + // optimize + field = 1; + field = 0; + field = 1; + field = 0; + // don't optimize (overlapping value ranges) + field = x == y ? 1 : 0; + field = array1Length == array2Length ? 1 : 0; + field = array1Length == (-array2Length) ? 1 : 0; + } + + private void test(String snippet, String referenceSnippet) { + StructuredGraph graph = getCanonicalizedGraph(snippet); + StructuredGraph referenceGraph = getCanonicalizedGraph(referenceSnippet); + assertEquals(referenceGraph, graph); + } + + private StructuredGraph getCanonicalizedGraph(String snippet) { + StructuredGraph graph = parse(snippet); + new CanonicalizerPhase(false).apply(graph, new PhaseContext(getProviders(), null)); + for (FrameState state : graph.getNodes(FrameState.class).snapshot()) { + state.replaceAtUsages(null); + state.safeDelete(); + } + return graph; + } +} diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryArithmeticTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryArithmeticTest.java Wed Mar 26 20:44:11 2014 +0100 @@ -0,0 +1,4333 @@ +/* + * Copyright (c) 2014, 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.oracle.graal.compiler.test; + +import java.lang.reflect.*; + +import org.junit.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; + +public class MemoryArithmeticTest extends GraalCompilerTest { + + @Override + protected InstalledCode getCode(ResolvedJavaMethod method, StructuredGraph graph) { + return super.getCode(method, graph, true); + } + + /** + * Called before a test is executed. + */ + @Override + protected void before(Method method) { + // don't let any null exception tracking change the generated code. + getMetaAccess().lookupJavaMethod(method).reprofile(); + } + + /** + * A dummy field used by some tests to create side effects. + */ + protected static int count; + + static class FieldObject { + boolean booleanValue; + byte byteValue; + short shortValue; + char charValue; + int intValue; + float floatValue; + long longValue; + double doubleValue; + Object objectValue; + } + + static FieldObject maxObject = new FieldObject(); + static FieldObject minObject; + + static final boolean booleanTestValue1 = false; + static final byte byteTestValue1 = 0; + static final short shortTestValue1 = 0; + static final char charTestValue1 = 0; + static final int intTestValue1 = 0; + static final float floatTestValue1 = 0; + static final long longTestValue1 = 0; + static final double doubleTestValue1 = 0; + static final Object objectTestValue1 = null; + + static final boolean booleanTestValue2 = true; + static final byte byteTestValue2 = Byte.MAX_VALUE; + static final short shortTestValue2 = Short.MAX_VALUE; + static final char charTestValue2 = Character.MAX_VALUE; + static final int intTestValue2 = Integer.MAX_VALUE; + static final float floatTestValue2 = Float.MAX_VALUE; + static final long longTestValue2 = Long.MAX_VALUE; + static final double doubleTestValue2 = Double.MAX_VALUE; + static final Object objectTestValue2 = "String"; + + static { + maxObject.booleanValue = true; + maxObject.byteValue = Byte.MAX_VALUE; + maxObject.shortValue = Short.MAX_VALUE; + maxObject.charValue = Character.MAX_VALUE; + maxObject.intValue = Integer.MAX_VALUE; + maxObject.floatValue = Float.MAX_VALUE; + maxObject.longValue = Long.MAX_VALUE; + maxObject.doubleValue = Double.MAX_VALUE; + maxObject.objectValue = "String"; + } + + public static Object testBooleanCompare(FieldObject f, boolean booleanValue) { + if (f.booleanValue == booleanValue) { + return f; + } + return null; + } + + public static Object testBooleanCompareConstant1(FieldObject f) { + if (f.booleanValue == booleanTestValue1) { + return f; + } + return null; + } + + public static Object testBooleanCompareConstant2(FieldObject f) { + if (f.booleanValue == booleanTestValue2) { + return f; + } + return null; + } + + @Test + public void testBooleanCompares() { + FieldObject f = new FieldObject(); + test("testBooleanCompare", f, booleanTestValue1); + test("testBooleanCompareConstant1", f); + test("testBooleanCompareConstant2", f); + } + + @Test + public void testBooleanNullCompares() { + test("testBooleanCompare", null, booleanTestValue1); + } + + @Test + public void testBooleanNullCompares1() { + test("testBooleanCompareConstant1", (Object) null); + } + + @Test + public void testBooleanNullCompares2() { + test("testBooleanCompareConstant2", (Object) null); + } + + public static Object testByteCompare(FieldObject f, byte byteValue) { + if (f.byteValue == byteValue) { + return f; + } + return null; + } + + public static Object testByteCompareConstant1(FieldObject f) { + if (f.byteValue == byteTestValue1) { + return f; + } + return null; + } + + public static Object testByteCompareConstant2(FieldObject f) { + if (f.byteValue == byteTestValue2) { + return f; + } + return null; + } + + @Test + public void testByteCompares() { + FieldObject f = new FieldObject(); + test("testByteCompare", f, byteTestValue1); + test("testByteCompareConstant1", f); + test("testByteCompareConstant2", f); + } + + @Test + public void testByteNullCompares() { + test("testByteCompare", null, byteTestValue1); + } + + @Test + public void testByteNullCompares1() { + test("testByteCompareConstant1", (Object) null); + } + + @Test + public void testByteNullCompares2() { + test("testByteCompareConstant2", (Object) null); + } + + public static Object testByteCompareLess(FieldObject f, byte byteValue) { + if (f.byteValue < byteValue) { + return f; + } + return null; + } + + public static Object testByteCompareLessConstant1(FieldObject f) { + if (f.byteValue < byteTestValue1) { + return f; + } + return null; + } + + public static Object testByteCompareLessConstant2(FieldObject f) { + if (f.byteValue < byteTestValue2) { + return f; + } + return null; + } + + @Test + public void testByteComparesLess() { + FieldObject f = new FieldObject(); + test("testByteCompareLess", f, byteTestValue1); + test("testByteCompareLessConstant1", f); + test("testByteCompareLessConstant2", f); + } + + @Test + public void testByteNullComparesLess() { + test("testByteCompareLess", null, byteTestValue1); + } + + @Test + public void testByteNullComparesLess1() { + test("testByteCompareLessConstant1", (Object) null); + } + + @Test + public void testByteNullComparesLess2() { + test("testByteCompareLessConstant2", (Object) null); + } + + public static Object testByteSwappedCompareLess(FieldObject f, byte byteValue) { + if (byteValue < f.byteValue) { + return f; + } + return null; + } + + public static Object testByteSwappedCompareLessConstant1(FieldObject f) { + if (byteTestValue1 < f.byteValue) { + return f; + } + return null; + } + + public static Object testByteSwappedCompareLessConstant2(FieldObject f) { + if (byteTestValue2 < f.byteValue) { + return f; + } + return null; + } + + @Test + public void testByteSwappedComparesLess() { + FieldObject f = new FieldObject(); + test("testByteSwappedCompareLess", f, byteTestValue1); + test("testByteSwappedCompareLessConstant1", f); + test("testByteSwappedCompareLessConstant2", f); + } + + @Test + public void testByteNullSwappedComparesLess() { + test("testByteSwappedCompareLess", null, byteTestValue1); + } + + @Test + public void testByteNullSwappedComparesLess1() { + test("testByteSwappedCompareLessConstant1", (Object) null); + } + + @Test + public void testByteNullSwappedComparesLess2() { + test("testByteSwappedCompareLessConstant2", (Object) null); + } + + public static Object testByteCompareLessEqual(FieldObject f, byte byteValue) { + if (f.byteValue <= byteValue) { + return f; + } + return null; + } + + public static Object testByteCompareLessEqualConstant1(FieldObject f) { + if (f.byteValue <= byteTestValue1) { + return f; + } + return null; + } + + public static Object testByteCompareLessEqualConstant2(FieldObject f) { + if (f.byteValue <= byteTestValue2) { + return f; + } + return null; + } + + @Test + public void testByteComparesLessEqual() { + FieldObject f = new FieldObject(); + test("testByteCompareLessEqual", f, byteTestValue1); + test("testByteCompareLessEqualConstant1", f); + test("testByteCompareLessEqualConstant2", f); + } + + @Test + public void testByteNullComparesLessEqual() { + test("testByteCompareLessEqual", null, byteTestValue1); + } + + @Test + public void testByteNullComparesLessEqual1() { + test("testByteCompareLessEqualConstant1", (Object) null); + } + + @Test + public void testByteNullComparesLessEqual2() { + test("testByteCompareLessEqualConstant2", (Object) null); + } + + public static Object testByteSwappedCompareLessEqual(FieldObject f, byte byteValue) { + if (byteValue <= f.byteValue) { + return f; + } + return null; + } + + public static Object testByteSwappedCompareLessEqualConstant1(FieldObject f) { + if (byteTestValue1 <= f.byteValue) { + return f; + } + return null; + } + + public static Object testByteSwappedCompareLessEqualConstant2(FieldObject f) { + if (byteTestValue2 <= f.byteValue) { + return f; + } + return null; + } + + @Test + public void testByteSwappedComparesLessEqual() { + FieldObject f = new FieldObject(); + test("testByteSwappedCompareLessEqual", f, byteTestValue1); + test("testByteSwappedCompareLessEqualConstant1", f); + test("testByteSwappedCompareLessEqualConstant2", f); + } + + @Test + public void testByteNullSwappedComparesLessEqual() { + test("testByteSwappedCompareLessEqual", null, byteTestValue1); + } + + @Test + public void testByteNullSwappedComparesLessEqual1() { + test("testByteSwappedCompareLessEqualConstant1", (Object) null); + } + + @Test + public void testByteNullSwappedComparesLessEqual2() { + test("testByteSwappedCompareLessEqualConstant2", (Object) null); + } + + public static Object testByteCompareGreater(FieldObject f, byte byteValue) { + if (f.byteValue > byteValue) { + return f; + } + return null; + } + + public static Object testByteCompareGreaterConstant1(FieldObject f) { + if (f.byteValue > byteTestValue1) { + return f; + } + return null; + } + + public static Object testByteCompareGreaterConstant2(FieldObject f) { + if (f.byteValue > byteTestValue2) { + return f; + } + return null; + } + + @Test + public void testByteComparesGreater() { + FieldObject f = new FieldObject(); + test("testByteCompareGreater", f, byteTestValue1); + test("testByteCompareGreaterConstant1", f); + test("testByteCompareGreaterConstant2", f); + } + + @Test + public void testByteNullComparesGreater() { + test("testByteCompareGreater", null, byteTestValue1); + } + + @Test + public void testByteNullComparesGreater1() { + test("testByteCompareGreaterConstant1", (Object) null); + } + + @Test + public void testByteNullComparesGreater2() { + test("testByteCompareGreaterConstant2", (Object) null); + } + + public static Object testByteSwappedCompareGreater(FieldObject f, byte byteValue) { + if (byteValue > f.byteValue) { + return f; + } + return null; + } + + public static Object testByteSwappedCompareGreaterConstant1(FieldObject f) { + if (byteTestValue1 > f.byteValue) { + return f; + } + return null; + } + + public static Object testByteSwappedCompareGreaterConstant2(FieldObject f) { + if (byteTestValue2 > f.byteValue) { + return f; + } + return null; + } + + @Test + public void testByteSwappedComparesGreater() { + FieldObject f = new FieldObject(); + test("testByteSwappedCompareGreater", f, byteTestValue1); + test("testByteSwappedCompareGreaterConstant1", f); + test("testByteSwappedCompareGreaterConstant2", f); + } + + @Test + public void testByteNullSwappedComparesGreater() { + test("testByteSwappedCompareGreater", null, byteTestValue1); + } + + @Test + public void testByteNullSwappedComparesGreater1() { + test("testByteSwappedCompareGreaterConstant1", (Object) null); + } + + @Test + public void testByteNullSwappedComparesGreater2() { + test("testByteSwappedCompareGreaterConstant2", (Object) null); + } + + public static Object testByteCompareGreaterEqual(FieldObject f, byte byteValue) { + if (f.byteValue >= byteValue) { + return f; + } + return null; + } + + public static Object testByteCompareGreaterEqualConstant1(FieldObject f) { + if (f.byteValue >= byteTestValue1) { + return f; + } + return null; + } + + public static Object testByteCompareGreaterEqualConstant2(FieldObject f) { + if (f.byteValue >= byteTestValue2) { + return f; + } + return null; + } + + @Test + public void testByteComparesGreaterEqual() { + FieldObject f = new FieldObject(); + test("testByteCompareGreaterEqual", f, byteTestValue1); + test("testByteCompareGreaterEqualConstant1", f); + test("testByteCompareGreaterEqualConstant2", f); + } + + @Test + public void testByteNullComparesGreaterEqual() { + test("testByteCompareGreaterEqual", null, byteTestValue1); + } + + @Test + public void testByteNullComparesGreaterEqual1() { + test("testByteCompareGreaterEqualConstant1", (Object) null); + } + + @Test + public void testByteNullComparesGreaterEqual2() { + test("testByteCompareGreaterEqualConstant2", (Object) null); + } + + public static Object testByteSwappedCompareGreaterEqual(FieldObject f, byte byteValue) { + if (byteValue >= f.byteValue) { + return f; + } + return null; + } + + public static Object testByteSwappedCompareGreaterEqualConstant1(FieldObject f) { + if (byteTestValue1 >= f.byteValue) { + return f; + } + return null; + } + + public static Object testByteSwappedCompareGreaterEqualConstant2(FieldObject f) { + if (byteTestValue2 >= f.byteValue) { + return f; + } + return null; + } + + @Test + public void testByteSwappedComparesGreaterEqual() { + FieldObject f = new FieldObject(); + test("testByteSwappedCompareGreaterEqual", f, byteTestValue1); + test("testByteSwappedCompareGreaterEqualConstant1", f); + test("testByteSwappedCompareGreaterEqualConstant2", f); + } + + @Test + public void testByteNullSwappedComparesGreaterEqual() { + test("testByteSwappedCompareGreaterEqual", null, byteTestValue1); + } + + @Test + public void testByteNullSwappedComparesGreaterEqual1() { + test("testByteSwappedCompareGreaterEqualConstant1", (Object) null); + } + + @Test + public void testByteNullSwappedComparesGreaterEqual2() { + test("testByteSwappedCompareGreaterEqualConstant2", (Object) null); + } + + public static Object testShortCompare(FieldObject f, short shortValue) { + if (f.shortValue == shortValue) { + return f; + } + return null; + } + + public static Object testShortCompareConstant1(FieldObject f) { + if (f.shortValue == shortTestValue1) { + return f; + } + return null; + } + + public static Object testShortCompareConstant2(FieldObject f) { + if (f.shortValue == shortTestValue2) { + return f; + } + return null; + } + + @Test + public void testShortCompares() { + FieldObject f = new FieldObject(); + test("testShortCompare", f, shortTestValue1); + test("testShortCompareConstant1", f); + test("testShortCompareConstant2", f); + } + + @Test + public void testShortNullCompares() { + test("testShortCompare", null, shortTestValue1); + } + + @Test + public void testShortNullCompares1() { + test("testShortCompareConstant1", (Object) null); + } + + @Test + public void testShortNullCompares2() { + test("testShortCompareConstant2", (Object) null); + } + + public static Object testShortCompareLess(FieldObject f, short shortValue) { + if (f.shortValue < shortValue) { + return f; + } + return null; + } + + public static Object testShortCompareLessConstant1(FieldObject f) { + if (f.shortValue < shortTestValue1) { + return f; + } + return null; + } + + public static Object testShortCompareLessConstant2(FieldObject f) { + if (f.shortValue < shortTestValue2) { + return f; + } + return null; + } + + @Test + public void testShortComparesLess() { + FieldObject f = new FieldObject(); + test("testShortCompareLess", f, shortTestValue1); + test("testShortCompareLessConstant1", f); + test("testShortCompareLessConstant2", f); + } + + @Test + public void testShortNullComparesLess() { + test("testShortCompareLess", null, shortTestValue1); + } + + @Test + public void testShortNullComparesLess1() { + test("testShortCompareLessConstant1", (Object) null); + } + + @Test + public void testShortNullComparesLess2() { + test("testShortCompareLessConstant2", (Object) null); + } + + public static Object testShortSwappedCompareLess(FieldObject f, short shortValue) { + if (shortValue < f.shortValue) { + return f; + } + return null; + } + + public static Object testShortSwappedCompareLessConstant1(FieldObject f) { + if (shortTestValue1 < f.shortValue) { + return f; + } + return null; + } + + public static Object testShortSwappedCompareLessConstant2(FieldObject f) { + if (shortTestValue2 < f.shortValue) { + return f; + } + return null; + } + + @Test + public void testShortSwappedComparesLess() { + FieldObject f = new FieldObject(); + test("testShortSwappedCompareLess", f, shortTestValue1); + test("testShortSwappedCompareLessConstant1", f); + test("testShortSwappedCompareLessConstant2", f); + } + + @Test + public void testShortNullSwappedComparesLess() { + test("testShortSwappedCompareLess", null, shortTestValue1); + } + + @Test + public void testShortNullSwappedComparesLess1() { + test("testShortSwappedCompareLessConstant1", (Object) null); + } + + @Test + public void testShortNullSwappedComparesLess2() { + test("testShortSwappedCompareLessConstant2", (Object) null); + } + + public static Object testShortCompareLessEqual(FieldObject f, short shortValue) { + if (f.shortValue <= shortValue) { + return f; + } + return null; + } + + public static Object testShortCompareLessEqualConstant1(FieldObject f) { + if (f.shortValue <= shortTestValue1) { + return f; + } + return null; + } + + public static Object testShortCompareLessEqualConstant2(FieldObject f) { + if (f.shortValue <= shortTestValue2) { + return f; + } + return null; + } + + @Test + public void testShortComparesLessEqual() { + FieldObject f = new FieldObject(); + test("testShortCompareLessEqual", f, shortTestValue1); + test("testShortCompareLessEqualConstant1", f); + test("testShortCompareLessEqualConstant2", f); + } + + @Test + public void testShortNullComparesLessEqual() { + test("testShortCompareLessEqual", null, shortTestValue1); + } + + @Test + public void testShortNullComparesLessEqual1() { + test("testShortCompareLessEqualConstant1", (Object) null); + } + + @Test + public void testShortNullComparesLessEqual2() { + test("testShortCompareLessEqualConstant2", (Object) null); + } + + public static Object testShortSwappedCompareLessEqual(FieldObject f, short shortValue) { + if (shortValue <= f.shortValue) { + return f; + } + return null; + } + + public static Object testShortSwappedCompareLessEqualConstant1(FieldObject f) { + if (shortTestValue1 <= f.shortValue) { + return f; + } + return null; + } + + public static Object testShortSwappedCompareLessEqualConstant2(FieldObject f) { + if (shortTestValue2 <= f.shortValue) { + return f; + } + return null; + } + + @Test + public void testShortSwappedComparesLessEqual() { + FieldObject f = new FieldObject(); + test("testShortSwappedCompareLessEqual", f, shortTestValue1); + test("testShortSwappedCompareLessEqualConstant1", f); + test("testShortSwappedCompareLessEqualConstant2", f); + } + + @Test + public void testShortNullSwappedComparesLessEqual() { + test("testShortSwappedCompareLessEqual", null, shortTestValue1); + } + + @Test + public void testShortNullSwappedComparesLessEqual1() { + test("testShortSwappedCompareLessEqualConstant1", (Object) null); + } + + @Test + public void testShortNullSwappedComparesLessEqual2() { + test("testShortSwappedCompareLessEqualConstant2", (Object) null); + } + + public static Object testShortCompareGreater(FieldObject f, short shortValue) { + if (f.shortValue > shortValue) { + return f; + } + return null; + } + + public static Object testShortCompareGreaterConstant1(FieldObject f) { + if (f.shortValue > shortTestValue1) { + return f; + } + return null; + } + + public static Object testShortCompareGreaterConstant2(FieldObject f) { + if (f.shortValue > shortTestValue2) { + return f; + } + return null; + } + + @Test + public void testShortComparesGreater() { + FieldObject f = new FieldObject(); + test("testShortCompareGreater", f, shortTestValue1); + test("testShortCompareGreaterConstant1", f); + test("testShortCompareGreaterConstant2", f); + } + + @Test + public void testShortNullComparesGreater() { + test("testShortCompareGreater", null, shortTestValue1); + } + + @Test + public void testShortNullComparesGreater1() { + test("testShortCompareGreaterConstant1", (Object) null); + } + + @Test + public void testShortNullComparesGreater2() { + test("testShortCompareGreaterConstant2", (Object) null); + } + + public static Object testShortSwappedCompareGreater(FieldObject f, short shortValue) { + if (shortValue > f.shortValue) { + return f; + } + return null; + } + + public static Object testShortSwappedCompareGreaterConstant1(FieldObject f) { + if (shortTestValue1 > f.shortValue) { + return f; + } + return null; + } + + public static Object testShortSwappedCompareGreaterConstant2(FieldObject f) { + if (shortTestValue2 > f.shortValue) { + return f; + } + return null; + } + + @Test + public void testShortSwappedComparesGreater() { + FieldObject f = new FieldObject(); + test("testShortSwappedCompareGreater", f, shortTestValue1); + test("testShortSwappedCompareGreaterConstant1", f); + test("testShortSwappedCompareGreaterConstant2", f); + } + + @Test + public void testShortNullSwappedComparesGreater() { + test("testShortSwappedCompareGreater", null, shortTestValue1); + } + + @Test + public void testShortNullSwappedComparesGreater1() { + test("testShortSwappedCompareGreaterConstant1", (Object) null); + } + + @Test + public void testShortNullSwappedComparesGreater2() { + test("testShortSwappedCompareGreaterConstant2", (Object) null); + } + + public static Object testShortCompareGreaterEqual(FieldObject f, short shortValue) { + if (f.shortValue >= shortValue) { + return f; + } + return null; + } + + public static Object testShortCompareGreaterEqualConstant1(FieldObject f) { + if (f.shortValue >= shortTestValue1) { + return f; + } + return null; + } + + public static Object testShortCompareGreaterEqualConstant2(FieldObject f) { + if (f.shortValue >= shortTestValue2) { + return f; + } + return null; + } + + @Test + public void testShortComparesGreaterEqual() { + FieldObject f = new FieldObject(); + test("testShortCompareGreaterEqual", f, shortTestValue1); + test("testShortCompareGreaterEqualConstant1", f); + test("testShortCompareGreaterEqualConstant2", f); + } + + @Test + public void testShortNullComparesGreaterEqual() { + test("testShortCompareGreaterEqual", null, shortTestValue1); + } + + @Test + public void testShortNullComparesGreaterEqual1() { + test("testShortCompareGreaterEqualConstant1", (Object) null); + } + + @Test + public void testShortNullComparesGreaterEqual2() { + test("testShortCompareGreaterEqualConstant2", (Object) null); + } + + public static Object testShortSwappedCompareGreaterEqual(FieldObject f, short shortValue) { + if (shortValue >= f.shortValue) { + return f; + } + return null; + } + + public static Object testShortSwappedCompareGreaterEqualConstant1(FieldObject f) { + if (shortTestValue1 >= f.shortValue) { + return f; + } + return null; + } + + public static Object testShortSwappedCompareGreaterEqualConstant2(FieldObject f) { + if (shortTestValue2 >= f.shortValue) { + return f; + } + return null; + } + + @Test + public void testShortSwappedComparesGreaterEqual() { + FieldObject f = new FieldObject(); + test("testShortSwappedCompareGreaterEqual", f, shortTestValue1); + test("testShortSwappedCompareGreaterEqualConstant1", f); + test("testShortSwappedCompareGreaterEqualConstant2", f); + } + + @Test + public void testShortNullSwappedComparesGreaterEqual() { + test("testShortSwappedCompareGreaterEqual", null, shortTestValue1); + } + + @Test + public void testShortNullSwappedComparesGreaterEqual1() { + test("testShortSwappedCompareGreaterEqualConstant1", (Object) null); + } + + @Test + public void testShortNullSwappedComparesGreaterEqual2() { + test("testShortSwappedCompareGreaterEqualConstant2", (Object) null); + } + + public static Object testCharCompare(FieldObject f, char charValue) { + if (f.charValue == charValue) { + return f; + } + return null; + } + + public static Object testCharCompareConstant1(FieldObject f) { + if (f.charValue == charTestValue1) { + return f; + } + return null; + } + + public static Object testCharCompareConstant2(FieldObject f) { + if (f.charValue == charTestValue2) { + return f; + } + return null; + } + + @Test + public void testCharCompares() { + FieldObject f = new FieldObject(); + test("testCharCompare", f, charTestValue1); + test("testCharCompareConstant1", f); + test("testCharCompareConstant2", f); + } + + @Test + public void testCharNullCompares() { + test("testCharCompare", null, charTestValue1); + } + + @Test + public void testCharNullCompares1() { + test("testCharCompareConstant1", (Object) null); + } + + @Test + public void testCharNullCompares2() { + test("testCharCompareConstant2", (Object) null); + } + + public static Object testCharCompareLess(FieldObject f, char charValue) { + if (f.charValue < charValue) { + return f; + } + return null; + } + + public static Object testCharCompareLessConstant1(FieldObject f) { + if (f.charValue < charTestValue1) { + return f; + } + return null; + } + + public static Object testCharCompareLessConstant2(FieldObject f) { + if (f.charValue < charTestValue2) { + return f; + } + return null; + } + + @Test + public void testCharComparesLess() { + FieldObject f = new FieldObject(); + test("testCharCompareLess", f, charTestValue1); + test("testCharCompareLessConstant1", f); + test("testCharCompareLessConstant2", f); + } + + @Test + public void testCharNullComparesLess() { + test("testCharCompareLess", null, charTestValue1); + } + + @Test + public void testCharNullComparesLess1() { + test("testCharCompareLessConstant1", (Object) null); + } + + @Test + public void testCharNullComparesLess2() { + test("testCharCompareLessConstant2", (Object) null); + } + + public static Object testCharSwappedCompareLess(FieldObject f, char charValue) { + if (charValue < f.charValue) { + return f; + } + return null; + } + + public static Object testCharSwappedCompareLessConstant1(FieldObject f) { + if (charTestValue1 < f.charValue) { + return f; + } + return null; + } + + public static Object testCharSwappedCompareLessConstant2(FieldObject f) { + if (charTestValue2 < f.charValue) { + return f; + } + return null; + } + + @Test + public void testCharSwappedComparesLess() { + FieldObject f = new FieldObject(); + test("testCharSwappedCompareLess", f, charTestValue1); + test("testCharSwappedCompareLessConstant1", f); + test("testCharSwappedCompareLessConstant2", f); + } + + @Test + public void testCharNullSwappedComparesLess() { + test("testCharSwappedCompareLess", null, charTestValue1); + } + + @Test + public void testCharNullSwappedComparesLess1() { + test("testCharSwappedCompareLessConstant1", (Object) null); + } + + @Test + public void testCharNullSwappedComparesLess2() { + test("testCharSwappedCompareLessConstant2", (Object) null); + } + + public static Object testCharCompareLessEqual(FieldObject f, char charValue) { + if (f.charValue <= charValue) { + return f; + } + return null; + } + + public static Object testCharCompareLessEqualConstant1(FieldObject f) { + if (f.charValue <= charTestValue1) { + return f; + } + return null; + } + + public static Object testCharCompareLessEqualConstant2(FieldObject f) { + if (f.charValue <= charTestValue2) { + return f; + } + return null; + } + + @Test + public void testCharComparesLessEqual() { + FieldObject f = new FieldObject(); + test("testCharCompareLessEqual", f, charTestValue1); + test("testCharCompareLessEqualConstant1", f); + test("testCharCompareLessEqualConstant2", f); + } + + @Test + public void testCharNullComparesLessEqual() { + test("testCharCompareLessEqual", null, charTestValue1); + } + + @Test + public void testCharNullComparesLessEqual1() { + test("testCharCompareLessEqualConstant1", (Object) null); + } + + @Test + public void testCharNullComparesLessEqual2() { + test("testCharCompareLessEqualConstant2", (Object) null); + } + + public static Object testCharSwappedCompareLessEqual(FieldObject f, char charValue) { + if (charValue <= f.charValue) { + return f; + } + return null; + } + + public static Object testCharSwappedCompareLessEqualConstant1(FieldObject f) { + if (charTestValue1 <= f.charValue) { + return f; + } + return null; + } + + public static Object testCharSwappedCompareLessEqualConstant2(FieldObject f) { + if (charTestValue2 <= f.charValue) { + return f; + } + return null; + } + + @Test + public void testCharSwappedComparesLessEqual() { + FieldObject f = new FieldObject(); + test("testCharSwappedCompareLessEqual", f, charTestValue1); + test("testCharSwappedCompareLessEqualConstant1", f); + test("testCharSwappedCompareLessEqualConstant2", f); + } + + @Test + public void testCharNullSwappedComparesLessEqual() { + test("testCharSwappedCompareLessEqual", null, charTestValue1); + } + + @Test + public void testCharNullSwappedComparesLessEqual1() { + test("testCharSwappedCompareLessEqualConstant1", (Object) null); + } + + @Test + public void testCharNullSwappedComparesLessEqual2() { + test("testCharSwappedCompareLessEqualConstant2", (Object) null); + } + + public static Object testCharCompareGreater(FieldObject f, char charValue) { + if (f.charValue > charValue) { + return f; + } + return null; + } + + public static Object testCharCompareGreaterConstant1(FieldObject f) { + if (f.charValue > charTestValue1) { + return f; + } + return null; + } + + public static Object testCharCompareGreaterConstant2(FieldObject f) { + if (f.charValue > charTestValue2) { + return f; + } + return null; + } + + @Test + public void testCharComparesGreater() { + FieldObject f = new FieldObject(); + test("testCharCompareGreater", f, charTestValue1); + test("testCharCompareGreaterConstant1", f); + test("testCharCompareGreaterConstant2", f); + } + + @Test + public void testCharNullComparesGreater() { + test("testCharCompareGreater", null, charTestValue1); + } + + @Test + public void testCharNullComparesGreater1() { + test("testCharCompareGreaterConstant1", (Object) null); + } + + @Test + public void testCharNullComparesGreater2() { + test("testCharCompareGreaterConstant2", (Object) null); + } + + public static Object testCharSwappedCompareGreater(FieldObject f, char charValue) { + if (charValue > f.charValue) { + return f; + } + return null; + } + + public static Object testCharSwappedCompareGreaterConstant1(FieldObject f) { + if (charTestValue1 > f.charValue) { + return f; + } + return null; + } + + public static Object testCharSwappedCompareGreaterConstant2(FieldObject f) { + if (charTestValue2 > f.charValue) { + return f; + } + return null; + } + + @Test + public void testCharSwappedComparesGreater() { + FieldObject f = new FieldObject(); + test("testCharSwappedCompareGreater", f, charTestValue1); + test("testCharSwappedCompareGreaterConstant1", f); + test("testCharSwappedCompareGreaterConstant2", f); + } + + @Test + public void testCharNullSwappedComparesGreater() { + test("testCharSwappedCompareGreater", null, charTestValue1); + } + + @Test + public void testCharNullSwappedComparesGreater1() { + test("testCharSwappedCompareGreaterConstant1", (Object) null); + } + + @Test + public void testCharNullSwappedComparesGreater2() { + test("testCharSwappedCompareGreaterConstant2", (Object) null); + } + + public static Object testCharCompareGreaterEqual(FieldObject f, char charValue) { + if (f.charValue >= charValue) { + return f; + } + return null; + } + + public static Object testCharCompareGreaterEqualConstant1(FieldObject f) { + if (f.charValue >= charTestValue1) { + return f; + } + return null; + } + + public static Object testCharCompareGreaterEqualConstant2(FieldObject f) { + if (f.charValue >= charTestValue2) { + return f; + } + return null; + } + + @Test + public void testCharComparesGreaterEqual() { + FieldObject f = new FieldObject(); + test("testCharCompareGreaterEqual", f, charTestValue1); + test("testCharCompareGreaterEqualConstant1", f); + test("testCharCompareGreaterEqualConstant2", f); + } + + @Test + public void testCharNullComparesGreaterEqual() { + test("testCharCompareGreaterEqual", null, charTestValue1); + } + + @Test + public void testCharNullComparesGreaterEqual1() { + test("testCharCompareGreaterEqualConstant1", (Object) null); + } + + @Test + public void testCharNullComparesGreaterEqual2() { + test("testCharCompareGreaterEqualConstant2", (Object) null); + } + + public static Object testCharSwappedCompareGreaterEqual(FieldObject f, char charValue) { + if (charValue >= f.charValue) { + return f; + } + return null; + } + + public static Object testCharSwappedCompareGreaterEqualConstant1(FieldObject f) { + if (charTestValue1 >= f.charValue) { + return f; + } + return null; + } + + public static Object testCharSwappedCompareGreaterEqualConstant2(FieldObject f) { + if (charTestValue2 >= f.charValue) { + return f; + } + return null; + } + + @Test + public void testCharSwappedComparesGreaterEqual() { + FieldObject f = new FieldObject(); + test("testCharSwappedCompareGreaterEqual", f, charTestValue1); + test("testCharSwappedCompareGreaterEqualConstant1", f); + test("testCharSwappedCompareGreaterEqualConstant2", f); + } + + @Test + public void testCharNullSwappedComparesGreaterEqual() { + test("testCharSwappedCompareGreaterEqual", null, charTestValue1); + } + + @Test + public void testCharNullSwappedComparesGreaterEqual1() { + test("testCharSwappedCompareGreaterEqualConstant1", (Object) null); + } + + @Test + public void testCharNullSwappedComparesGreaterEqual2() { + test("testCharSwappedCompareGreaterEqualConstant2", (Object) null); + } + + public static Object testIntCompare(FieldObject f, int intValue) { + if (f.intValue == intValue) { + return f; + } + return null; + } + + public static Object testIntCompareConstant1(FieldObject f) { + if (f.intValue == intTestValue1) { + return f; + } + return null; + } + + public static Object testIntCompareConstant2(FieldObject f) { + if (f.intValue == intTestValue2) { + return f; + } + return null; + } + + @Test + public void testIntCompares() { + FieldObject f = new FieldObject(); + test("testIntCompare", f, intTestValue1); + test("testIntCompareConstant1", f); + test("testIntCompareConstant2", f); + } + + @Test + public void testIntNullCompares() { + test("testIntCompare", null, intTestValue1); + } + + @Test + public void testIntNullCompares1() { + test("testIntCompareConstant1", (Object) null); + } + + @Test + public void testIntNullCompares2() { + test("testIntCompareConstant2", (Object) null); + } + + public static Object testIntCompareLess(FieldObject f, int intValue) { + if (f.intValue < intValue) { + return f; + } + return null; + } + + public static Object testIntCompareLessConstant1(FieldObject f) { + if (f.intValue < intTestValue1) { + return f; + } + return null; + } + + public static Object testIntCompareLessConstant2(FieldObject f) { + if (f.intValue < intTestValue2) { + return f; + } + return null; + } + + @Test + public void testIntComparesLess() { + FieldObject f = new FieldObject(); + test("testIntCompareLess", f, intTestValue1); + test("testIntCompareLessConstant1", f); + test("testIntCompareLessConstant2", f); + } + + @Test + public void testIntNullComparesLess() { + test("testIntCompareLess", null, intTestValue1); + } + + @Test + public void testIntNullComparesLess1() { + test("testIntCompareLessConstant1", (Object) null); + } + + @Test + public void testIntNullComparesLess2() { + test("testIntCompareLessConstant2", (Object) null); + } + + public static Object testIntSwappedCompareLess(FieldObject f, int intValue) { + if (intValue < f.intValue) { + return f; + } + return null; + } + + public static Object testIntSwappedCompareLessConstant1(FieldObject f) { + if (intTestValue1 < f.intValue) { + return f; + } + return null; + } + + public static Object testIntSwappedCompareLessConstant2(FieldObject f) { + if (intTestValue2 < f.intValue) { + return f; + } + return null; + } + + @Test + public void testIntSwappedComparesLess() { + FieldObject f = new FieldObject(); + test("testIntSwappedCompareLess", f, intTestValue1); + test("testIntSwappedCompareLessConstant1", f); + test("testIntSwappedCompareLessConstant2", f); + } + + @Test + public void testIntNullSwappedComparesLess() { + test("testIntSwappedCompareLess", null, intTestValue1); + } + + @Test + public void testIntNullSwappedComparesLess1() { + test("testIntSwappedCompareLessConstant1", (Object) null); + } + + @Test + public void testIntNullSwappedComparesLess2() { + test("testIntSwappedCompareLessConstant2", (Object) null); + } + + public static Object testIntCompareLessEqual(FieldObject f, int intValue) { + if (f.intValue <= intValue) { + return f; + } + return null; + } + + public static Object testIntCompareLessEqualConstant1(FieldObject f) { + if (f.intValue <= intTestValue1) { + return f; + } + return null; + } + + public static Object testIntCompareLessEqualConstant2(FieldObject f) { + if (f.intValue <= intTestValue2) { + return f; + } + return null; + } + + @Test + public void testIntComparesLessEqual() { + FieldObject f = new FieldObject(); + test("testIntCompareLessEqual", f, intTestValue1); + test("testIntCompareLessEqualConstant1", f); + test("testIntCompareLessEqualConstant2", f); + } + + @Test + public void testIntNullComparesLessEqual() { + test("testIntCompareLessEqual", null, intTestValue1); + } + + @Test + public void testIntNullComparesLessEqual1() { + test("testIntCompareLessEqualConstant1", (Object) null); + } + + @Test + public void testIntNullComparesLessEqual2() { + test("testIntCompareLessEqualConstant2", (Object) null); + } + + public static Object testIntSwappedCompareLessEqual(FieldObject f, int intValue) { + if (intValue <= f.intValue) { + return f; + } + return null; + } + + public static Object testIntSwappedCompareLessEqualConstant1(FieldObject f) { + if (intTestValue1 <= f.intValue) { + return f; + } + return null; + } + + public static Object testIntSwappedCompareLessEqualConstant2(FieldObject f) { + if (intTestValue2 <= f.intValue) { + return f; + } + return null; + } + + @Test + public void testIntSwappedComparesLessEqual() { + FieldObject f = new FieldObject(); + test("testIntSwappedCompareLessEqual", f, intTestValue1); + test("testIntSwappedCompareLessEqualConstant1", f); + test("testIntSwappedCompareLessEqualConstant2", f); + } + + @Test + public void testIntNullSwappedComparesLessEqual() { + test("testIntSwappedCompareLessEqual", null, intTestValue1); + } + + @Test + public void testIntNullSwappedComparesLessEqual1() { + test("testIntSwappedCompareLessEqualConstant1", (Object) null); + } + + @Test + public void testIntNullSwappedComparesLessEqual2() { + test("testIntSwappedCompareLessEqualConstant2", (Object) null); + } + + public static Object testIntCompareGreater(FieldObject f, int intValue) { + if (f.intValue > intValue) { + return f; + } + return null; + } + + public static Object testIntCompareGreaterConstant1(FieldObject f) { + if (f.intValue > intTestValue1) { + return f; + } + return null; + } + + public static Object testIntCompareGreaterConstant2(FieldObject f) { + if (f.intValue > intTestValue2) { + return f; + } + return null; + } + + @Test + public void testIntComparesGreater() { + FieldObject f = new FieldObject(); + test("testIntCompareGreater", f, intTestValue1); + test("testIntCompareGreaterConstant1", f); + test("testIntCompareGreaterConstant2", f); + } + + @Test + public void testIntNullComparesGreater() { + test("testIntCompareGreater", null, intTestValue1); + } + + @Test + public void testIntNullComparesGreater1() { + test("testIntCompareGreaterConstant1", (Object) null); + } + + @Test + public void testIntNullComparesGreater2() { + test("testIntCompareGreaterConstant2", (Object) null); + } + + public static Object testIntSwappedCompareGreater(FieldObject f, int intValue) { + if (intValue > f.intValue) { + return f; + } + return null; + } + + public static Object testIntSwappedCompareGreaterConstant1(FieldObject f) { + if (intTestValue1 > f.intValue) { + return f; + } + return null; + } + + public static Object testIntSwappedCompareGreaterConstant2(FieldObject f) { + if (intTestValue2 > f.intValue) { + return f; + } + return null; + } + + @Test + public void testIntSwappedComparesGreater() { + FieldObject f = new FieldObject(); + test("testIntSwappedCompareGreater", f, intTestValue1); + test("testIntSwappedCompareGreaterConstant1", f); + test("testIntSwappedCompareGreaterConstant2", f); + } + + @Test + public void testIntNullSwappedComparesGreater() { + test("testIntSwappedCompareGreater", null, intTestValue1); + } + + @Test + public void testIntNullSwappedComparesGreater1() { + test("testIntSwappedCompareGreaterConstant1", (Object) null); + } + + @Test + public void testIntNullSwappedComparesGreater2() { + test("testIntSwappedCompareGreaterConstant2", (Object) null); + } + + public static Object testIntCompareGreaterEqual(FieldObject f, int intValue) { + if (f.intValue >= intValue) { + return f; + } + return null; + } + + public static Object testIntCompareGreaterEqualConstant1(FieldObject f) { + if (f.intValue >= intTestValue1) { + return f; + } + return null; + } + + public static Object testIntCompareGreaterEqualConstant2(FieldObject f) { + if (f.intValue >= intTestValue2) { + return f; + } + return null; + } + + @Test + public void testIntComparesGreaterEqual() { + FieldObject f = new FieldObject(); + test("testIntCompareGreaterEqual", f, intTestValue1); + test("testIntCompareGreaterEqualConstant1", f); + test("testIntCompareGreaterEqualConstant2", f); + } + + @Test + public void testIntNullComparesGreaterEqual() { + test("testIntCompareGreaterEqual", null, intTestValue1); + } + + @Test + public void testIntNullComparesGreaterEqual1() { + test("testIntCompareGreaterEqualConstant1", (Object) null); + } + + @Test + public void testIntNullComparesGreaterEqual2() { + test("testIntCompareGreaterEqualConstant2", (Object) null); + } + + public static Object testIntSwappedCompareGreaterEqual(FieldObject f, int intValue) { + if (intValue >= f.intValue) { + return f; + } + return null; + } + + public static Object testIntSwappedCompareGreaterEqualConstant1(FieldObject f) { + if (intTestValue1 >= f.intValue) { + return f; + } + return null; + } + + public static Object testIntSwappedCompareGreaterEqualConstant2(FieldObject f) { + if (intTestValue2 >= f.intValue) { + return f; + } + return null; + } + + @Test + public void testIntSwappedComparesGreaterEqual() { + FieldObject f = new FieldObject(); + test("testIntSwappedCompareGreaterEqual", f, intTestValue1); + test("testIntSwappedCompareGreaterEqualConstant1", f); + test("testIntSwappedCompareGreaterEqualConstant2", f); + } + + @Test + public void testIntNullSwappedComparesGreaterEqual() { + test("testIntSwappedCompareGreaterEqual", null, intTestValue1); + } + + @Test + public void testIntNullSwappedComparesGreaterEqual1() { + test("testIntSwappedCompareGreaterEqualConstant1", (Object) null); + } + + @Test + public void testIntNullSwappedComparesGreaterEqual2() { + test("testIntSwappedCompareGreaterEqualConstant2", (Object) null); + } + + public static Object testFloatCompare(FieldObject f, float floatValue) { + if (f.floatValue == floatValue) { + return f; + } + return null; + } + + public static Object testFloatCompareConstant1(FieldObject f) { + if (f.floatValue == floatTestValue1) { + return f; + } + return null; + } + + public static Object testFloatCompareConstant2(FieldObject f) { + if (f.floatValue == floatTestValue2) { + return f; + } + return null; + } + + @Test + public void testFloatCompares() { + FieldObject f = new FieldObject(); + test("testFloatCompare", f, floatTestValue1); + test("testFloatCompareConstant1", f); + test("testFloatCompareConstant2", f); + } + + @Test + public void testFloatNullCompares() { + test("testFloatCompare", null, floatTestValue1); + } + + @Test + public void testFloatNullCompares1() { + test("testFloatCompareConstant1", (Object) null); + } + + @Test + public void testFloatNullCompares2() { + test("testFloatCompareConstant2", (Object) null); + } + + public static Object testFloatCompareLess(FieldObject f, float floatValue) { + if (f.floatValue < floatValue) { + return f; + } + return null; + } + + public static Object testFloatCompareLessConstant1(FieldObject f) { + if (f.floatValue < floatTestValue1) { + return f; + } + return null; + } + + public static Object testFloatCompareLessConstant2(FieldObject f) { + if (f.floatValue < floatTestValue2) { + return f; + } + return null; + } + + @Test + public void testFloatComparesLess() { + FieldObject f = new FieldObject(); + test("testFloatCompareLess", f, floatTestValue1); + test("testFloatCompareLessConstant1", f); + test("testFloatCompareLessConstant2", f); + } + + @Test + public void testFloatNullComparesLess() { + test("testFloatCompareLess", null, floatTestValue1); + } + + @Test + public void testFloatNullComparesLess1() { + test("testFloatCompareLessConstant1", (Object) null); + } + + @Test + public void testFloatNullComparesLess2() { + test("testFloatCompareLessConstant2", (Object) null); + } + + public static Object testFloatSwappedCompareLess(FieldObject f, float floatValue) { + if (floatValue < f.floatValue) { + return f; + } + return null; + } + + public static Object testFloatSwappedCompareLessConstant1(FieldObject f) { + if (floatTestValue1 < f.floatValue) { + return f; + } + return null; + } + + public static Object testFloatSwappedCompareLessConstant2(FieldObject f) { + if (floatTestValue2 < f.floatValue) { + return f; + } + return null; + } + + @Test + public void testFloatSwappedComparesLess() { + FieldObject f = new FieldObject(); + test("testFloatSwappedCompareLess", f, floatTestValue1); + test("testFloatSwappedCompareLessConstant1", f); + test("testFloatSwappedCompareLessConstant2", f); + } + + @Test + public void testFloatNullSwappedComparesLess() { + test("testFloatSwappedCompareLess", null, floatTestValue1); + } + + @Test + public void testFloatNullSwappedComparesLess1() { + test("testFloatSwappedCompareLessConstant1", (Object) null); + } + + @Test + public void testFloatNullSwappedComparesLess2() { + test("testFloatSwappedCompareLessConstant2", (Object) null); + } + + public static Object testFloatCompareLessEqual(FieldObject f, float floatValue) { + if (f.floatValue <= floatValue) { + return f; + } + return null; + } + + public static Object testFloatCompareLessEqualConstant1(FieldObject f) { + if (f.floatValue <= floatTestValue1) { + return f; + } + return null; + } + + public static Object testFloatCompareLessEqualConstant2(FieldObject f) { + if (f.floatValue <= floatTestValue2) { + return f; + } + return null; + } + + @Test + public void testFloatComparesLessEqual() { + FieldObject f = new FieldObject(); + test("testFloatCompareLessEqual", f, floatTestValue1); + test("testFloatCompareLessEqualConstant1", f); + test("testFloatCompareLessEqualConstant2", f); + } + + @Test + public void testFloatNullComparesLessEqual() { + test("testFloatCompareLessEqual", null, floatTestValue1); + } + + @Test + public void testFloatNullComparesLessEqual1() { + test("testFloatCompareLessEqualConstant1", (Object) null); + } + + @Test + public void testFloatNullComparesLessEqual2() { + test("testFloatCompareLessEqualConstant2", (Object) null); + } + + public static Object testFloatSwappedCompareLessEqual(FieldObject f, float floatValue) { + if (floatValue <= f.floatValue) { + return f; + } + return null; + } + + public static Object testFloatSwappedCompareLessEqualConstant1(FieldObject f) { + if (floatTestValue1 <= f.floatValue) { + return f; + } + return null; + } + + public static Object testFloatSwappedCompareLessEqualConstant2(FieldObject f) { + if (floatTestValue2 <= f.floatValue) { + return f; + } + return null; + } + + @Test + public void testFloatSwappedComparesLessEqual() { + FieldObject f = new FieldObject(); + test("testFloatSwappedCompareLessEqual", f, floatTestValue1); + test("testFloatSwappedCompareLessEqualConstant1", f); + test("testFloatSwappedCompareLessEqualConstant2", f); + } + + @Test + public void testFloatNullSwappedComparesLessEqual() { + test("testFloatSwappedCompareLessEqual", null, floatTestValue1); + } + + @Test + public void testFloatNullSwappedComparesLessEqual1() { + test("testFloatSwappedCompareLessEqualConstant1", (Object) null); + } + + @Test + public void testFloatNullSwappedComparesLessEqual2() { + test("testFloatSwappedCompareLessEqualConstant2", (Object) null); + } + + public static Object testFloatCompareGreater(FieldObject f, float floatValue) { + if (f.floatValue > floatValue) { + return f; + } + return null; + } + + public static Object testFloatCompareGreaterConstant1(FieldObject f) { + if (f.floatValue > floatTestValue1) { + return f; + } + return null; + } + + public static Object testFloatCompareGreaterConstant2(FieldObject f) { + if (f.floatValue > floatTestValue2) { + return f; + } + return null; + } + + @Test + public void testFloatComparesGreater() { + FieldObject f = new FieldObject(); + test("testFloatCompareGreater", f, floatTestValue1); + test("testFloatCompareGreaterConstant1", f); + test("testFloatCompareGreaterConstant2", f); + } + + @Test + public void testFloatNullComparesGreater() { + test("testFloatCompareGreater", null, floatTestValue1); + } + + @Test + public void testFloatNullComparesGreater1() { + test("testFloatCompareGreaterConstant1", (Object) null); + } + + @Test + public void testFloatNullComparesGreater2() { + test("testFloatCompareGreaterConstant2", (Object) null); + } + + public static Object testFloatSwappedCompareGreater(FieldObject f, float floatValue) { + if (floatValue > f.floatValue) { + return f; + } + return null; + } + + public static Object testFloatSwappedCompareGreaterConstant1(FieldObject f) { + if (floatTestValue1 > f.floatValue) { + return f; + } + return null; + } + + public static Object testFloatSwappedCompareGreaterConstant2(FieldObject f) { + if (floatTestValue2 > f.floatValue) { + return f; + } + return null; + } + + @Test + public void testFloatSwappedComparesGreater() { + FieldObject f = new FieldObject(); + test("testFloatSwappedCompareGreater", f, floatTestValue1); + test("testFloatSwappedCompareGreaterConstant1", f); + test("testFloatSwappedCompareGreaterConstant2", f); + } + + @Test + public void testFloatNullSwappedComparesGreater() { + test("testFloatSwappedCompareGreater", null, floatTestValue1); + } + + @Test + public void testFloatNullSwappedComparesGreater1() { + test("testFloatSwappedCompareGreaterConstant1", (Object) null); + } + + @Test + public void testFloatNullSwappedComparesGreater2() { + test("testFloatSwappedCompareGreaterConstant2", (Object) null); + } + + public static Object testFloatCompareGreaterEqual(FieldObject f, float floatValue) { + if (f.floatValue >= floatValue) { + return f; + } + return null; + } + + public static Object testFloatCompareGreaterEqualConstant1(FieldObject f) { + if (f.floatValue >= floatTestValue1) { + return f; + } + return null; + } + + public static Object testFloatCompareGreaterEqualConstant2(FieldObject f) { + if (f.floatValue >= floatTestValue2) { + return f; + } + return null; + } + + @Test + public void testFloatComparesGreaterEqual() { + FieldObject f = new FieldObject(); + test("testFloatCompareGreaterEqual", f, floatTestValue1); + test("testFloatCompareGreaterEqualConstant1", f); + test("testFloatCompareGreaterEqualConstant2", f); + } + + @Test + public void testFloatNullComparesGreaterEqual() { + test("testFloatCompareGreaterEqual", null, floatTestValue1); + } + + @Test + public void testFloatNullComparesGreaterEqual1() { + test("testFloatCompareGreaterEqualConstant1", (Object) null); + } + + @Test + public void testFloatNullComparesGreaterEqual2() { + test("testFloatCompareGreaterEqualConstant2", (Object) null); + } + + public static Object testFloatSwappedCompareGreaterEqual(FieldObject f, float floatValue) { + if (floatValue >= f.floatValue) { + return f; + } + return null; + } + + public static Object testFloatSwappedCompareGreaterEqualConstant1(FieldObject f) { + if (floatTestValue1 >= f.floatValue) { + return f; + } + return null; + } + + public static Object testFloatSwappedCompareGreaterEqualConstant2(FieldObject f) { + if (floatTestValue2 >= f.floatValue) { + return f; + } + return null; + } + + @Test + public void testFloatSwappedComparesGreaterEqual() { + FieldObject f = new FieldObject(); + test("testFloatSwappedCompareGreaterEqual", f, floatTestValue1); + test("testFloatSwappedCompareGreaterEqualConstant1", f); + test("testFloatSwappedCompareGreaterEqualConstant2", f); + } + + @Test + public void testFloatNullSwappedComparesGreaterEqual() { + test("testFloatSwappedCompareGreaterEqual", null, floatTestValue1); + } + + @Test + public void testFloatNullSwappedComparesGreaterEqual1() { + test("testFloatSwappedCompareGreaterEqualConstant1", (Object) null); + } + + @Test + public void testFloatNullSwappedComparesGreaterEqual2() { + test("testFloatSwappedCompareGreaterEqualConstant2", (Object) null); + } + + public static Object testLongCompare(FieldObject f, long longValue) { + if (f.longValue == longValue) { + return f; + } + return null; + } + + public static Object testLongCompareConstant1(FieldObject f) { + if (f.longValue == longTestValue1) { + return f; + } + return null; + } + + public static Object testLongCompareConstant2(FieldObject f) { + if (f.longValue == longTestValue2) { + return f; + } + return null; + } + + @Test + public void testLongCompares() { + FieldObject f = new FieldObject(); + test("testLongCompare", f, longTestValue1); + test("testLongCompareConstant1", f); + test("testLongCompareConstant2", f); + } + + @Test + public void testLongNullCompares() { + test("testLongCompare", null, longTestValue1); + } + + @Test + public void testLongNullCompares1() { + test("testLongCompareConstant1", (Object) null); + } + + @Test + public void testLongNullCompares2() { + test("testLongCompareConstant2", (Object) null); + } + + public static Object testLongCompareLess(FieldObject f, long longValue) { + if (f.longValue < longValue) { + return f; + } + return null; + } + + public static Object testLongCompareLessConstant1(FieldObject f) { + if (f.longValue < longTestValue1) { + return f; + } + return null; + } + + public static Object testLongCompareLessConstant2(FieldObject f) { + if (f.longValue < longTestValue2) { + return f; + } + return null; + } + + @Test + public void testLongComparesLess() { + FieldObject f = new FieldObject(); + test("testLongCompareLess", f, longTestValue1); + test("testLongCompareLessConstant1", f); + test("testLongCompareLessConstant2", f); + } + + @Test + public void testLongNullComparesLess() { + test("testLongCompareLess", null, longTestValue1); + } + + @Test + public void testLongNullComparesLess1() { + test("testLongCompareLessConstant1", (Object) null); + } + + @Test + public void testLongNullComparesLess2() { + test("testLongCompareLessConstant2", (Object) null); + } + + public static Object testLongSwappedCompareLess(FieldObject f, long longValue) { + if (longValue < f.longValue) { + return f; + } + return null; + } + + public static Object testLongSwappedCompareLessConstant1(FieldObject f) { + if (longTestValue1 < f.longValue) { + return f; + } + return null; + } + + public static Object testLongSwappedCompareLessConstant2(FieldObject f) { + if (longTestValue2 < f.longValue) { + return f; + } + return null; + } + + @Test + public void testLongSwappedComparesLess() { + FieldObject f = new FieldObject(); + test("testLongSwappedCompareLess", f, longTestValue1); + test("testLongSwappedCompareLessConstant1", f); + test("testLongSwappedCompareLessConstant2", f); + } + + @Test + public void testLongNullSwappedComparesLess() { + test("testLongSwappedCompareLess", null, longTestValue1); + } + + @Test + public void testLongNullSwappedComparesLess1() { + test("testLongSwappedCompareLessConstant1", (Object) null); + } + + @Test + public void testLongNullSwappedComparesLess2() { + test("testLongSwappedCompareLessConstant2", (Object) null); + } + + public static Object testLongCompareLessEqual(FieldObject f, long longValue) { + if (f.longValue <= longValue) { + return f; + } + return null; + } + + public static Object testLongCompareLessEqualConstant1(FieldObject f) { + if (f.longValue <= longTestValue1) { + return f; + } + return null; + } + + public static Object testLongCompareLessEqualConstant2(FieldObject f) { + if (f.longValue <= longTestValue2) { + return f; + } + return null; + } + + @Test + public void testLongComparesLessEqual() { + FieldObject f = new FieldObject(); + test("testLongCompareLessEqual", f, longTestValue1); + test("testLongCompareLessEqualConstant1", f); + test("testLongCompareLessEqualConstant2", f); + } + + @Test + public void testLongNullComparesLessEqual() { + test("testLongCompareLessEqual", null, longTestValue1); + } + + @Test + public void testLongNullComparesLessEqual1() { + test("testLongCompareLessEqualConstant1", (Object) null); + } + + @Test + public void testLongNullComparesLessEqual2() { + test("testLongCompareLessEqualConstant2", (Object) null); + } + + public static Object testLongSwappedCompareLessEqual(FieldObject f, long longValue) { + if (longValue <= f.longValue) { + return f; + } + return null; + } + + public static Object testLongSwappedCompareLessEqualConstant1(FieldObject f) { + if (longTestValue1 <= f.longValue) { + return f; + } + return null; + } + + public static Object testLongSwappedCompareLessEqualConstant2(FieldObject f) { + if (longTestValue2 <= f.longValue) { + return f; + } + return null; + } + + @Test + public void testLongSwappedComparesLessEqual() { + FieldObject f = new FieldObject(); + test("testLongSwappedCompareLessEqual", f, longTestValue1); + test("testLongSwappedCompareLessEqualConstant1", f); + test("testLongSwappedCompareLessEqualConstant2", f); + } + + @Test + public void testLongNullSwappedComparesLessEqual() { + test("testLongSwappedCompareLessEqual", null, longTestValue1); + } + + @Test + public void testLongNullSwappedComparesLessEqual1() { + test("testLongSwappedCompareLessEqualConstant1", (Object) null); + } + + @Test + public void testLongNullSwappedComparesLessEqual2() { + test("testLongSwappedCompareLessEqualConstant2", (Object) null); + } + + public static Object testLongCompareGreater(FieldObject f, long longValue) { + if (f.longValue > longValue) { + return f; + } + return null; + } + + public static Object testLongCompareGreaterConstant1(FieldObject f) { + if (f.longValue > longTestValue1) { + return f; + } + return null; + } + + public static Object testLongCompareGreaterConstant2(FieldObject f) { + if (f.longValue > longTestValue2) { + return f; + } + return null; + } + + @Test + public void testLongComparesGreater() { + FieldObject f = new FieldObject(); + test("testLongCompareGreater", f, longTestValue1); + test("testLongCompareGreaterConstant1", f); + test("testLongCompareGreaterConstant2", f); + } + + @Test + public void testLongNullComparesGreater() { + test("testLongCompareGreater", null, longTestValue1); + } + + @Test + public void testLongNullComparesGreater1() { + test("testLongCompareGreaterConstant1", (Object) null); + } + + @Test + public void testLongNullComparesGreater2() { + test("testLongCompareGreaterConstant2", (Object) null); + } + + public static Object testLongSwappedCompareGreater(FieldObject f, long longValue) { + if (longValue > f.longValue) { + return f; + } + return null; + } + + public static Object testLongSwappedCompareGreaterConstant1(FieldObject f) { + if (longTestValue1 > f.longValue) { + return f; + } + return null; + } + + public static Object testLongSwappedCompareGreaterConstant2(FieldObject f) { + if (longTestValue2 > f.longValue) { + return f; + } + return null; + } + + @Test + public void testLongSwappedComparesGreater() { + FieldObject f = new FieldObject(); + test("testLongSwappedCompareGreater", f, longTestValue1); + test("testLongSwappedCompareGreaterConstant1", f); + test("testLongSwappedCompareGreaterConstant2", f); + } + + @Test + public void testLongNullSwappedComparesGreater() { + test("testLongSwappedCompareGreater", null, longTestValue1); + } + + @Test + public void testLongNullSwappedComparesGreater1() { + test("testLongSwappedCompareGreaterConstant1", (Object) null); + } + + @Test + public void testLongNullSwappedComparesGreater2() { + test("testLongSwappedCompareGreaterConstant2", (Object) null); + } + + public static Object testLongCompareGreaterEqual(FieldObject f, long longValue) { + if (f.longValue >= longValue) { + return f; + } + return null; + } + + public static Object testLongCompareGreaterEqualConstant1(FieldObject f) { + if (f.longValue >= longTestValue1) { + return f; + } + return null; + } + + public static Object testLongCompareGreaterEqualConstant2(FieldObject f) { + if (f.longValue >= longTestValue2) { + return f; + } + return null; + } + + @Test + public void testLongComparesGreaterEqual() { + FieldObject f = new FieldObject(); + test("testLongCompareGreaterEqual", f, longTestValue1); + test("testLongCompareGreaterEqualConstant1", f); + test("testLongCompareGreaterEqualConstant2", f); + } + + @Test + public void testLongNullComparesGreaterEqual() { + test("testLongCompareGreaterEqual", null, longTestValue1); + } + + @Test + public void testLongNullComparesGreaterEqual1() { + test("testLongCompareGreaterEqualConstant1", (Object) null); + } + + @Test + public void testLongNullComparesGreaterEqual2() { + test("testLongCompareGreaterEqualConstant2", (Object) null); + } + + public static Object testLongSwappedCompareGreaterEqual(FieldObject f, long longValue) { + if (longValue >= f.longValue) { + return f; + } + return null; + } + + public static Object testLongSwappedCompareGreaterEqualConstant1(FieldObject f) { + if (longTestValue1 >= f.longValue) { + return f; + } + return null; + } + + public static Object testLongSwappedCompareGreaterEqualConstant2(FieldObject f) { + if (longTestValue2 >= f.longValue) { + return f; + } + return null; + } + + @Test + public void testLongSwappedComparesGreaterEqual() { + FieldObject f = new FieldObject(); + test("testLongSwappedCompareGreaterEqual", f, longTestValue1); + test("testLongSwappedCompareGreaterEqualConstant1", f); + test("testLongSwappedCompareGreaterEqualConstant2", f); + } + + @Test + public void testLongNullSwappedComparesGreaterEqual() { + test("testLongSwappedCompareGreaterEqual", null, longTestValue1); + } + + @Test + public void testLongNullSwappedComparesGreaterEqual1() { + test("testLongSwappedCompareGreaterEqualConstant1", (Object) null); + } + + @Test + public void testLongNullSwappedComparesGreaterEqual2() { + test("testLongSwappedCompareGreaterEqualConstant2", (Object) null); + } + + public static Object testDoubleCompare(FieldObject f, double doubleValue) { + if (f.doubleValue == doubleValue) { + return f; + } + return null; + } + + public static Object testDoubleCompareConstant1(FieldObject f) { + if (f.doubleValue == doubleTestValue1) { + return f; + } + return null; + } + + public static Object testDoubleCompareConstant2(FieldObject f) { + if (f.doubleValue == doubleTestValue2) { + return f; + } + return null; + } + + @Test + public void testDoubleCompares() { + FieldObject f = new FieldObject(); + test("testDoubleCompare", f, doubleTestValue1); + test("testDoubleCompareConstant1", f); + test("testDoubleCompareConstant2", f); + } + + @Test + public void testDoubleNullCompares() { + test("testDoubleCompare", null, doubleTestValue1); + } + + @Test + public void testDoubleNullCompares1() { + test("testDoubleCompareConstant1", (Object) null); + } + + @Test + public void testDoubleNullCompares2() { + test("testDoubleCompareConstant2", (Object) null); + } + + public static Object testDoubleCompareLess(FieldObject f, double doubleValue) { + if (f.doubleValue < doubleValue) { + return f; + } + return null; + } + + public static Object testDoubleCompareLessConstant1(FieldObject f) { + if (f.doubleValue < doubleTestValue1) { + return f; + } + return null; + } + + public static Object testDoubleCompareLessConstant2(FieldObject f) { + if (f.doubleValue < doubleTestValue2) { + return f; + } + return null; + } + + @Test + public void testDoubleComparesLess() { + FieldObject f = new FieldObject(); + test("testDoubleCompareLess", f, doubleTestValue1); + test("testDoubleCompareLessConstant1", f); + test("testDoubleCompareLessConstant2", f); + } + + @Test + public void testDoubleNullComparesLess() { + test("testDoubleCompareLess", null, doubleTestValue1); + } + + @Test + public void testDoubleNullComparesLess1() { + test("testDoubleCompareLessConstant1", (Object) null); + } + + @Test + public void testDoubleNullComparesLess2() { + test("testDoubleCompareLessConstant2", (Object) null); + } + + public static Object testDoubleSwappedCompareLess(FieldObject f, double doubleValue) { + if (doubleValue < f.doubleValue) { + return f; + } + return null; + } + + public static Object testDoubleSwappedCompareLessConstant1(FieldObject f) { + if (doubleTestValue1 < f.doubleValue) { + return f; + } + return null; + } + + public static Object testDoubleSwappedCompareLessConstant2(FieldObject f) { + if (doubleTestValue2 < f.doubleValue) { + return f; + } + return null; + } + + @Test + public void testDoubleSwappedComparesLess() { + FieldObject f = new FieldObject(); + test("testDoubleSwappedCompareLess", f, doubleTestValue1); + test("testDoubleSwappedCompareLessConstant1", f); + test("testDoubleSwappedCompareLessConstant2", f); + } + + @Test + public void testDoubleNullSwappedComparesLess() { + test("testDoubleSwappedCompareLess", null, doubleTestValue1); + } + + @Test + public void testDoubleNullSwappedComparesLess1() { + test("testDoubleSwappedCompareLessConstant1", (Object) null); + } + + @Test + public void testDoubleNullSwappedComparesLess2() { + test("testDoubleSwappedCompareLessConstant2", (Object) null); + } + + public static Object testDoubleCompareLessEqual(FieldObject f, double doubleValue) { + if (f.doubleValue <= doubleValue) { + return f; + } + return null; + } + + public static Object testDoubleCompareLessEqualConstant1(FieldObject f) { + if (f.doubleValue <= doubleTestValue1) { + return f; + } + return null; + } + + public static Object testDoubleCompareLessEqualConstant2(FieldObject f) { + if (f.doubleValue <= doubleTestValue2) { + return f; + } + return null; + } + + @Test + public void testDoubleComparesLessEqual() { + FieldObject f = new FieldObject(); + test("testDoubleCompareLessEqual", f, doubleTestValue1); + test("testDoubleCompareLessEqualConstant1", f); + test("testDoubleCompareLessEqualConstant2", f); + } + + @Test + public void testDoubleNullComparesLessEqual() { + test("testDoubleCompareLessEqual", null, doubleTestValue1); + } + + @Test + public void testDoubleNullComparesLessEqual1() { + test("testDoubleCompareLessEqualConstant1", (Object) null); + } + + @Test + public void testDoubleNullComparesLessEqual2() { + test("testDoubleCompareLessEqualConstant2", (Object) null); + } + + public static Object testDoubleSwappedCompareLessEqual(FieldObject f, double doubleValue) { + if (doubleValue <= f.doubleValue) { + return f; + } + return null; + } + + public static Object testDoubleSwappedCompareLessEqualConstant1(FieldObject f) { + if (doubleTestValue1 <= f.doubleValue) { + return f; + } + return null; + } + + public static Object testDoubleSwappedCompareLessEqualConstant2(FieldObject f) { + if (doubleTestValue2 <= f.doubleValue) { + return f; + } + return null; + } + + @Test + public void testDoubleSwappedComparesLessEqual() { + FieldObject f = new FieldObject(); + test("testDoubleSwappedCompareLessEqual", f, doubleTestValue1); + test("testDoubleSwappedCompareLessEqualConstant1", f); + test("testDoubleSwappedCompareLessEqualConstant2", f); + } + + @Test + public void testDoubleNullSwappedComparesLessEqual() { + test("testDoubleSwappedCompareLessEqual", null, doubleTestValue1); + } + + @Test + public void testDoubleNullSwappedComparesLessEqual1() { + test("testDoubleSwappedCompareLessEqualConstant1", (Object) null); + } + + @Test + public void testDoubleNullSwappedComparesLessEqual2() { + test("testDoubleSwappedCompareLessEqualConstant2", (Object) null); + } + + public static Object testDoubleCompareGreater(FieldObject f, double doubleValue) { + if (f.doubleValue > doubleValue) { + return f; + } + return null; + } + + public static Object testDoubleCompareGreaterConstant1(FieldObject f) { + if (f.doubleValue > doubleTestValue1) { + return f; + } + return null; + } + + public static Object testDoubleCompareGreaterConstant2(FieldObject f) { + if (f.doubleValue > doubleTestValue2) { + return f; + } + return null; + } + + @Test + public void testDoubleComparesGreater() { + FieldObject f = new FieldObject(); + test("testDoubleCompareGreater", f, doubleTestValue1); + test("testDoubleCompareGreaterConstant1", f); + test("testDoubleCompareGreaterConstant2", f); + } + + @Test + public void testDoubleNullComparesGreater() { + test("testDoubleCompareGreater", null, doubleTestValue1); + } + + @Test + public void testDoubleNullComparesGreater1() { + test("testDoubleCompareGreaterConstant1", (Object) null); + } + + @Test + public void testDoubleNullComparesGreater2() { + test("testDoubleCompareGreaterConstant2", (Object) null); + } + + public static Object testDoubleSwappedCompareGreater(FieldObject f, double doubleValue) { + if (doubleValue > f.doubleValue) { + return f; + } + return null; + } + + public static Object testDoubleSwappedCompareGreaterConstant1(FieldObject f) { + if (doubleTestValue1 > f.doubleValue) { + return f; + } + return null; + } + + public static Object testDoubleSwappedCompareGreaterConstant2(FieldObject f) { + if (doubleTestValue2 > f.doubleValue) { + return f; + } + return null; + } + + @Test + public void testDoubleSwappedComparesGreater() { + FieldObject f = new FieldObject(); + test("testDoubleSwappedCompareGreater", f, doubleTestValue1); + test("testDoubleSwappedCompareGreaterConstant1", f); + test("testDoubleSwappedCompareGreaterConstant2", f); + } + + @Test + public void testDoubleNullSwappedComparesGreater() { + test("testDoubleSwappedCompareGreater", null, doubleTestValue1); + } + + @Test + public void testDoubleNullSwappedComparesGreater1() { + test("testDoubleSwappedCompareGreaterConstant1", (Object) null); + } + + @Test + public void testDoubleNullSwappedComparesGreater2() { + test("testDoubleSwappedCompareGreaterConstant2", (Object) null); + } + + public static Object testDoubleCompareGreaterEqual(FieldObject f, double doubleValue) { + if (f.doubleValue >= doubleValue) { + return f; + } + return null; + } + + public static Object testDoubleCompareGreaterEqualConstant1(FieldObject f) { + if (f.doubleValue >= doubleTestValue1) { + return f; + } + return null; + } + + public static Object testDoubleCompareGreaterEqualConstant2(FieldObject f) { + if (f.doubleValue >= doubleTestValue2) { + return f; + } + return null; + } + + @Test + public void testDoubleComparesGreaterEqual() { + FieldObject f = new FieldObject(); + test("testDoubleCompareGreaterEqual", f, doubleTestValue1); + test("testDoubleCompareGreaterEqualConstant1", f); + test("testDoubleCompareGreaterEqualConstant2", f); + } + + @Test + public void testDoubleNullComparesGreaterEqual() { + test("testDoubleCompareGreaterEqual", null, doubleTestValue1); + } + + @Test + public void testDoubleNullComparesGreaterEqual1() { + test("testDoubleCompareGreaterEqualConstant1", (Object) null); + } + + @Test + public void testDoubleNullComparesGreaterEqual2() { + test("testDoubleCompareGreaterEqualConstant2", (Object) null); + } + + public static Object testDoubleSwappedCompareGreaterEqual(FieldObject f, double doubleValue) { + if (doubleValue >= f.doubleValue) { + return f; + } + return null; + } + + public static Object testDoubleSwappedCompareGreaterEqualConstant1(FieldObject f) { + if (doubleTestValue1 >= f.doubleValue) { + return f; + } + return null; + } + + public static Object testDoubleSwappedCompareGreaterEqualConstant2(FieldObject f) { + if (doubleTestValue2 >= f.doubleValue) { + return f; + } + return null; + } + + @Test + public void testDoubleSwappedComparesGreaterEqual() { + FieldObject f = new FieldObject(); + test("testDoubleSwappedCompareGreaterEqual", f, doubleTestValue1); + test("testDoubleSwappedCompareGreaterEqualConstant1", f); + test("testDoubleSwappedCompareGreaterEqualConstant2", f); + } + + @Test + public void testDoubleNullSwappedComparesGreaterEqual() { + test("testDoubleSwappedCompareGreaterEqual", null, doubleTestValue1); + } + + @Test + public void testDoubleNullSwappedComparesGreaterEqual1() { + test("testDoubleSwappedCompareGreaterEqualConstant1", (Object) null); + } + + @Test + public void testDoubleNullSwappedComparesGreaterEqual2() { + test("testDoubleSwappedCompareGreaterEqualConstant2", (Object) null); + } + + public static Object testObjectCompare(FieldObject f, Object objectValue) { + if (f.objectValue == objectValue) { + return f; + } + return null; + } + + public static Object testObjectCompareConstant1(FieldObject f) { + if (f.objectValue == objectTestValue1) { + return f; + } + return null; + } + + public static Object testObjectCompareConstant2(FieldObject f) { + if (f.objectValue == objectTestValue2) { + return f; + } + return null; + } + + @Test + public void testObjectCompares() { + FieldObject f = new FieldObject(); + test("testObjectCompare", f, objectTestValue1); + test("testObjectCompareConstant1", f); + test("testObjectCompareConstant2", f); + } + + @Test + public void testObjectNullCompares() { + test("testObjectCompare", null, objectTestValue1); + } + + @Test + public void testObjectNullCompares1() { + test("testObjectCompareConstant1", (Object) null); + } + + @Test + public void testObjectNullCompares2() { + test("testObjectCompareConstant2", (Object) null); + } + + public static int testByteAdd(FieldObject f, byte byteValue) { + return f.byteValue + byteValue; + } + + public static int testByteAddConstant1(FieldObject f) { + return f.byteValue + byteTestValue1; + } + + public static int testByteAddConstant2(FieldObject f) { + return f.byteValue + byteTestValue2; + } + + @Test + public void testByteAdds() { + FieldObject f = new FieldObject(); + test("testByteAdd", f, byteTestValue1); + test("testByteAddConstant1", f); + test("testByteAddConstant2", f); + } + + @Test + public void testByteNullAdd() { + test("testByteAdd", null, byteTestValue1); + } + + public static int testShortAdd(FieldObject f, short shortValue) { + return f.shortValue + shortValue; + } + + public static int testShortAddConstant1(FieldObject f) { + return f.shortValue + shortTestValue1; + } + + public static int testShortAddConstant2(FieldObject f) { + return f.shortValue + shortTestValue2; + } + + @Test + public void testShortAdds() { + FieldObject f = new FieldObject(); + test("testShortAdd", f, shortTestValue1); + test("testShortAddConstant1", f); + test("testShortAddConstant2", f); + } + + @Test + public void testShortNullAdd() { + test("testShortAdd", null, shortTestValue1); + } + + public static int testCharAdd(FieldObject f, char charValue) { + return f.charValue + charValue; + } + + public static int testCharAddConstant1(FieldObject f) { + return f.charValue + charTestValue1; + } + + public static int testCharAddConstant2(FieldObject f) { + return f.charValue + charTestValue2; + } + + @Test + public void testCharAdds() { + FieldObject f = new FieldObject(); + test("testCharAdd", f, charTestValue1); + test("testCharAddConstant1", f); + test("testCharAddConstant2", f); + } + + @Test + public void testCharNullAdd() { + test("testCharAdd", null, charTestValue1); + } + + public static int testIntAdd(FieldObject f, int intValue) { + return f.intValue + intValue; + } + + public static int testIntAddConstant1(FieldObject f) { + return f.intValue + intTestValue1; + } + + public static int testIntAddConstant2(FieldObject f) { + return f.intValue + intTestValue2; + } + + @Test + public void testIntAdds() { + FieldObject f = new FieldObject(); + test("testIntAdd", f, intTestValue1); + test("testIntAddConstant1", f); + test("testIntAddConstant2", f); + } + + @Test + public void testIntNullAdd() { + test("testIntAdd", null, intTestValue1); + } + + public static long testLongAdd(FieldObject f, long longValue) { + return f.longValue + longValue; + } + + public static long testLongAddConstant1(FieldObject f) { + return f.longValue + longTestValue1; + } + + public static long testLongAddConstant2(FieldObject f) { + return f.longValue + longTestValue2; + } + + @Test + public void testLongAdds() { + FieldObject f = new FieldObject(); + test("testLongAdd", f, longTestValue1); + test("testLongAddConstant1", f); + test("testLongAddConstant2", f); + } + + @Test + public void testLongNullAdd() { + test("testLongAdd", null, longTestValue1); + } + + public static float testFloatAdd(FieldObject f, float floatValue) { + return f.floatValue + floatValue; + } + + public static float testFloatAddConstant1(FieldObject f) { + return f.floatValue + floatTestValue1; + } + + public static float testFloatAddConstant2(FieldObject f) { + return f.floatValue + floatTestValue2; + } + + @Test + public void testFloatAdds() { + FieldObject f = new FieldObject(); + test("testFloatAdd", f, floatTestValue1); + test("testFloatAddConstant1", f); + test("testFloatAddConstant2", f); + } + + @Test + public void testFloatNullAdd() { + test("testFloatAdd", null, floatTestValue1); + } + + public static double testDoubleAdd(FieldObject f, double doubleValue) { + return f.doubleValue + doubleValue; + } + + public static double testDoubleAddConstant1(FieldObject f) { + return f.doubleValue + doubleTestValue1; + } + + public static double testDoubleAddConstant2(FieldObject f) { + return f.doubleValue + doubleTestValue2; + } + + @Test + public void testDoubleAdds() { + FieldObject f = new FieldObject(); + test("testDoubleAdd", f, doubleTestValue1); + test("testDoubleAddConstant1", f); + test("testDoubleAddConstant2", f); + } + + @Test + public void testDoubleNullAdd() { + test("testDoubleAdd", null, doubleTestValue1); + } + + public static int testByteSub(FieldObject f, byte byteValue) { + return f.byteValue - byteValue; + } + + public static int testByteSubConstant1(FieldObject f) { + return f.byteValue - byteTestValue1; + } + + public static int testByteSubConstant2(FieldObject f) { + return f.byteValue - byteTestValue2; + } + + @Test + public void testByteSubs() { + FieldObject f = new FieldObject(); + test("testByteSub", f, byteTestValue1); + test("testByteSubConstant1", f); + test("testByteSubConstant2", f); + } + + @Test + public void testByteNullSub() { + test("testByteSub", null, byteTestValue1); + } + + public static int testShortSub(FieldObject f, short shortValue) { + return f.shortValue - shortValue; + } + + public static int testShortSubConstant1(FieldObject f) { + return f.shortValue - shortTestValue1; + } + + public static int testShortSubConstant2(FieldObject f) { + return f.shortValue - shortTestValue2; + } + + @Test + public void testShortSubs() { + FieldObject f = new FieldObject(); + test("testShortSub", f, shortTestValue1); + test("testShortSubConstant1", f); + test("testShortSubConstant2", f); + } + + @Test + public void testShortNullSub() { + test("testShortSub", null, shortTestValue1); + } + + public static int testCharSub(FieldObject f, char charValue) { + return f.charValue - charValue; + } + + public static int testCharSubConstant1(FieldObject f) { + return f.charValue - charTestValue1; + } + + public static int testCharSubConstant2(FieldObject f) { + return f.charValue - charTestValue2; + } + + @Test + public void testCharSubs() { + FieldObject f = new FieldObject(); + test("testCharSub", f, charTestValue1); + test("testCharSubConstant1", f); + test("testCharSubConstant2", f); + } + + @Test + public void testCharNullSub() { + test("testCharSub", null, charTestValue1); + } + + public static int testIntSub(FieldObject f, int intValue) { + return f.intValue - intValue; + } + + public static int testIntSubConstant1(FieldObject f) { + return f.intValue - intTestValue1; + } + + public static int testIntSubConstant2(FieldObject f) { + return f.intValue - intTestValue2; + } + + @Test + public void testIntSubs() { + FieldObject f = new FieldObject(); + test("testIntSub", f, intTestValue1); + test("testIntSubConstant1", f); + test("testIntSubConstant2", f); + } + + @Test + public void testIntNullSub() { + test("testIntSub", null, intTestValue1); + } + + public static long testLongSub(FieldObject f, long longValue) { + return f.longValue - longValue; + } + + public static long testLongSubConstant1(FieldObject f) { + return f.longValue - longTestValue1; + } + + public static long testLongSubConstant2(FieldObject f) { + return f.longValue - longTestValue2; + } + + @Test + public void testLongSubs() { + FieldObject f = new FieldObject(); + test("testLongSub", f, longTestValue1); + test("testLongSubConstant1", f); + test("testLongSubConstant2", f); + } + + @Test + public void testLongNullSub() { + test("testLongSub", null, longTestValue1); + } + + public static float testFloatSub(FieldObject f, float floatValue) { + return f.floatValue - floatValue; + } + + public static float testFloatSubConstant1(FieldObject f) { + return f.floatValue - floatTestValue1; + } + + public static float testFloatSubConstant2(FieldObject f) { + return f.floatValue - floatTestValue2; + } + + @Test + public void testFloatSubs() { + FieldObject f = new FieldObject(); + test("testFloatSub", f, floatTestValue1); + test("testFloatSubConstant1", f); + test("testFloatSubConstant2", f); + } + + @Test + public void testFloatNullSub() { + test("testFloatSub", null, floatTestValue1); + } + + public static double testDoubleSub(FieldObject f, double doubleValue) { + return f.doubleValue - doubleValue; + } + + public static double testDoubleSubConstant1(FieldObject f) { + return f.doubleValue - doubleTestValue1; + } + + public static double testDoubleSubConstant2(FieldObject f) { + return f.doubleValue - doubleTestValue2; + } + + @Test + public void testDoubleSubs() { + FieldObject f = new FieldObject(); + test("testDoubleSub", f, doubleTestValue1); + test("testDoubleSubConstant1", f); + test("testDoubleSubConstant2", f); + } + + @Test + public void testDoubleNullSub() { + test("testDoubleSub", null, doubleTestValue1); + } + + public static int testByteMul(FieldObject f, byte byteValue) { + return f.byteValue * byteValue; + } + + public static int testByteMulConstant1(FieldObject f) { + return f.byteValue * byteTestValue1; + } + + public static int testByteMulConstant2(FieldObject f) { + return f.byteValue * byteTestValue2; + } + + @Test + public void testByteMuls() { + FieldObject f = new FieldObject(); + test("testByteMul", f, byteTestValue1); + test("testByteMulConstant1", f); + test("testByteMulConstant2", f); + } + + @Test + public void testByteNullMul() { + test("testByteMul", null, byteTestValue1); + } + + public static int testShortMul(FieldObject f, short shortValue) { + return f.shortValue * shortValue; + } + + public static int testShortMulConstant1(FieldObject f) { + return f.shortValue * shortTestValue1; + } + + public static int testShortMulConstant2(FieldObject f) { + return f.shortValue * shortTestValue2; + } + + @Test + public void testShortMuls() { + FieldObject f = new FieldObject(); + test("testShortMul", f, shortTestValue1); + test("testShortMulConstant1", f); + test("testShortMulConstant2", f); + } + + @Test + public void testShortNullMul() { + test("testShortMul", null, shortTestValue1); + } + + public static int testCharMul(FieldObject f, char charValue) { + return f.charValue * charValue; + } + + public static int testCharMulConstant1(FieldObject f) { + return f.charValue * charTestValue1; + } + + public static int testCharMulConstant2(FieldObject f) { + return f.charValue * charTestValue2; + } + + @Test + public void testCharMuls() { + FieldObject f = new FieldObject(); + test("testCharMul", f, charTestValue1); + test("testCharMulConstant1", f); + test("testCharMulConstant2", f); + } + + @Test + public void testCharNullMul() { + test("testCharMul", null, charTestValue1); + } + + public static int testIntMul(FieldObject f, int intValue) { + return f.intValue * intValue; + } + + public static int testIntMulConstant1(FieldObject f) { + return f.intValue * intTestValue1; + } + + public static int testIntMulConstant2(FieldObject f) { + return f.intValue * intTestValue2; + } + + @Test + public void testIntMuls() { + FieldObject f = new FieldObject(); + test("testIntMul", f, intTestValue1); + test("testIntMulConstant1", f); + test("testIntMulConstant2", f); + } + + @Test + public void testIntNullMul() { + test("testIntMul", null, intTestValue1); + } + + public static long testLongMul(FieldObject f, long longValue) { + return f.longValue * longValue; + } + + public static long testLongMulConstant1(FieldObject f) { + return f.longValue * longTestValue1; + } + + public static long testLongMulConstant2(FieldObject f) { + return f.longValue * longTestValue2; + } + + @Test + public void testLongMuls() { + FieldObject f = new FieldObject(); + test("testLongMul", f, longTestValue1); + test("testLongMulConstant1", f); + test("testLongMulConstant2", f); + } + + @Test + public void testLongNullMul() { + test("testLongMul", null, longTestValue1); + } + + public static float testFloatMul(FieldObject f, float floatValue) { + return f.floatValue * floatValue; + } + + public static float testFloatMulConstant1(FieldObject f) { + return f.floatValue * floatTestValue1; + } + + public static float testFloatMulConstant2(FieldObject f) { + return f.floatValue * floatTestValue2; + } + + @Test + public void testFloatMuls() { + FieldObject f = new FieldObject(); + test("testFloatMul", f, floatTestValue1); + test("testFloatMulConstant1", f); + test("testFloatMulConstant2", f); + } + + @Test + public void testFloatNullMul() { + test("testFloatMul", null, floatTestValue1); + } + + public static double testDoubleMul(FieldObject f, double doubleValue) { + return f.doubleValue * doubleValue; + } + + public static double testDoubleMulConstant1(FieldObject f) { + return f.doubleValue * doubleTestValue1; + } + + public static double testDoubleMulConstant2(FieldObject f) { + return f.doubleValue * doubleTestValue2; + } + + @Test + public void testDoubleMuls() { + FieldObject f = new FieldObject(); + test("testDoubleMul", f, doubleTestValue1); + test("testDoubleMulConstant1", f); + test("testDoubleMulConstant2", f); + } + + @Test + public void testDoubleNullMul() { + test("testDoubleMul", null, doubleTestValue1); + } + + public static int testByteDiv(FieldObject f, byte byteValue) { + return f.byteValue / byteValue; + } + + public static int testByteDivConstant1(FieldObject f) { + return f.byteValue / byteTestValue1; + } + + public static int testByteDivConstant2(FieldObject f) { + return f.byteValue / byteTestValue2; + } + + @Test + public void testByteDivs() { + FieldObject f = new FieldObject(); + test("testByteDiv", f, byteTestValue1); + test("testByteDivConstant1", f); + test("testByteDivConstant2", f); + } + + @Test + public void testByteNullDiv() { + test("testByteDiv", null, byteTestValue1); + } + + public static int testShortDiv(FieldObject f, short shortValue) { + return f.shortValue / shortValue; + } + + public static int testShortDivConstant1(FieldObject f) { + return f.shortValue / shortTestValue1; + } + + public static int testShortDivConstant2(FieldObject f) { + return f.shortValue / shortTestValue2; + } + + @Test + public void testShortDivs() { + FieldObject f = new FieldObject(); + test("testShortDiv", f, shortTestValue1); + test("testShortDivConstant1", f); + test("testShortDivConstant2", f); + } + + @Test + public void testShortNullDiv() { + test("testShortDiv", null, shortTestValue1); + } + + public static int testCharDiv(FieldObject f, char charValue) { + return f.charValue / charValue; + } + + public static int testCharDivConstant1(FieldObject f) { + return f.charValue / charTestValue1; + } + + public static int testCharDivConstant2(FieldObject f) { + return f.charValue / charTestValue2; + } + + @Test + public void testCharDivs() { + FieldObject f = new FieldObject(); + test("testCharDiv", f, charTestValue1); + test("testCharDivConstant1", f); + test("testCharDivConstant2", f); + } + + @Test + public void testCharNullDiv() { + test("testCharDiv", null, charTestValue1); + } + + public static int testIntDiv(FieldObject f, int intValue) { + return f.intValue / intValue; + } + + public static int testIntDivConstant1(FieldObject f) { + return f.intValue / intTestValue1; + } + + public static int testIntDivConstant2(FieldObject f) { + return f.intValue / intTestValue2; + } + + @Test + public void testIntDivs() { + FieldObject f = new FieldObject(); + test("testIntDiv", f, intTestValue1); + test("testIntDivConstant1", f); + test("testIntDivConstant2", f); + } + + @Test + public void testIntNullDiv() { + test("testIntDiv", null, intTestValue1); + } + + public static long testLongDiv(FieldObject f, long longValue) { + return f.longValue / longValue; + } + + public static long testLongDivConstant1(FieldObject f) { + return f.longValue / longTestValue1; + } + + public static long testLongDivConstant2(FieldObject f) { + return f.longValue / longTestValue2; + } + + @Test + public void testLongDivs() { + FieldObject f = new FieldObject(); + test("testLongDiv", f, longTestValue1); + test("testLongDivConstant1", f); + test("testLongDivConstant2", f); + } + + @Test + public void testLongNullDiv() { + test("testLongDiv", null, longTestValue1); + } + + public static float testFloatDiv(FieldObject f, float floatValue) { + return f.floatValue / floatValue; + } + + public static float testFloatDivConstant1(FieldObject f) { + return f.floatValue / floatTestValue1; + } + + public static float testFloatDivConstant2(FieldObject f) { + return f.floatValue / floatTestValue2; + } + + @Test + public void testFloatDivs() { + FieldObject f = new FieldObject(); + test("testFloatDiv", f, floatTestValue1); + test("testFloatDivConstant1", f); + test("testFloatDivConstant2", f); + } + + @Test + public void testFloatNullDiv() { + test("testFloatDiv", null, floatTestValue1); + } + + public static double testDoubleDiv(FieldObject f, double doubleValue) { + return f.doubleValue / doubleValue; + } + + public static double testDoubleDivConstant1(FieldObject f) { + return f.doubleValue / doubleTestValue1; + } + + public static double testDoubleDivConstant2(FieldObject f) { + return f.doubleValue / doubleTestValue2; + } + + @Test + public void testDoubleDivs() { + FieldObject f = new FieldObject(); + test("testDoubleDiv", f, doubleTestValue1); + test("testDoubleDivConstant1", f); + test("testDoubleDivConstant2", f); + } + + @Test + public void testDoubleNullDiv() { + test("testDoubleDiv", null, doubleTestValue1); + } + + public static int testByteOr(FieldObject f, byte byteValue) { + return f.byteValue | byteValue; + } + + public static int testByteOrConstant1(FieldObject f) { + return f.byteValue | byteTestValue1; + } + + public static int testByteOrConstant2(FieldObject f) { + return f.byteValue | byteTestValue2; + } + + @Test + public void testByteOrs() { + FieldObject f = new FieldObject(); + test("testByteOr", f, byteTestValue1); + test("testByteOrConstant1", f); + test("testByteOrConstant2", f); + } + + @Test + public void testByteNullOr() { + test("testByteOr", null, byteTestValue1); + } + + public static int testShortOr(FieldObject f, short shortValue) { + return f.shortValue | shortValue; + } + + public static int testShortOrConstant1(FieldObject f) { + return f.shortValue | shortTestValue1; + } + + public static int testShortOrConstant2(FieldObject f) { + return f.shortValue | shortTestValue2; + } + + @Test + public void testShortOrs() { + FieldObject f = new FieldObject(); + test("testShortOr", f, shortTestValue1); + test("testShortOrConstant1", f); + test("testShortOrConstant2", f); + } + + @Test + public void testShortNullOr() { + test("testShortOr", null, shortTestValue1); + } + + public static int testCharOr(FieldObject f, char charValue) { + return f.charValue | charValue; + } + + public static int testCharOrConstant1(FieldObject f) { + return f.charValue | charTestValue1; + } + + public static int testCharOrConstant2(FieldObject f) { + return f.charValue | charTestValue2; + } + + @Test + public void testCharOrs() { + FieldObject f = new FieldObject(); + test("testCharOr", f, charTestValue1); + test("testCharOrConstant1", f); + test("testCharOrConstant2", f); + } + + @Test + public void testCharNullOr() { + test("testCharOr", null, charTestValue1); + } + + public static int testIntOr(FieldObject f, int intValue) { + return f.intValue | intValue; + } + + public static int testIntOrConstant1(FieldObject f) { + return f.intValue | intTestValue1; + } + + public static int testIntOrConstant2(FieldObject f) { + return f.intValue | intTestValue2; + } + + @Test + public void testIntOrs() { + FieldObject f = new FieldObject(); + test("testIntOr", f, intTestValue1); + test("testIntOrConstant1", f); + test("testIntOrConstant2", f); + } + + @Test + public void testIntNullOr() { + test("testIntOr", null, intTestValue1); + } + + public static long testLongOr(FieldObject f, long longValue) { + return f.longValue | longValue; + } + + public static long testLongOrConstant1(FieldObject f) { + return f.longValue | longTestValue1; + } + + public static long testLongOrConstant2(FieldObject f) { + return f.longValue | longTestValue2; + } + + @Test + public void testLongOrs() { + FieldObject f = new FieldObject(); + test("testLongOr", f, longTestValue1); + test("testLongOrConstant1", f); + test("testLongOrConstant2", f); + } + + @Test + public void testLongNullOr() { + test("testLongOr", null, longTestValue1); + } + + public static int testByteXor(FieldObject f, byte byteValue) { + return f.byteValue ^ byteValue; + } + + public static int testByteXorConstant1(FieldObject f) { + return f.byteValue ^ byteTestValue1; + } + + public static int testByteXorConstant2(FieldObject f) { + return f.byteValue ^ byteTestValue2; + } + + @Test + public void testByteXors() { + FieldObject f = new FieldObject(); + test("testByteXor", f, byteTestValue1); + test("testByteXorConstant1", f); + test("testByteXorConstant2", f); + } + + @Test + public void testByteNullXor() { + test("testByteXor", null, byteTestValue1); + } + + public static int testShortXor(FieldObject f, short shortValue) { + return f.shortValue ^ shortValue; + } + + public static int testShortXorConstant1(FieldObject f) { + return f.shortValue ^ shortTestValue1; + } + + public static int testShortXorConstant2(FieldObject f) { + return f.shortValue ^ shortTestValue2; + } + + @Test + public void testShortXors() { + FieldObject f = new FieldObject(); + test("testShortXor", f, shortTestValue1); + test("testShortXorConstant1", f); + test("testShortXorConstant2", f); + } + + @Test + public void testShortNullXor() { + test("testShortXor", null, shortTestValue1); + } + + public static int testCharXor(FieldObject f, char charValue) { + return f.charValue ^ charValue; + } + + public static int testCharXorConstant1(FieldObject f) { + return f.charValue ^ charTestValue1; + } + + public static int testCharXorConstant2(FieldObject f) { + return f.charValue ^ charTestValue2; + } + + @Test + public void testCharXors() { + FieldObject f = new FieldObject(); + test("testCharXor", f, charTestValue1); + test("testCharXorConstant1", f); + test("testCharXorConstant2", f); + } + + @Test + public void testCharNullXor() { + test("testCharXor", null, charTestValue1); + } + + public static int testIntXor(FieldObject f, int intValue) { + return f.intValue ^ intValue; + } + + public static int testIntXorConstant1(FieldObject f) { + return f.intValue ^ intTestValue1; + } + + public static int testIntXorConstant2(FieldObject f) { + return f.intValue ^ intTestValue2; + } + + @Test + public void testIntXors() { + FieldObject f = new FieldObject(); + test("testIntXor", f, intTestValue1); + test("testIntXorConstant1", f); + test("testIntXorConstant2", f); + } + + @Test + public void testIntNullXor() { + test("testIntXor", null, intTestValue1); + } + + public static long testLongXor(FieldObject f, long longValue) { + return f.longValue ^ longValue; + } + + public static long testLongXorConstant1(FieldObject f) { + return f.longValue ^ longTestValue1; + } + + public static long testLongXorConstant2(FieldObject f) { + return f.longValue ^ longTestValue2; + } + + @Test + public void testLongXors() { + FieldObject f = new FieldObject(); + test("testLongXor", f, longTestValue1); + test("testLongXorConstant1", f); + test("testLongXorConstant2", f); + } + + @Test + public void testLongNullXor() { + test("testLongXor", null, longTestValue1); + } + + public static int testByteAnd(FieldObject f, byte byteValue) { + return f.byteValue & byteValue; + } + + public static int testByteAndConstant1(FieldObject f) { + return f.byteValue & byteTestValue1; + } + + public static int testByteAndConstant2(FieldObject f) { + return f.byteValue & byteTestValue2; + } + + @Test + public void testByteAnds() { + FieldObject f = new FieldObject(); + test("testByteAnd", f, byteTestValue1); + test("testByteAndConstant1", f); + test("testByteAndConstant2", f); + } + + @Test + public void testByteNullAnd() { + test("testByteAnd", null, byteTestValue1); + } + + public static int testShortAnd(FieldObject f, short shortValue) { + return f.shortValue & shortValue; + } + + public static int testShortAndConstant1(FieldObject f) { + return f.shortValue & shortTestValue1; + } + + public static int testShortAndConstant2(FieldObject f) { + return f.shortValue & shortTestValue2; + } + + @Test + public void testShortAnds() { + FieldObject f = new FieldObject(); + test("testShortAnd", f, shortTestValue1); + test("testShortAndConstant1", f); + test("testShortAndConstant2", f); + } + + @Test + public void testShortNullAnd() { + test("testShortAnd", null, shortTestValue1); + } + + public static int testCharAnd(FieldObject f, char charValue) { + return f.charValue & charValue; + } + + public static int testCharAndConstant1(FieldObject f) { + return f.charValue & charTestValue1; + } + + public static int testCharAndConstant2(FieldObject f) { + return f.charValue & charTestValue2; + } + + @Test + public void testCharAnds() { + FieldObject f = new FieldObject(); + test("testCharAnd", f, charTestValue1); + test("testCharAndConstant1", f); + test("testCharAndConstant2", f); + } + + @Test + public void testCharNullAnd() { + test("testCharAnd", null, charTestValue1); + } + + public static int testIntAnd(FieldObject f, int intValue) { + return f.intValue & intValue; + } + + public static int testIntAndConstant1(FieldObject f) { + return f.intValue & intTestValue1; + } + + public static int testIntAndConstant2(FieldObject f) { + return f.intValue & intTestValue2; + } + + @Test + public void testIntAnds() { + FieldObject f = new FieldObject(); + test("testIntAnd", f, intTestValue1); + test("testIntAndConstant1", f); + test("testIntAndConstant2", f); + } + + @Test + public void testIntNullAnd() { + test("testIntAnd", null, intTestValue1); + } + + public static long testLongAnd(FieldObject f, long longValue) { + return f.longValue & longValue; + } + + public static long testLongAndConstant1(FieldObject f) { + return f.longValue & longTestValue1; + } + + public static long testLongAndConstant2(FieldObject f) { + return f.longValue & longTestValue2; + } + + @Test + public void testLongAnds() { + FieldObject f = new FieldObject(); + test("testLongAnd", f, longTestValue1); + test("testLongAndConstant1", f); + test("testLongAndConstant2", f); + } + + @Test + public void testLongNullAnd() { + test("testLongAnd", null, longTestValue1); + } + + public static boolean testIntMask(FieldObject f, int intValue) { + if ((f.intValue & intValue) != 0) { + count++; + return false; + } + return true; + } + + public static boolean testIntMaskConstant1(FieldObject f) { + return (f.intValue & intTestValue1) != 0; + } + + public static boolean testIntMaskConstant2(FieldObject f) { + return (f.intValue & intTestValue2) != 0; + } + + @Test + public void testIntMasks() { + FieldObject f = new FieldObject(); + test("testIntMask", f, intTestValue1); + test("testIntMaskConstant1", f); + test("testIntMaskConstant2", f); + } + + @Test + public void testIntNullMask() { + test("testIntMask", null, intTestValue1); + } + + public static boolean testLongMask(FieldObject f, long longValue) { + if ((f.longValue & longValue) != 0) { + count++; + return false; + } + return true; + } + + public static boolean testLongMaskConstant1(FieldObject f) { + return (f.longValue & longTestValue1) != 0; + } + + public static boolean testLongMaskConstant2(FieldObject f) { + return (f.longValue & longTestValue2) != 0; + } + + @Test + public void testLongMasks() { + FieldObject f = new FieldObject(); + test("testLongMask", f, longTestValue1); + test("testLongMaskConstant1", f); + test("testLongMaskConstant2", f); + } + + @Test + public void testLongNullMask() { + test("testLongMask", null, longTestValue1); + } + + public static int doConvertByteInt(FieldObject f) { + return f.byteValue; + } + + @Test + public void testConvertByteInt() { + test("doConvertByteInt", maxObject); + test("doConvertByteInt", (FieldObject) null); + } + + public static int doConvertShortInt(FieldObject f) { + return f.shortValue; + } + + @Test + public void testConvertShortInt() { + test("doConvertShortInt", maxObject); + test("doConvertShortInt", (FieldObject) null); + } + + public static int doConvertCharInt(FieldObject f) { + return f.charValue; + } + + @Test + public void testConvertCharInt() { + test("doConvertCharInt", maxObject); + test("doConvertCharInt", (FieldObject) null); + } + + public static int doConvertLongInt(FieldObject f) { + return (int) f.longValue; + } + + @Test + public void testConvertLongInt() { + test("doConvertLongInt", maxObject); + test("doConvertLongInt", (FieldObject) null); + } + + public static int doConvertFloatInt(FieldObject f) { + return (int) f.floatValue; + } + + @Test + public void testConvertFloatInt() { + test("doConvertFloatInt", maxObject); + test("doConvertFloatInt", (FieldObject) null); + } + + public static int doConvertDoubleInt(FieldObject f) { + return (int) f.doubleValue; + } + + @Test + public void testConvertDoubleInt() { + test("doConvertDoubleInt", maxObject); + test("doConvertDoubleInt", (FieldObject) null); + } + + public static long doConvertByteLong(FieldObject f) { + return f.byteValue; + } + + @Test + public void testConvertByteLong() { + test("doConvertByteLong", maxObject); + test("doConvertByteLong", (FieldObject) null); + } + + public static long doConvertShortLong(FieldObject f) { + return f.shortValue; + } + + @Test + public void testConvertShortLong() { + test("doConvertShortLong", maxObject); + test("doConvertShortLong", (FieldObject) null); + } + + public static long doConvertCharLong(FieldObject f) { + return f.charValue; + } + + @Test + public void testConvertCharLong() { + test("doConvertCharLong", maxObject); + test("doConvertCharLong", (FieldObject) null); + } + + public static long doConvertIntLong(FieldObject f) { + return f.intValue; + } + + @Test + public void testConvertIntLong() { + test("doConvertIntLong", maxObject); + test("doConvertIntLong", (FieldObject) null); + } + + public static long doConvertFloatLong(FieldObject f) { + return (long) f.floatValue; + } + + @Test + public void testConvertFloatLong() { + test("doConvertFloatLong", maxObject); + test("doConvertFloatLong", (FieldObject) null); + } + + public static long doConvertDoubleLong(FieldObject f) { + return (long) f.doubleValue; + } + + @Test + public void testConvertDoubleLong() { + test("doConvertDoubleLong", maxObject); + test("doConvertDoubleLong", (FieldObject) null); + } + + public static float doConvertByteFloat(FieldObject f) { + return f.byteValue; + } + + @Test + public void testConvertByteFloat() { + test("doConvertByteFloat", maxObject); + test("doConvertByteFloat", (FieldObject) null); + } + + public static float doConvertShortFloat(FieldObject f) { + return f.shortValue; + } + + @Test + public void testConvertShortFloat() { + test("doConvertShortFloat", maxObject); + test("doConvertShortFloat", (FieldObject) null); + } + + public static float doConvertCharFloat(FieldObject f) { + return f.charValue; + } + + @Test + public void testConvertCharFloat() { + test("doConvertCharFloat", maxObject); + test("doConvertCharFloat", (FieldObject) null); + } + + public static float doConvertIntFloat(FieldObject f) { + return f.intValue; + } + + @Test + public void testConvertIntFloat() { + test("doConvertIntFloat", maxObject); + test("doConvertIntFloat", (FieldObject) null); + } + + public static float doConvertLongFloat(FieldObject f) { + return f.longValue; + } + + @Test + public void testConvertLongFloat() { + test("doConvertLongFloat", maxObject); + test("doConvertLongFloat", (FieldObject) null); + } + + public static float doConvertDoubleFloat(FieldObject f) { + return (float) f.doubleValue; + } + + @Test + public void testConvertDoubleFloat() { + test("doConvertDoubleFloat", maxObject); + test("doConvertDoubleFloat", (FieldObject) null); + } + + public static double doConvertByteDouble(FieldObject f) { + return f.byteValue; + } + + @Test + public void testConvertByteDouble() { + test("doConvertByteDouble", maxObject); + test("doConvertByteDouble", (FieldObject) null); + } + + public static double doConvertShortDouble(FieldObject f) { + return f.shortValue; + } + + @Test + public void testConvertShortDouble() { + test("doConvertShortDouble", maxObject); + test("doConvertShortDouble", (FieldObject) null); + } + + public static double doConvertCharDouble(FieldObject f) { + return f.charValue; + } + + @Test + public void testConvertCharDouble() { + test("doConvertCharDouble", maxObject); + test("doConvertCharDouble", (FieldObject) null); + } + + public static double doConvertIntDouble(FieldObject f) { + return f.intValue; + } + + @Test + public void testConvertIntDouble() { + test("doConvertIntDouble", maxObject); + test("doConvertIntDouble", (FieldObject) null); + } + + public static double doConvertLongDouble(FieldObject f) { + return f.longValue; + } + + @Test + public void testConvertLongDouble() { + test("doConvertLongDouble", maxObject); + test("doConvertLongDouble", (FieldObject) null); + } + + public static double doConvertFloatDouble(FieldObject f) { + return f.floatValue; + } + + @Test + public void testConvertFloatDouble() { + test("doConvertFloatDouble", maxObject); + test("doConvertFloatDouble", (FieldObject) null); + } +} diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThread.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThread.java Wed Mar 26 20:44:11 2014 +0100 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2012, 2014, 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.oracle.graal.compiler; + +import com.oracle.graal.compiler.CompilerThreadFactory.*; +import com.oracle.graal.debug.*; + +/** + * A compiler thread is a daemon thread that runs at {@link Thread#MAX_PRIORITY} and executes in the + * context of a thread-local {@linkplain GraalDebugConfig debug configuration}. + */ +public class CompilerThread extends Thread { + + private final DebugConfigAccess debugConfigAccess; + + public CompilerThread(Runnable r, String namePrefix, DebugConfigAccess debugConfigAccess) { + super(r); + this.setName(namePrefix + "-" + this.getId()); + this.setPriority(Thread.MAX_PRIORITY); + this.setDaemon(true); + this.debugConfigAccess = debugConfigAccess; + } + + @Override + public void run() { + GraalDebugConfig debugConfig = debugConfigAccess.getDebugConfig(); + try { + super.run(); + } finally { + if (debugConfig != null) { + for (DebugDumpHandler dumpHandler : debugConfig.dumpHandlers()) { + try { + dumpHandler.close(); + } catch (Throwable t) { + } + } + } + } + } +} diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThreadFactory.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThreadFactory.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThreadFactory.java Wed Mar 26 20:44:11 2014 +0100 @@ -53,38 +53,4 @@ public Thread newThread(Runnable r) { return new CompilerThread(r, threadNamePrefix, debugConfigAccess); } - - /** - * A compiler thread is a daemon thread that runs at {@link Thread#MAX_PRIORITY} and executes in - * the context of a thread-local {@linkplain GraalDebugConfig debug configuration}. - */ - public static class CompilerThread extends Thread { - - private final DebugConfigAccess debugConfigAccess; - - public CompilerThread(Runnable r, String namePrefix, DebugConfigAccess debugConfigAccess) { - super(r); - this.setName(namePrefix + "-" + this.getId()); - this.setPriority(Thread.MAX_PRIORITY); - this.setDaemon(true); - this.debugConfigAccess = debugConfigAccess; - } - - @Override - public void run() { - GraalDebugConfig debugConfig = debugConfigAccess.getDebugConfig(); - try { - super.run(); - } finally { - if (debugConfig != null) { - for (DebugDumpHandler dumpHandler : debugConfig.dumpHandlers()) { - try { - dumpHandler.close(); - } catch (Throwable t) { - } - } - } - } - } - } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java Wed Mar 26 20:44:11 2014 +0100 @@ -1179,7 +1179,9 @@ String to = "?"; if (first != null && first != Range.EndMarker) { from = String.valueOf(from()); - to = String.valueOf(to()); + // to() may cache a computed value, modifying the current object, which is a bad idea + // for a printing function. Compute it directly instead. + to = String.valueOf(calcTo()); } String locationString = this.location == null ? "" : "@" + this.location; return operandNumber + ":" + operand + (isRegister(operand) ? "" : locationString) + "[" + from + "," + to + "]"; diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java Wed Mar 26 20:44:11 2014 +0100 @@ -53,6 +53,14 @@ private MoveResolver moveResolver; // for ordering spill moves + /** + * Only 10% of the lists in {@link #spillIntervals} are actually used. But when they are used, + * they can grow quite long. The maximum length observed was 45 (all numbers taken from a + * bootstrap run of Graal). Therefore, we initialize {@link #spillIntervals} with this marker + * value, and allocate a "real" list only on demand in {@link #setUsePos}. + */ + private static final List EMPTY_LIST = new ArrayList<>(0); + // accessors mapped to same functions in class LinearScan int blockCount() { return allocator.blockCount(); @@ -76,7 +84,7 @@ 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<>(2); + spillIntervals[i] = EMPTY_LIST; } usePos = new int[allocator.registers.length]; blockPos = new int[allocator.registers.length]; @@ -111,7 +119,12 @@ this.usePos[i] = usePos; } if (!onlyProcessUsePos) { - spillIntervals[i].add(interval); + List list = spillIntervals[i]; + if (list == EMPTY_LIST) { + list = new ArrayList<>(2); + spillIntervals[i] = list; + } + list.add(interval); } } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Wed Mar 26 20:44:11 2014 +0100 @@ -145,7 +145,7 @@ /** * set this before using the LIRGenerator - * + * * TODO this should be removed */ void setDebugInfoBuilder(DebugInfoBuilder builder) { @@ -155,7 +155,7 @@ /** * Checks whether the supplied constant can be used without loading it into a register for store * operations, i.e., on the right hand side of a memory access. - * + * * @param c The constant to check. * @return True if the constant can be used directly, false if the constant needs to be in a * register. @@ -204,7 +204,7 @@ /** * Creates a new {@linkplain Variable variable}. - * + * * @param platformKind The kind of the new variable. * @return a new variable */ @@ -260,18 +260,29 @@ return false; } + private static FrameState getFrameState(DeoptimizingNode deopt) { + if (deopt instanceof DeoptimizingNode.DeoptBefore) { + return ((DeoptimizingNode.DeoptBefore) deopt).stateBefore(); + } else if (deopt instanceof DeoptimizingNode.DeoptDuring) { + return ((DeoptimizingNode.DeoptDuring) deopt).stateDuring(); + } else { + assert deopt instanceof DeoptimizingNode.DeoptAfter; + return ((DeoptimizingNode.DeoptAfter) deopt).stateAfter(); + } + } + public LIRFrameState state(DeoptimizingNode deopt) { if (!deopt.canDeoptimize()) { return null; } - return stateFor(deopt.getDeoptimizationState()); + return stateFor(getFrameState(deopt)); } public LIRFrameState stateWithExceptionEdge(DeoptimizingNode deopt, LabelRef exceptionEdge) { if (!deopt.canDeoptimize()) { return null; } - return stateForWithExceptionEdge(deopt.getDeoptimizationState(), exceptionEdge); + return stateForWithExceptionEdge(getFrameState(deopt), exceptionEdge); } public LIRFrameState stateFor(FrameState state) { @@ -288,7 +299,7 @@ /** * Gets the ABI specific operand used to return a value of a given kind from a method. - * + * * @param kind the kind of value being returned * @return the operand representing the ABI defined location used return a value of kind * {@code kind} @@ -300,7 +311,7 @@ return res.getFrameMap().registerConfig.getReturnRegister(kind).asValue(kind); } - protected void append(LIRInstruction op) { + public void append(LIRInstruction op) { if (printIRWithLIR && !TTY.isSuppressed()) { // if (currentInstruction != null && lastInstructionPrinted != currentInstruction) { // lastInstructionPrinted = currentInstruction; @@ -387,7 +398,7 @@ LIRFrameState state = null; if (linkage.canDeoptimize()) { if (info != null) { - state = stateFor(info.getDeoptimizationState()); + state = stateFor(getFrameState(info)); } else { assert needOnlyOopMaps(); state = new LIRFrameState(null, null, null); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRGenerator.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRGenerator.java Wed Mar 26 20:44:11 2014 +0100 @@ -37,6 +37,7 @@ import com.oracle.graal.compiler.gen.LIRGenerator.LoadConstant; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.BlockEndOp; @@ -50,6 +51,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.virtual.*; +import com.oracle.graal.phases.*; /** * This class traverses the HIR instructions and generates LIR instructions from them. @@ -95,18 +97,30 @@ /** * Returns the operand that has been previously initialized by - * {@link #setResult(ValueNode, Value)} with the result of an instruction. - * + * {@link #setResult(ValueNode, Value)} with the result of an instruction. It's a code + * generation error to ask for the operand of ValueNode that doesn't have one yet. + * * @param node A node that produces a result value. */ @Override public Value operand(ValueNode node) { + Value operand = getOperand(node); + assert operand != null : String.format("missing operand for %1s", node); + return operand; + } + + @Override + public boolean hasOperand(ValueNode node) { + return getOperand(node) != null; + } + + private Value getOperand(ValueNode node) { if (nodeOperands == null) { return null; } Value operand = nodeOperands.get(node); if (operand == null) { - return getConstantOperand(node); + operand = getConstantOperand(node); } return operand; } @@ -178,24 +192,40 @@ return LabelRef.forSuccessor(res.getLIR(), (Block) gen.getCurrentBlock(), suxIndex); } + @Deprecated + private static FrameState getFrameState(DeoptimizingNode deopt) { + if (deopt instanceof DeoptimizingNode.DeoptBefore) { + return ((DeoptimizingNode.DeoptBefore) deopt).stateBefore(); + } else if (deopt instanceof DeoptimizingNode.DeoptDuring) { + return ((DeoptimizingNode.DeoptDuring) deopt).stateDuring(); + } else { + assert deopt instanceof DeoptimizingNode.DeoptAfter; + return ((DeoptimizingNode.DeoptAfter) deopt).stateAfter(); + } + } + + @Deprecated public LIRFrameState state(DeoptimizingNode deopt) { if (!deopt.canDeoptimize()) { return null; } - return stateFor(deopt.getDeoptimizationState()); + return stateFor(getFrameState(deopt)); } + @Deprecated public LIRFrameState stateWithExceptionEdge(DeoptimizingNode deopt, LabelRef exceptionEdge) { if (!deopt.canDeoptimize()) { return null; } - return stateForWithExceptionEdge(deopt.getDeoptimizationState(), exceptionEdge); + return stateForWithExceptionEdge(getFrameState(deopt), exceptionEdge); } + @Deprecated public LIRFrameState stateFor(FrameState state) { return stateForWithExceptionEdge(state, null); } + @Deprecated public LIRFrameState stateForWithExceptionEdge(FrameState state, LabelRef exceptionEdge) { if (gen.needOnlyOopMaps()) { return new LIRFrameState(null, null, null); @@ -204,7 +234,7 @@ return getDebugInfoBuilder().build(state, exceptionEdge); } - final protected void append(LIRInstruction op) { + public final void append(LIRInstruction op) { if (printIRWithLIR && !TTY.isSuppressed()) { if (currentInstruction != null && lastInstructionPrinted != currentInstruction) { lastInstructionPrinted = currentInstruction; @@ -275,23 +305,32 @@ } List nodes = blockMap.get(block); + int instructionsFolded = 0; for (int i = 0; i < nodes.size(); i++) { Node instr = nodes.get(i); if (traceLevel >= 3) { TTY.println("LIRGen for " + instr); } + if (instructionsFolded > 0) { + instructionsFolded--; + continue; + } if (!ConstantNodeRecordsUsages && instr instanceof ConstantNode) { // Loading of constants is done lazily by operand() + } else if (instr instanceof ValueNode) { ValueNode valueNode = (ValueNode) instr; - if (operand(valueNode) == null) { + if (!hasOperand(valueNode)) { if (!peephole(valueNode)) { - try { - doRoot((ValueNode) instr); - } catch (GraalInternalError e) { - throw e.addContext(instr); - } catch (Throwable e) { - throw new GraalInternalError(e).addContext(instr); + instructionsFolded = maybeFoldMemory(nodes, i, valueNode); + if (instructionsFolded == 0) { + try { + doRoot((ValueNode) instr); + } catch (GraalInternalError e) { + throw e.addContext(instr); + } catch (Throwable e) { + throw new GraalInternalError(e).addContext(instr); + } } } } else { @@ -318,6 +357,138 @@ doBlockEnd(block); } + private static final DebugMetric MemoryFoldSuccess = Debug.metric("MemoryFoldSuccess"); + private static final DebugMetric MemoryFoldFailed = Debug.metric("MemoryFoldFailed"); + private static final DebugMetric MemoryFoldFailedNonAdjacent = Debug.metric("MemoryFoldedFailedNonAdjacent"); + private static final DebugMetric MemoryFoldFailedDifferentBlock = Debug.metric("MemoryFoldedFailedDifferentBlock"); + + /** + * Subclass can provide helper to fold memory operations into other operations. + */ + public MemoryArithmeticLIRLowerer getMemoryLowerer() { + return null; + } + + /** + * Try to find a sequence of Nodes which can be passed to the backend to look for optimized + * instruction sequences using memory. Currently this basically is a read with a single + * arithmetic user followed by an possible if use. This should generalized to more generic + * pattern matching so that it can be more flexibly used. + */ + private int maybeFoldMemory(List nodes, int i, ValueNode access) { + MemoryArithmeticLIRLowerer lowerer = getMemoryLowerer(); + if (lowerer != null && GraalOptions.OptFoldMemory.getValue() && (access instanceof ReadNode || access instanceof FloatingReadNode) && access.usages().count() == 1 && i + 1 < nodes.size()) { + try (Scope s = Debug.scope("MaybeFoldMemory", access)) { + // This is all bit hacky since it's happening on the linearized schedule. This needs + // to be revisited at some point. + + // Find a memory lowerable usage of this operation + if (access.usages().first() instanceof MemoryArithmeticLIRLowerable) { + ValueNode operation = (ValueNode) access.usages().first(); + if (!nodes.contains(operation)) { + Debug.log("node %1s in different block from %1s", access, operation); + MemoryFoldFailedDifferentBlock.increment(); + return 0; + } + ValueNode firstOperation = operation; + if (operation instanceof LogicNode) { + if (operation.usages().count() == 1 && operation.usages().first() instanceof IfNode) { + ValueNode ifNode = (ValueNode) operation.usages().first(); + if (!nodes.contains(ifNode)) { + MemoryFoldFailedDifferentBlock.increment(); + Debug.log("if node %1s in different block from %1s", ifNode, operation); + try (Indent indent = Debug.logAndIndent("checking operations")) { + int start = nodes.indexOf(access); + int end = nodes.indexOf(operation); + for (int i1 = Math.min(start, end); i1 <= Math.max(start, end); i1++) { + indent.log("%d: (%d) %1s", i1, nodes.get(i1).usages().count(), nodes.get(i1)); + } + } + return 0; + } else { + operation = ifNode; + } + } + } + if (Debug.isLogEnabled()) { + synchronized ("lock") { // Hack to ensure the output is grouped. + try (Indent indent = Debug.logAndIndent("checking operations")) { + int start = nodes.indexOf(access); + int end = nodes.indexOf(operation); + for (int i1 = Math.min(start, end); i1 <= Math.max(start, end); i1++) { + indent.log("%d: (%d) %1s", i1, nodes.get(i1).usages().count(), nodes.get(i1)); + } + } + } + } + // Possible lowerable operation in the same block. Check out the dependencies. + int opIndex = nodes.indexOf(operation); + int current = i + 1; + ArrayList deferred = null; + while (current < opIndex) { + ScheduledNode node = nodes.get(current); + if (node != firstOperation) { + if (node instanceof LocationNode || node instanceof VirtualObjectNode) { + // nothing to do + } else if (node instanceof ConstantNode) { + if (deferred == null) { + deferred = new ArrayList<>(2); + } + // These nodes are collected and the backend is expended to + // evaluate them before generating the lowered form. This + // basically works around unfriendly scheduling of values which + // are defined in a block but not used there. + deferred.add((ValueNode) node); + } else { + Debug.log("unexpected node %1s", node); + // Unexpected inline node + break; + } + } + current++; + } + + if (current == opIndex) { + if (lowerer.memoryPeephole((Access) access, (MemoryArithmeticLIRLowerable) operation, deferred)) { + MemoryFoldSuccess.increment(); + // if this operation had multiple access inputs, then previous attempts + // would be marked as failures which is wrong. Try to adjust the + // counters to account for this. + for (Node input : operation.inputs()) { + if (input == access) { + continue; + } + if (input instanceof Access && nodes.contains(input)) { + MemoryFoldFailedNonAdjacent.add(-1); + } + } + if (deferred != null) { + // Ensure deferred nodes were evaluated + for (ValueNode node : deferred) { + assert hasOperand(node); + } + } + return opIndex - i; + } else { + // This isn't true failure, it just means there wasn't match for the + // pattern. Usually that means it's just not supported by the backend. + MemoryFoldFailed.increment(); + return 0; + } + } else { + MemoryFoldFailedNonAdjacent.increment(); + } + } else { + // memory usage which isn't considered lowerable. Mostly these are + // uninteresting but it might be worth looking at to ensure that interesting + // nodes are being properly handled. + // Debug.log("usage isn't lowerable %1s", access.usages().first()); + } + } + } + return 0; + } + protected abstract boolean peephole(ValueNode valueNode); private boolean hasBlockEnd(Block block) { @@ -336,7 +507,7 @@ Debug.log("Visiting %s", instr); emitNode(instr); - Debug.log("Operand for %s = %s", instr, operand(instr)); + Debug.log("Operand for %s = %s", instr, getOperand(instr)); } protected void emitNode(ValueNode node) { @@ -459,7 +630,7 @@ private Value operandForPhi(PhiNode phi) { assert phi.type() == PhiType.Value : "wrong phi type: " + phi; - Value result = operand(phi); + Value result = getOperand(phi); if (result == null) { // allocate a variable for this phi Variable newOperand = gen.newVariable(getPhiKind(phi)); @@ -622,7 +793,7 @@ * This method tries to create a switch implementation that is optimal for the given switch. It * will either generate a sequential if/then/else cascade, a set of range tests or a table * switch. - * + * * If the given switch does not contain int keys, it will always create a sequential * implementation. */ diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java Wed Mar 26 20:44:11 2014 +0100 @@ -25,15 +25,29 @@ import static com.oracle.graal.phases.GraalOptions.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.options.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; public class LowTier extends PhaseSuite { + static class Options { + + // @formatter:off + @Option(help = "") + public static final OptionValue ProfileCompiledMethods = new OptionValue<>(false); + // @formatter:on + + } + public LowTier() { CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue()); + if (Options.ProfileCompiledMethods.getValue()) { + appendPhase(new ProfileCompiledMethodsPhase()); + } + appendPhase(new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.LOW_TIER)); appendPhase(new RemoveValueProxyPhase()); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Wed Mar 26 20:44:11 2014 +0100 @@ -356,7 +356,9 @@ /** * Prints a message to the current debug scope's logging stream. This method must only be called - * if debugging is {@linkplain Debug#isEnabled() enabled}. + * if debugging is {@linkplain Debug#isEnabled() enabled} as it incurs allocation at the call + * site. If possible, call one of the other {@code log()} methods in this class that take a + * fixed number of parameters. * * @param format a format string * @param args the arguments referenced by the format specifiers in {@code format} @@ -369,6 +371,17 @@ } /** + * This override exists the catch cases when log is called with one argument from a method which + * is vararg. It will bind to this method instead of the single arg variant and produce a + * deprecation warning instead of silently wrapping the Object[] inside of another Object[]. + */ + @Deprecated + public static void log(String format, Object[] args) { + assert false : "shouldn't use this"; + logv(format, args); + } + + /** * The same as {@link #log}, but without line termination and without indentation. */ public static void printf(String msg, Object... args) { @@ -443,6 +456,73 @@ return noLoggerInstance; } + /** + * A convenience function which combines enabling/disabling of logging and + * {@link #logAndIndent(String, Object...)}. Note: Use this method with care because it + * overrules the -G:Log option. + * + * @param enabled Flag for enabling or disabling logging + * @param msg The format string of the log message + * @param args The arguments referenced by the log message string + * @return The new indentation level + * @see Indent#logAndIndent + */ + public static Indent logAndIndent(boolean enabled, String msg, Object... args) { + if (ENABLED) { + Collection dumpHandlers; + PrintStream output; + DebugConfig currentConfig = DebugScope.getConfig(); + if (currentConfig != null) { + dumpHandlers = currentConfig.dumpHandlers(); + output = currentConfig.output(); + } else { + dumpHandlers = Collections. emptyList(); + output = System.out; + } + DebugConfigScope configScope = new DebugConfigScope(Debug.fixedConfig(enabled, Debug.isDumpEnabled(), false, false, dumpHandlers, output)); + return new IndentWithEnable(Debug.logAndIndent(msg, args), configScope); + } + return noLoggerInstance; + } + + private static class IndentWithEnable implements Indent { + + Indent delegate; + DebugConfigScope configScope; + + IndentWithEnable(Indent delegate, DebugConfigScope configScope) { + this.delegate = delegate; + this.configScope = configScope; + } + + @Override + public void log(String msg, Object... args) { + delegate.log(msg, args); + } + + @Override + public Indent indent() { + return delegate.indent(); + } + + @Override + public Indent logAndIndent(String msg, Object... args) { + return delegate.logAndIndent(msg, args); + } + + @Override + public Indent outdent() { + configScope.close(); + return delegate.outdent(); + } + + @Override + public void close() { + configScope.close(); + delegate.close(); + } + } + public static Iterable context() { if (ENABLED) { return DebugScope.getInstance().getCurrentContext(); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed Mar 26 20:44:11 2014 +0100 @@ -44,6 +44,7 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.NoOp; import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.amd64.AMD64Move.LeaDataOp; import com.oracle.graal.lir.amd64.AMD64Move.LoadOp; import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp; import com.oracle.graal.lir.amd64.AMD64Move.StoreConstantOp; @@ -152,6 +153,10 @@ return ((AMD64HotSpotLIRGenerationResult) res).getStub() != null; } + public void emitData(AllocatableValue dst, byte[] data) { + append(new LeaDataOp(dst, data)); + } + private LIRFrameState currentRuntimeCallInfo; @Override diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMemoryPeephole.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMemoryPeephole.java Wed Mar 26 20:44:11 2014 +0100 @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2014, 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.oracle.graal.hotspot.amd64; + +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.compiler.amd64.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.data.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.amd64.AMD64ControlFlow.BranchOp; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.extended.*; + +/** + * Specialized code gen for comparison with compressed memory. + */ + +public class AMD64HotSpotMemoryPeephole extends AMD64MemoryPeephole { + public static class CompareMemoryCompressedOp extends AMD64LIRInstruction { + @Alive({COMPOSITE}) protected AMD64AddressValue x; + @Use({CONST}) protected Value y; + @State protected LIRFrameState state; + + public CompareMemoryCompressedOp(AMD64AddressValue x, Constant y, LIRFrameState state) { + this.x = x; + this.y = y; + this.state = state; + } + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + Constant constant = (Constant) y; + if (constant.isNull()) { + masm.cmpl(x.toAddress(), 0); + } else { + if (y.getKind() == Kind.Object) { + crb.recordInlineDataInCode(new OopData(0, constant.asObject(), true)); + } else if (y.getKind() == Kind.Long) { + crb.recordInlineDataInCode(new MetaspaceData(0, constant.asLong(), constant.getPrimitiveAnnotation(), true)); + } else { + throw GraalInternalError.shouldNotReachHere(); + } + if (state != null) { + crb.recordImplicitException(masm.position(), state); + } + masm.cmpl(x.toAddress(), 0xdeaddead); + } + } + } + + AMD64HotSpotMemoryPeephole(AMD64NodeLIRGenerator gen) { + super(gen); + } + + @Override + protected boolean emitCompareBranchMemory(ValueNode left, ValueNode right, Access access, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel, + double trueLabelProbability) { + assert left == access || right == access; + ValueNode other = left == access ? right : left; + Kind kind = access.nullCheckLocation().getValueKind(); + + if (other.isConstant() && kind == Kind.Object && access.isCompressible()) { + ensureEvaluated(other); + gen.append(new CompareMemoryCompressedOp(makeAddress(access), other.asConstant(), getState(access))); + Condition finalCondition = right == access ? cond.mirror() : cond; + gen.append(new BranchOp(finalCondition, trueLabel, falseLabel, trueLabelProbability)); + return true; + } + + return super.emitCompareBranchMemory(left, right, access, cond, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability); + } +} diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRGenerator.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRGenerator.java Wed Mar 26 20:44:11 2014 +0100 @@ -59,6 +59,7 @@ public AMD64HotSpotNodeLIRGenerator(StructuredGraph graph, LIRGenerationResult res, LIRGenerator gen) { super(graph, res, gen); + memoryPeephole = new AMD64HotSpotMemoryPeephole(this); } private AMD64HotSpotLIRGenerator getGen() { diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java Wed Mar 26 20:44:11 2014 +0100 @@ -82,7 +82,7 @@ NodeIterable calls = graph.getNodes(MethodCallTargetNode.class); assert calls.count() == 1; ResolvedJavaMethod lambdaMethod = calls.first().targetMethod(); - Debug.log("target ... " + lambdaMethod); + Debug.log("target ... %s", lambdaMethod); if (lambdaMethod == null) { Debug.log("Did not find call in accept()"); @@ -115,7 +115,7 @@ getHSAILBackend().executeKernel(code, jobSize, args); return true; } catch (InvalidInstalledCodeException iice) { - Debug.log("WARNING: Invalid installed code at exec time." + iice); + Debug.log("WARNING: Invalid installed code at exec time: %s", iice); iice.printStackTrace(); return false; } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java Wed Mar 26 20:44:11 2014 +0100 @@ -31,6 +31,8 @@ import com.oracle.graal.compiler.hsail.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.hsail.*; import com.oracle.graal.lir.hsail.HSAILControlFlow.ForeignCall1ArgOp; @@ -57,6 +59,11 @@ this.config = config; } + @Override + public HotSpotProviders getProviders() { + return (HotSpotProviders) super.getProviders(); + } + int getLogMinObjectAlignment() { return config.logMinObjAlignment(); } @@ -131,6 +138,9 @@ if (isCompressed) { if ((c.getKind() == Kind.Object) && c.isNull()) { append(new StoreConstantOp(Kind.Int, storeAddress, Constant.forInt(0), state)); + } else if (c.getKind() == Kind.Long) { + Constant value = compress(c, config.getKlassEncoding()); + append(new StoreConstantOp(Kind.Int, storeAddress, value, state)); } else { throw GraalInternalError.shouldNotReachHere("can't handle: " + access); } @@ -194,4 +204,14 @@ // this version of emitForeignCall not used for now } + /** + * @return a compressed version of the incoming constant lifted from AMD64HotSpotLIRGenerator + */ + protected static Constant compress(Constant c, CompressEncoding encoding) { + if (c.getKind() == Kind.Long) { + return Constant.forIntegerKind(Kind.Int, (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL), c.getPrimitiveAnnotation()); + } else { + throw GraalInternalError.shouldNotReachHere(); + } + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRGenerator.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRGenerator.java Wed Mar 26 20:44:11 2014 +0100 @@ -28,6 +28,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.hsail.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; import com.oracle.graal.lir.*; import com.oracle.graal.lir.hsail.*; import com.oracle.graal.lir.hsail.HSAILControlFlow.CondMoveOp; @@ -85,4 +87,14 @@ setResult(node, nodeResult); } + /** + * @return a compressed version of the incoming constant lifted from AMD64HotSpotLIRGenerator + */ + protected static Constant compress(Constant c, CompressEncoding encoding) { + if (c.getKind() == Kind.Long) { + return Constant.forIntegerKind(Kind.Int, (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL), c.getPrimitiveAnnotation()); + } else { + throw GraalInternalError.shouldNotReachHere(); + } + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java Wed Mar 26 20:44:11 2014 +0100 @@ -250,7 +250,7 @@ ValueNode[] launchArgsArray = args.values().toArray(new ValueNode[args.size()]); ForeignCallNode result = append(new ForeignCallNode(providers.getForeignCalls(), CALL_KERNEL, launchArgsArray)); - result.setDeoptimizationState(fs); + result.setStateAfter(fs); InvokeNode getObjectResult = null; ValueNode returnValue; diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Wed Mar 26 20:44:11 2014 +0100 @@ -31,6 +31,7 @@ import static com.oracle.graal.phases.common.InliningUtil.*; import java.io.*; +import java.lang.management.*; import java.lang.reflect.*; import java.util.*; import java.util.concurrent.*; @@ -40,7 +41,7 @@ import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; import com.oracle.graal.baseline.*; -import com.oracle.graal.compiler.CompilerThreadFactory.CompilerThread; +import com.oracle.graal.compiler.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.debug.internal.*; @@ -108,6 +109,12 @@ private boolean blocking; + /** + * A {@link com.sun.management.ThreadMXBean} to be able to query some information about the + * current compiler thread, e.g. total allocated bytes. + */ + private final com.sun.management.ThreadMXBean threadMXBean = (com.sun.management.ThreadMXBean) ManagementFactory.getThreadMXBean(); + public CompilationTask(HotSpotBackend backend, HotSpotResolvedJavaMethod method, int entryBCI, boolean blocking) { this.backend = backend; this.method = method; @@ -210,9 +217,11 @@ */ HotSpotVMConfig config = backend.getRuntime().getConfig(); + final long threadId = Thread.currentThread().getId(); long previousInlinedBytecodes = InlinedBytecodes.getCurrentValue(); long previousCompilationTime = CompilationTime.getCurrentValue(); HotSpotInstalledCode installedCode = null; + try (TimerCloseable a = CompilationTime.start()) { if (!tryToChangeStatus(CompilationStatus.Queued, CompilationStatus.Running)) { return; @@ -237,7 +246,9 @@ CompilationResult result = null; TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method); - long start = System.currentTimeMillis(); + final long start = System.currentTimeMillis(); + final long allocatedBytesBefore = threadMXBean.getThreadAllocatedBytes(threadId); + try (Scope s = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(id), true))) { if (UseBaselineCompiler.getValue() == true) { @@ -281,10 +292,18 @@ } finally { filter.remove(); final boolean printAfterCompilation = PrintAfterCompilation.getValue() && !TTY.isSuppressed(); - if (printAfterCompilation) { - TTY.println(getMethodDescription() + String.format(" | %4dms %5dB", System.currentTimeMillis() - start, (result != null ? result.getTargetCodeSize() : -1))); - } else if (printCompilation) { - TTY.println(String.format("%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, (result != null ? result.getTargetCodeSize() : -1))); + + if (printAfterCompilation || printCompilation) { + final long stop = System.currentTimeMillis(); + final int targetCodeSize = result != null ? result.getTargetCodeSize() : -1; + final long allocatedBytesAfter = threadMXBean.getThreadAllocatedBytes(threadId); + final long allocatedBytes = (allocatedBytesAfter - allocatedBytesBefore) / 1024; + + if (printAfterCompilation) { + TTY.println(getMethodDescription() + String.format(" | %4dms %5dB %5dkB", stop - start, targetCodeSize, allocatedBytes)); + } else if (printCompilation) { + TTY.println(String.format("%-6d Graal %-70s %-45s %-50s | %4dms %5dB %5dkB", id, "", "", "", stop - start, targetCodeSize, allocatedBytes)); + } } } @@ -296,7 +315,6 @@ } } stats.finish(method, installedCode); - } catch (BailoutException bailout) { BAILOUTS.increment(); if (ExitVMOnBailout.getValue()) { diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Wed Mar 26 20:44:11 2014 +0100 @@ -1022,8 +1022,15 @@ @HotSpotVMField(name = "Method::_access_flags", type = "AccessFlags", get = HotSpotVMField.Type.OFFSET) @Stable public int methodAccessFlagsOffset; @HotSpotVMField(name = "Method::_constMethod", type = "ConstMethod*", get = HotSpotVMField.Type.OFFSET) @Stable public int methodConstMethodOffset; @HotSpotVMField(name = "Method::_intrinsic_id", type = "u1", get = HotSpotVMField.Type.OFFSET) @Stable public int methodIntrinsicIdOffset; + @HotSpotVMField(name = "Method::_flags", type = "u1", get = HotSpotVMField.Type.OFFSET) @Stable public int methodFlagsOffset; @HotSpotVMField(name = "Method::_vtable_index", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int methodVtableIndexOffset; + @HotSpotVMConstant(name = "Method::_jfr_towrite") @Stable public int methodFlagsJfrTowrite; + @HotSpotVMConstant(name = "Method::_caller_sensitive") @Stable public int methodFlagsCallerSensitive; + @HotSpotVMConstant(name = "Method::_force_inline") @Stable public int methodFlagsForceInline; + @HotSpotVMConstant(name = "Method::_dont_inline") @Stable public int methodFlagsDontInline; + @HotSpotVMConstant(name = "Method::_hidden") @Stable public int methodFlagsHidden; + @HotSpotVMConstant(name = "JVM_ACC_MONITOR_MATCH") @Stable public int jvmAccMonitorMatch; @HotSpotVMConstant(name = "JVM_ACC_HAS_MONITOR_BYTECODES") @Stable public int jvmAccHasMonitorBytecodes; @@ -1276,6 +1283,7 @@ @HotSpotVMConstant(name = "DataLayout::call_type_data_tag") @Stable public int dataLayoutCallTypeDataTag; @HotSpotVMConstant(name = "DataLayout::virtual_call_type_data_tag") @Stable public int dataLayoutVirtualCallTypeDataTag; @HotSpotVMConstant(name = "DataLayout::parameters_type_data_tag") @Stable public int dataLayoutParametersTypeDataTag; + @HotSpotVMConstant(name = "DataLayout::speculative_trap_data_tag") @Stable public int dataLayoutSpeculativeTrapDataTag; @HotSpotVMFlag(name = "BciProfileWidth") @Stable public int bciProfileWidth; @HotSpotVMFlag(name = "TypeProfileWidth") @Stable public int typeProfileWidth; diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Wed Mar 26 20:44:11 2014 +0100 @@ -99,12 +99,12 @@ long getKlassImplementor(long metaspaceKlass); /** - * Initializes a {@link HotSpotResolvedJavaMethod} object from a metaspace Method object. + * Determines if a given metaspace method is ignored by security stack walks. * * @param metaspaceMethod the metaspace Method object - * @param method address of a metaspace Method object + * @return true if the method is ignored */ - void initializeMethod(long metaspaceMethod, HotSpotResolvedJavaMethod method); + boolean methodIsIgnoredBySecurityStackWalk(long metaspaceMethod); /** * Converts a name to a metaspace klass. diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Wed Mar 26 20:44:11 2014 +0100 @@ -104,8 +104,7 @@ @Override public native boolean hasFinalizableSubclass(long metaspaceKlass); - @Override - public native void initializeMethod(long metaspaceMethod, HotSpotResolvedJavaMethod method); + public native boolean methodIsIgnoredBySecurityStackWalk(long metaspaceMethod); @Override public native long getClassInitializer(long metaspaceKlass); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Wed Mar 26 20:44:11 2014 +0100 @@ -33,7 +33,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.*; -import com.oracle.graal.compiler.CompilerThreadFactory.CompilerThread; import com.oracle.graal.compiler.CompilerThreadFactory.DebugConfigAccess; import com.oracle.graal.debug.*; import com.oracle.graal.debug.internal.*; diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Wed Mar 26 20:44:11 2014 +0100 @@ -23,7 +23,6 @@ package com.oracle.graal.hotspot.debug; import java.io.*; -import java.text.*; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; @@ -36,8 +35,8 @@ import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; +import com.oracle.graal.nodes.HeapAccess.BarrierType; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.HeapAccess.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.debug.*; import com.oracle.graal.nodes.extended.*; @@ -83,6 +82,8 @@ //@formatter:off @Option(help = "Turn on the benchmark counters, and displays the results on VM shutdown") private static final OptionValue GenericDynamicCounters = new OptionValue<>(false); + @Option(help = "Turn on the benchmark counters, and displays the results every n milliseconds") + private static final OptionValue TimedDynamicCounters = new OptionValue<>(-1); @Option(help = "Turn on the benchmark counters, and listen for specific patterns on System.out/System.err:%n" + "Format: (err|out),start pattern,end pattern (~ matches multiple digits)%n" + @@ -109,7 +110,8 @@ } String name = counter.getName(); String group = counter.getGroup(); - name = counter.isWithContext() ? name + " @ " + counter.graph().graphId() + ":" + MetaUtil.format("%h.%n", counter.graph().method()) + "#" + group : name + "#" + group; + name = counter.isWithContext() && counter.graph().method() != null ? name + " @ " + counter.graph().graphId() + ":" + MetaUtil.format("%h.%n", counter.graph().method()) + "#" + group : name + + "#" + group; Integer index = indexes.get(name); if (index == null) { synchronized (BenchmarkCounters.class) { @@ -129,15 +131,15 @@ return index; } - public static synchronized void dump(PrintStream out, double seconds, long[] counters) { + public static synchronized void dump(PrintStream out, double seconds, long[] counters, int maxRows) { if (!groups.isEmpty()) { out.println("====== dynamic counters (" + staticCounters.size() + " in total) ======"); for (String group : new TreeSet<>(groups)) { if (group != null) { if (DUMP_STATIC) { - dumpCounters(out, seconds, counters, true, group); + dumpCounters(out, seconds, counters, true, group, maxRows); } - dumpCounters(out, seconds, counters, false, group); + dumpCounters(out, seconds, counters, false, group, maxRows); } } out.println("============================"); @@ -150,9 +152,10 @@ delta = counters; } - private static synchronized void dumpCounters(PrintStream out, double seconds, long[] counters, boolean staticCounter, String group) { + private static synchronized void dumpCounters(PrintStream out, double seconds, long[] counters, boolean staticCounter, String group, int maxRows) { TreeMap sorted = new TreeMap<>(); + // collect the numbers long[] array; if (staticCounter) { array = new long[indexes.size()]; @@ -165,6 +168,7 @@ array[i] -= delta[i]; } } + // sort the counters by putting them into a sorted map long sum = 0; for (Map.Entry entry : indexes.entrySet()) { int index = entry.getValue(); @@ -175,41 +179,51 @@ } if (sum > 0) { - NumberFormat format = NumberFormat.getInstance(Locale.US); long cutoff = sorted.size() < 10 ? 1 : Math.max(1, sum / 100); + int cnt = sorted.size(); + + // remove everything below cutoff and keep at most maxRows + Iterator> iter = sorted.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + long counter = entry.getKey() / array.length; + if (counter < cutoff || cnt > maxRows) { + iter.remove(); + } + cnt--; + } + if (staticCounter) { out.println("=========== " + group + " (static counters):"); for (Map.Entry entry : sorted.entrySet()) { long counter = entry.getKey() / array.length; - if (counter >= cutoff) { - out.println(format.format(counter) + " \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue()); - } + out.format(Locale.US, "%,19d %3d%% %s\n", counter, percentage(counter, sum), entry.getValue()); } - out.println(sum + ": total"); + out.format(Locale.US, "%,19d total\n", sum); } else { if (group.startsWith("~")) { out.println("=========== " + group + " (dynamic counters), time = " + seconds + " s:"); for (Map.Entry entry : sorted.entrySet()) { long counter = entry.getKey() / array.length; - if (counter >= cutoff) { - out.println(format.format((long) (counter / seconds)) + "/s \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue()); - } + out.format(Locale.US, "%,19d/s %3d%% %s\n", (long) (counter / seconds), percentage(counter, sum), entry.getValue()); } - out.println(format.format((long) (sum / seconds)) + "/s: total"); + out.format(Locale.US, "%,19d/s total\n", (long) (sum / seconds)); } else { out.println("=========== " + group + " (dynamic counters):"); for (Map.Entry entry : sorted.entrySet()) { long counter = entry.getKey() / array.length; - if (counter >= cutoff) { - out.println(format.format(counter) + " \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue()); - } + out.format(Locale.US, "%,19d %3d%% %s\n", counter, percentage(counter, sum), entry.getValue()); } - out.println(format.format(sum) + ": total"); + out.format(Locale.US, "%,19d total\n", sum); } } } } + private static long percentage(long counter, long sum) { + return (counter * 200 + 1) / sum / 2; + } + public abstract static class CallbackOutputStream extends OutputStream { protected final PrintStream delegate; @@ -282,7 +296,7 @@ case 2: if (waitingForEnd) { waitingForEnd = false; - BenchmarkCounters.dump(delegate, (System.nanoTime() - startTime) / 1000000000d, compilerToVM.collectCounters()); + BenchmarkCounters.dump(delegate, (System.nanoTime() - startTime) / 1000000000d, compilerToVM.collectCounters(), 100); } break; } @@ -309,20 +323,43 @@ if (Options.GenericDynamicCounters.getValue()) { enabled = true; } - if (Options.GenericDynamicCounters.getValue() || Options.BenchmarkDynamicCounters.getValue() != null) { + if (Options.TimedDynamicCounters.getValue() > 0) { + Thread thread = new Thread() { + long lastTime = System.nanoTime(); + PrintStream out = System.out; + + @Override + public void run() { + while (true) { + try { + Thread.sleep(Options.TimedDynamicCounters.getValue()); + } catch (InterruptedException e) { + } + long time = System.nanoTime(); + dump(out, (time - lastTime) / 1000000000d, compilerToVM.collectCounters(), 10); + lastTime = time; + } + } + }; + thread.setDaemon(true); + thread.setPriority(Thread.MAX_PRIORITY); + thread.start(); + enabled = true; + } + if (enabled) { clear(compilerToVM.collectCounters()); } } public static void shutdown(CompilerToVM compilerToVM, long compilerStartTime) { if (Options.GenericDynamicCounters.getValue()) { - dump(System.out, (System.nanoTime() - compilerStartTime) / 1000000000d, compilerToVM.collectCounters()); + dump(System.out, (System.nanoTime() - compilerStartTime) / 1000000000d, compilerToVM.collectCounters(), 100); } } public static void lower(DynamicCounterNode counter, HotSpotRegistersProvider registers, HotSpotVMConfig config, Kind wordKind) { StructuredGraph graph = counter.graph(); - if (excludedClassPrefix == null || !counter.graph().method().getDeclaringClass().getName().startsWith(excludedClassPrefix)) { + if (excludedClassPrefix == null || (counter.graph().method() != null && !counter.graph().method().getDeclaringClass().getName().startsWith(excludedClassPrefix))) { ReadRegisterNode thread = graph.add(new ReadRegisterNode(registers.getThreadRegister(), wordKind, true, false)); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Wed Mar 26 20:44:11 2014 +0100 @@ -33,6 +33,7 @@ import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType; import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.HotSpotMethodDataAccessor.Tag; /** * Access to a HotSpot MethodData structure (defined in methodData.hpp). @@ -57,7 +58,11 @@ new RetData(), new BranchData(), new MultiBranchData(), - new ArgInfoData() + new ArgInfoData(), + null, // call_type_data_tag + null, // virtual_call_type_data_tag + null, // parameters_type_data_tag + null // speculative_trap_data_tag }; // @formatter:on @@ -146,9 +151,10 @@ private HotSpotMethodDataAccessor getData(int position) { assert position >= 0 : "out of bounds"; - int tag = AbstractMethodData.readTag(this, position); - assert tag >= 0 && tag < PROFILE_DATA_ACCESSORS.length : "illegal tag " + tag; - return PROFILE_DATA_ACCESSORS[tag]; + final Tag tag = AbstractMethodData.readTag(this, position); + HotSpotMethodDataAccessor accessor = PROFILE_DATA_ACCESSORS[tag.getValue()]; + assert accessor == null || accessor.getTag() == tag : "wrong data accessor " + accessor + " for tag " + tag; + return accessor; } private int readUnsignedByte(int position, int offsetInBytes) { @@ -258,20 +264,21 @@ */ private static final int EXCEPTIONS_MASK = 0x2; - private final int tag; + private final Tag tag; private final int staticSize; - protected AbstractMethodData(int tag, int staticSize) { + protected AbstractMethodData(Tag tag, int staticSize) { this.tag = tag; this.staticSize = staticSize; } - public int getTag() { + public Tag getTag() { return tag; } - public static int readTag(HotSpotMethodData data, int position) { - return data.readUnsignedByte(position, config.dataLayoutTagOffset); + public static Tag readTag(HotSpotMethodData data, int position) { + final int tag = data.readUnsignedByte(position, config.dataLayoutTagOffset); + return Tag.getEnum(tag); } @Override @@ -337,7 +344,7 @@ private final TriState exceptionSeen; protected NoMethodData(TriState exceptionSeen) { - super(runtime().getConfig().dataLayoutNoTag, NO_DATA_SIZE); + super(Tag.No, NO_DATA_SIZE); this.exceptionSeen = exceptionSeen; } @@ -363,10 +370,10 @@ private static final int BIT_DATA_NULL_SEEN_FLAG = 0x01; private BitData() { - super(runtime().getConfig().dataLayoutBitDataTag, BIT_DATA_SIZE); + super(Tag.BitData, BIT_DATA_SIZE); } - protected BitData(int tag, int staticSize) { + protected BitData(Tag tag, int staticSize) { super(tag, staticSize); } @@ -387,10 +394,10 @@ private static final int COUNTER_DATA_COUNT_OFFSET = cellIndexToOffset(0); public CounterData() { - super(runtime().getConfig().dataLayoutCounterDataTag, COUNTER_DATA_SIZE); + super(Tag.CounterData, COUNTER_DATA_SIZE); } - protected CounterData(int tag, int staticSize) { + protected CounterData(Tag tag, int staticSize) { super(tag, staticSize); } @@ -416,10 +423,10 @@ protected static final int TAKEN_DISPLACEMENT_OFFSET = cellIndexToOffset(1); public JumpData() { - super(runtime().getConfig().dataLayoutJumpDataTag, JUMP_DATA_SIZE); + super(Tag.JumpData, JUMP_DATA_SIZE); } - protected JumpData(int tag, int staticSize) { + protected JumpData(Tag tag, int staticSize) { super(tag, staticSize); } @@ -465,7 +472,7 @@ protected static final int TYPE_DATA_FIRST_TYPE_OFFSET = cellIndexToOffset(2); protected static final int TYPE_DATA_FIRST_TYPE_COUNT_OFFSET = cellIndexToOffset(3); - protected AbstractTypeData(int tag, int staticSize) { + protected AbstractTypeData(Tag tag, int staticSize) { super(tag, staticSize); } @@ -548,7 +555,7 @@ private static final int TYPE_CHECK_DATA_SIZE = cellIndexToOffset(2) + TYPE_DATA_ROW_SIZE * config.typeProfileWidth; public TypeCheckData() { - super(runtime().getConfig().dataLayoutReceiverTypeDataTag, TYPE_CHECK_DATA_SIZE); + super(Tag.ReceiverTypeData, TYPE_CHECK_DATA_SIZE); } @Override @@ -569,12 +576,12 @@ private static final int VIRTUAL_CALL_DATA_FIRST_METHOD_COUNT_OFFSET = TYPE_DATA_FIRST_TYPE_COUNT_OFFSET + TYPE_DATA_ROW_SIZE * config.typeProfileWidth; public VirtualCallData() { - super(runtime().getConfig().dataLayoutVirtualCallDataTag, VIRTUAL_CALL_DATA_SIZE); + super(Tag.VirtualCallData, VIRTUAL_CALL_DATA_SIZE); } @Override public int getExecutionCount(HotSpotMethodData data, int position) { - int typeProfileWidth = config.typeProfileWidth; + final int typeProfileWidth = config.typeProfileWidth; long total = 0; for (int i = 0; i < typeProfileWidth; i++) { @@ -670,7 +677,7 @@ private static final int RET_DATA_SIZE = cellIndexToOffset(1) + RET_DATA_ROW_SIZE * config.bciProfileWidth; public RetData() { - super(runtime().getConfig().dataLayoutRetDataTag, RET_DATA_SIZE); + super(Tag.RetData, RET_DATA_SIZE); } } @@ -680,7 +687,7 @@ private static final int NOT_TAKEN_COUNT_OFFSET = cellIndexToOffset(2); public BranchData() { - super(runtime().getConfig().dataLayoutBranchDataTag, BRANCH_DATA_SIZE); + super(Tag.BranchData, BRANCH_DATA_SIZE); } @Override @@ -712,7 +719,7 @@ private static final int ARRAY_DATA_LENGTH_OFFSET = cellIndexToOffset(0); protected static final int ARRAY_DATA_START_OFFSET = cellIndexToOffset(1); - public ArrayData(int tag, int staticSize) { + public ArrayData(Tag tag, int staticSize) { super(tag, staticSize); } @@ -740,7 +747,7 @@ private static final int MULTI_BRANCH_DATA_FIRST_DISPLACEMENT_OFFSET = ARRAY_DATA_START_OFFSET + cellsToBytes(1); public MultiBranchData() { - super(runtime().getConfig().dataLayoutMultiBranchDataTag, MULTI_BRANCH_DATA_SIZE); + super(Tag.MultiBranchData, MULTI_BRANCH_DATA_SIZE); } @Override @@ -822,7 +829,7 @@ private static final int ARG_INFO_DATA_SIZE = cellIndexToOffset(1); public ArgInfoData() { - super(runtime().getConfig().dataLayoutArgInfoDataTag, ARG_INFO_DATA_SIZE); + super(Tag.ArgInfoData, ARG_INFO_DATA_SIZE); } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodDataAccessor.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodDataAccessor.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodDataAccessor.java Wed Mar 26 20:44:11 2014 +0100 @@ -22,8 +22,12 @@ */ package com.oracle.graal.hotspot.meta; +import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; + import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.ProfilingInfo.TriState; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.*; /** * Interface for accessor objects that encapsulate the logic for accessing the different kinds of @@ -33,11 +37,54 @@ public interface HotSpotMethodDataAccessor { /** - * Returns the tag stored in the LayoutData header. + * {@code DataLayout} tag values. + */ + enum Tag { + No(config().dataLayoutNoTag), + BitData(config().dataLayoutBitDataTag), + CounterData(config().dataLayoutCounterDataTag), + JumpData(config().dataLayoutJumpDataTag), + ReceiverTypeData(config().dataLayoutReceiverTypeDataTag), + VirtualCallData(config().dataLayoutVirtualCallDataTag), + RetData(config().dataLayoutRetDataTag), + BranchData(config().dataLayoutBranchDataTag), + MultiBranchData(config().dataLayoutMultiBranchDataTag), + ArgInfoData(config().dataLayoutArgInfoDataTag), + CallTypeData(config().dataLayoutCallTypeDataTag), + VirtualCallTypeData(config().dataLayoutVirtualCallTypeDataTag), + ParametersTypeData(config().dataLayoutParametersTypeDataTag), + SpeculativeTrapData(config().dataLayoutSpeculativeTrapDataTag); + + private final int value; + + private Tag(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + + private static HotSpotVMConfig config() { + return runtime().getConfig(); + } + + public static Tag getEnum(int value) { + for (Tag e : values()) { + if (e.value == value) { + return e; + } + } + throw GraalInternalError.shouldNotReachHere("unknown enum value " + value); + } + } + + /** + * Returns the {@link Tag} stored in the LayoutData header. * - * @return An integer >= 0 or -1 if not supported. + * @return tag stored in the LayoutData header */ - int getTag(); + Tag getTag(); /** * Returns the BCI stored in the LayoutData header. diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Wed Mar 26 20:44:11 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -53,10 +53,6 @@ private final HotSpotResolvedObjectType holder; private final HotSpotConstantPool constantPool; private final HotSpotSignature signature; - private boolean callerSensitive; - private boolean forceInline; - private boolean dontInline; - private boolean ignoredBySecurityStackWalk; private HotSpotMethodData methodData; private byte[] code; private SpeculationLog speculationLog; @@ -109,8 +105,6 @@ final int signatureIndex = unsafe.getChar(constMethod + config.constMethodSignatureIndexOffset); this.signature = (HotSpotSignature) constantPool.lookupSignature(signatureIndex); - - runtime().getCompilerToVM().initializeMethod(metaspaceMethod, this); } /** @@ -139,11 +133,20 @@ } /** + * Returns this method's flags ({@code Method::_flags}). + * + * @return flags of this method + */ + private int getFlags() { + return unsafe.getByte(metaspaceMethod + runtime().getConfig().methodFlagsOffset); + } + + /** * Returns this method's constant method flags ({@code ConstMethod::_flags}). * * @return flags of this method's ConstMethod */ - private long getConstMethodFlags() { + private int getConstMethodFlags() { return unsafe.getChar(getConstMethod() + runtime().getConfig().constMethodFlagsOffset); } @@ -169,8 +172,7 @@ * modifiers as well as the HotSpot internal modifiers. */ public int getAllModifiers() { - HotSpotVMConfig config = runtime().getConfig(); - return unsafe.getInt(metaspaceMethod + config.methodAccessFlagsOffset); + return unsafe.getInt(metaspaceMethod + runtime().getConfig().methodAccessFlagsOffset); } @Override @@ -245,19 +247,36 @@ } /** - * Returns true if this method has a CallerSensitive annotation. + * Returns true if this method has a {@code CallerSensitive} annotation. * * @return true if CallerSensitive annotation present, false otherwise */ public boolean isCallerSensitive() { - return callerSensitive; + return (getFlags() & runtime().getConfig().methodFlagsCallerSensitive) != 0; + } + + /** + * Returns true if this method has a {@code ForceInline} annotation. + * + * @return true if ForceInline annotation present, false otherwise + */ + public boolean isForceInline() { + return (getFlags() & runtime().getConfig().methodFlagsForceInline) != 0; + } + + /** + * Returns true if this method has a {@code DontInline} annotation. + * + * @return true if DontInline annotation present, false otherwise + */ + public boolean isDontInline() { + return (getFlags() & runtime().getConfig().methodFlagsDontInline) != 0; } /** * Manually adds a DontInline annotation to this method. */ public void setNotInlineable() { - dontInline = true; runtime().getCompilerToVM().doNotInlineOrCompile(metaspaceMethod); } @@ -268,7 +287,7 @@ * @return true if special method ignored by security stack walks, false otherwise */ public boolean ignoredBySecurityStackWalk() { - return ignoredBySecurityStackWalk; + return runtime().getCompilerToVM().methodIsIgnoredBySecurityStackWalk(metaspaceMethod); } public boolean hasBalancedMonitors() { @@ -502,7 +521,7 @@ @Override public boolean canBeInlined() { - if (dontInline) { + if (isDontInline()) { return false; } return runtime().getCompilerToVM().canInlineMethod(metaspaceMethod); @@ -510,7 +529,7 @@ @Override public boolean shouldBeInlined() { - if (forceInline) { + if (isForceInline()) { return true; } return runtime().getCompilerToVM().shouldInlineMethod(metaspaceMethod); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -22,18 +22,17 @@ */ package com.oracle.graal.hotspot.nodes; -import static com.oracle.graal.graph.UnsafeAccess.*; - -import com.oracle.graal.nodes.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.target.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.word.*; /** - * Converts a compile-time constant Java string into a malloc'ed C string. The malloc'ed string is - * never reclaimed so this should only be used for strings in permanent code such as compiled stubs. + * Converts a compile-time constant Java string into a C string installed with the generated code. */ -public final class CStringNode extends FloatingNode implements Lowerable { +public final class CStringNode extends FloatingNode implements LIRGenLowerable { private final String string; @@ -42,16 +41,29 @@ this.string = string; } - @Override - public void lower(LoweringTool tool) { - byte[] formatBytes = string.getBytes(); - long cstring = unsafe.allocateMemory(formatBytes.length + 1); - for (int i = 0; i < formatBytes.length; i++) { - unsafe.putByte(cstring + i, formatBytes[i]); + public void generate(NodeLIRGenerator gen) { + gen.setResult(this, emitCString(gen, string)); + } + + public static AllocatableValue emitCString(NodeLIRGeneratorTool gen, String value) { + AllocatableValue dst = gen.getLIRGeneratorTool().newVariable(gen.getLIRGeneratorTool().target().wordKind); + gen.getLIRGeneratorTool().emitData(dst, toCString(value)); + return dst; + } + + /** + * Converts a string to a null terminated byte array of ASCII characters. + * + * @param s a String that must only contain ASCII characters + */ + public static byte[] toCString(String s) { + byte[] bytes = new byte[s.length() + 1]; + for (int i = 0; i < s.length(); i++) { + assert s.charAt(i) < 128 : "non-ascii string: " + s; + bytes[i] = (byte) s.charAt(i); } - unsafe.putByte(cstring + formatBytes.length, (byte) 0); - ConstantNode replacement = ConstantNode.forLong(cstring, graph()); - graph().replaceFloating(this, replacement); + bytes[s.length()] = 0; + return bytes; } @NodeIntrinsic(setStampFromReturnType = true) diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrier.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrier.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrier.java Wed Mar 26 20:44:11 2014 +0100 @@ -25,7 +25,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -public class G1PreWriteBarrier extends WriteBarrier implements DeoptimizingNode { +public class G1PreWriteBarrier extends WriteBarrier implements DeoptimizingNode.DeoptBefore { @Input private FrameState deoptimizationState; private final boolean nullCheck; @@ -55,17 +55,13 @@ } @Override - public FrameState getDeoptimizationState() { + public FrameState stateBefore() { return deoptimizationState; } @Override - public void setDeoptimizationState(FrameState state) { + public void setStateBefore(FrameState state) { updateUsages(deoptimizationState, state); deoptimizationState = state; } - - public FrameState getState() { - return deoptimizationState; - } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -22,6 +22,9 @@ */ package com.oracle.graal.hotspot.nodes; +import static com.oracle.graal.api.meta.MetaUtil.*; +import static com.oracle.graal.hotspot.nodes.CStringNode.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; @@ -47,14 +50,22 @@ @Override public void generate(NodeLIRGeneratorTool gen) { - String whereString = "in compiled code for " + graph(); - - // As these strings will end up embedded as oops in the code, they - // must be interned or else they will cause the nmethod to be unloaded - // (nmethods are a) weak GC roots and b) unloaded if any of their - // embedded oops become unreachable). - Constant whereArg = Constant.forObject(whereString.intern()); - Constant formatArg = Constant.forObject(format.intern()); + String whereString; + if (stateBefore() != null) { + String nl = CodeUtil.NEW_LINE; + StringBuilder sb = new StringBuilder("in compiled code associated with frame state:"); + FrameState fs = stateBefore(); + while (fs != null) { + MetaUtil.appendLocation(sb.append(nl).append("\t"), fs.method(), fs.bci); + fs = fs.outerFrameState(); + } + whereString = sb.toString(); + } else { + ResolvedJavaMethod method = graph().method(); + whereString = "in compiled code for " + (method == null ? graph().toString() : format("%H.%n(%p)", method)); + } + Value whereArg = emitCString(gen, whereString); + Value formatArg = emitCString(gen, format); ForeignCallLinkage linkage = gen.getLIRGeneratorTool().getForeignCalls().lookupForeignCall(VMErrorNode.VM_ERROR); gen.getLIRGeneratorTool().emitForeignCall(linkage, null, whereArg, formatArg, gen.operand(value)); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Wed Mar 26 20:44:11 2014 +0100 @@ -68,9 +68,9 @@ protected static void addG1PreWriteBarrier(FixedAccessNode node, ValueNode object, ValueNode value, LocationNode location, boolean doLoad, boolean nullCheck, StructuredGraph graph) { G1PreWriteBarrier preBarrier = graph.add(new G1PreWriteBarrier(object, value, location, doLoad, nullCheck)); - preBarrier.setDeoptimizationState(node.getDeoptimizationState()); + preBarrier.setStateBefore(node.stateBefore()); node.setNullCheck(false); - node.setDeoptimizationState(null); + node.setStateBefore(null); graph.addBeforeFixed(node, preBarrier); } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Wed Mar 26 20:44:11 2014 +0100 @@ -27,7 +27,6 @@ import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.Options.*; import static com.oracle.graal.nodes.PiArrayNode.*; -import static com.oracle.graal.nodes.PiNode.*; import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; import static com.oracle.graal.phases.GraalOptions.*; import static com.oracle.graal.replacements.SnippetTemplate.*; @@ -251,7 +250,7 @@ * Computes the size of the memory chunk allocated for an array. This size accounts for the * array header size, boy size and any padding after the last element to satisfy object * alignment requirements. - * + * * @param length the number of elements in the array * @param alignment the object alignment requirement * @param headerSize the size of the array header @@ -285,7 +284,7 @@ /** * Zero uninitialized memory in a newly allocated object, unrolling as necessary and ensuring * that stores are aligned. - * + * * @param size number of bytes to zero * @param memory beginning of object which is being zeroed * @param constantSize is @ size} known to be constant in the snippet diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Wed Mar 26 20:44:11 2014 +0100 @@ -652,7 +652,7 @@ } sb.append(n); } - Debug.log(sb.toString()); + Debug.log("%s", sb); } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Mar 26 20:44:11 2014 +0100 @@ -140,7 +140,7 @@ * the jump. When the block is seen the second time, a {@link MergeNode} is created to * correctly merge the now two different predecessor states. */ - private static class BlockPlaceholderNode extends FixedWithNextNode { + protected static class BlockPlaceholderNode extends FixedWithNextNode { /* * Cannot be explicitly declared as a Node type since it is not an input; would cause @@ -240,6 +240,7 @@ } frameState.clearNonLiveLocals(blockMap.startBlock, liveness, true); ((StateSplit) lastInstr).setStateAfter(frameState.create(0)); + finishPrepare(lastInstr); if (graphBuilderConfig.eagerInfopointMode()) { InfopointNode ipn = currentGraph.add(new InfopointNode(InfopointReason.METHOD_START, frameState.create(0))); @@ -287,6 +288,15 @@ indent.outdent(); } + /** + * A hook for derived classes to modify the graph start instruction or append new + * instructions to it. + * + * @param startInstr The start instruction of the graph. + */ + protected void finishPrepare(FixedWithNextNode startInstr) { + } + private BciBlock unwindBlock(int bci) { if (unwindBlock == null) { unwindBlock = new ExceptionDispatchBlock(); @@ -306,6 +316,10 @@ return stream.currentBCI(); } + private void loadLocal(int index, Kind kind) { + frameState.push(kind, frameState.loadLocal(index)); + } + private void storeLocal(Kind kind, int index) { ValueNode value; if (kind == Kind.Object) { @@ -452,7 +466,7 @@ dispatchState.setRethrowException(true); } FixedNode target = createTarget(dispatchBlock, dispatchState); - dispatchBegin.setNext(target); + finishInstruction(dispatchBegin, dispatchState).setNext(target); return dispatchBegin; } @@ -1110,7 +1124,7 @@ private void genInvokeInterface(JavaMethod target) { if (target instanceof ResolvedJavaMethod) { ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(true), target.getSignature().getParameterCount(true)); - genInvokeIndirect(InvokeKind.Interface, (ResolvedJavaMethod) target, args); + appendInvoke(InvokeKind.Interface, (ResolvedJavaMethod) target, args); } else { handleUnresolvedInvoke(target, InvokeKind.Interface); } @@ -1145,7 +1159,7 @@ } ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(hasReceiver), target.getSignature().getParameterCount(hasReceiver)); if (hasReceiver) { - genInvokeIndirect(InvokeKind.Virtual, (ResolvedJavaMethod) target, args); + appendInvoke(InvokeKind.Virtual, (ResolvedJavaMethod) target, args); } else { appendInvoke(InvokeKind.Static, (ResolvedJavaMethod) target, args); } @@ -1160,47 +1174,12 @@ assert target != null; assert target.getSignature() != null; ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(true), target.getSignature().getParameterCount(true)); - invokeDirect((ResolvedJavaMethod) target, args); + appendInvoke(InvokeKind.Special, (ResolvedJavaMethod) target, args); } else { handleUnresolvedInvoke(target, InvokeKind.Special); } } - private void genInvokeIndirect(InvokeKind invokeKind, ResolvedJavaMethod target, ValueNode[] args) { - ValueNode receiver = args[0]; - // attempt to devirtualize the call - ResolvedJavaType klass = target.getDeclaringClass(); - - // 0. check for trivial cases - if (target.canBeStaticallyBound()) { - // check for trivial cases (e.g. final methods, nonvirtual methods) - invokeDirect(target, args); - return; - } - // 1. check if the exact type of the receiver can be determined - ResolvedJavaType exact = klass.asExactType(); - if (exact == null && receiver.stamp() instanceof ObjectStamp) { - ObjectStamp receiverStamp = (ObjectStamp) receiver.stamp(); - if (receiverStamp.isExactType()) { - exact = receiverStamp.type(); - } - } - if (exact != null) { - // either the holder class is exact, or the receiver object has an exact type - ResolvedJavaMethod exactMethod = exact.resolveMethod(target); - if (exactMethod != null) { - invokeDirect(exactMethod, args); - return; - } - } - // devirtualization failed, produce an actual invokevirtual - appendInvoke(invokeKind, target, args); - } - - private void invokeDirect(ResolvedJavaMethod target, ValueNode[] args) { - appendInvoke(InvokeKind.Special, target, args); - } - private void appendInvoke(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args) { Kind resultType = targetMethod.getSignature().getReturnKind(); if (DeoptALot.getValue()) { @@ -1787,6 +1766,8 @@ assert lastInstr.next() == null : "instructions already appended at block " + block; Debug.log(" frameState: %s", frameState); + lastInstr = finishInstruction(lastInstr, frameState); + int endBCI = stream.endBCI(); stream.setBCI(block.startBci); @@ -1836,6 +1817,7 @@ } } } + lastInstr = finishInstruction(lastInstr, frameState); if (bci < endBCI) { if (bci > block.endBci) { assert !block.getSuccessor(0).isExceptionEntry; @@ -1848,6 +1830,17 @@ } } + /** + * A hook for derived classes to modify the last instruction or add other instructions. + * + * @param instr The last instruction (= fixed node) which was added. + * @param state The current frame state. + * @Returns Returns the (new) last instruction. + */ + protected FixedWithNextNode finishInstruction(FixedWithNextNode instr, HIRFrameStateBuilder state) { + return instr; + } + private final int traceLevel = Options.TraceBytecodeParserLevel.getValue(); private void traceState() { @@ -2096,7 +2089,7 @@ if (!currentBlock.jsrScope.isEmpty()) { sb.append(' ').append(currentBlock.jsrScope); } - Debug.log(sb.toString()); + Debug.log("%s", sb); } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/except/BC_getfield1.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/except/BC_getfield1.java Wed Mar 26 20:44:11 2014 +0100 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2007, 2012, 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.oracle.graal.jtt.except; + +import com.oracle.graal.jtt.*; + +import org.junit.*; + +public class BC_getfield1 extends JTTTest { + + private int field = 13; + + public static void test(BC_getfield1 arg) { + @SuppressWarnings("unused") + int i = arg.field; + } + + @Test + public void run0() throws Throwable { + runTest("test", (Object) null); + } + + @Test + public void run1() throws Throwable { + // tests that the null check isn't removed along with the read + runTest(EMPTY, true, true, "test", (Object) null); + } + + @Test + public void run2() throws Throwable { + runTest("test", new BC_getfield1()); + } + +} diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java Wed Mar 26 20:44:11 2014 +0100 @@ -49,6 +49,7 @@ I2F, I2D, L2F, L2D, MOV_I2F, MOV_L2D, MOV_F2I, MOV_D2L, + MOV_B2UI, MOV_B2UL, // Zero extending byte loads /* * Converts a float/double to an int/long. The result of the conversion does not comply with Java semantics @@ -102,6 +103,32 @@ } /** + * Unary operation with separate memory source and destination operand. + */ + public static class Unary2MemoryOp extends AMD64LIRInstruction { + + @Opcode private final AMD64Arithmetic opcode; + @Def({REG}) protected AllocatableValue result; + @Use({COMPOSITE}) protected AMD64AddressValue x; + @State protected LIRFrameState state; + + public Unary2MemoryOp(AMD64Arithmetic opcode, AllocatableValue result, AMD64AddressValue x, LIRFrameState state) { + this.opcode = opcode; + this.result = result; + this.x = x; + this.state = state; + } + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + if (state != null) { + crb.recordImplicitException(masm.position(), state); + } + emit(crb, masm, opcode, result, x, null); + } + } + + /** * Binary operation with two operands. The first source operand is combined with the * destination. The second source operand may be a stack slot. */ @@ -135,6 +162,45 @@ /** * Binary operation with two operands. The first source operand is combined with the + * destination. The second source operand may be a stack slot. + */ + public static class BinaryMemory extends AMD64LIRInstruction { + + @Opcode private final AMD64Arithmetic opcode; + @Def({REG, HINT}) protected AllocatableValue result; + @Use({REG}) protected AllocatableValue x; + protected final Kind kind; + @Alive({COMPOSITE}) protected AMD64AddressValue location; + @State protected LIRFrameState state; + + public BinaryMemory(AMD64Arithmetic opcode, Kind kind, AllocatableValue result, AllocatableValue x, AMD64AddressValue location, LIRFrameState state) { + this.opcode = opcode; + this.result = result; + this.x = x; + this.location = location; + this.kind = kind; + this.state = state; + } + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + AMD64Move.move(crb, masm, result, x); + if (state != null) { + crb.recordImplicitException(masm.position(), state); + } + emit(crb, masm, opcode, result, location, null); + } + + @Override + public void verify() { + super.verify(); + assert differentRegisters(result, location) || sameRegister(x, location); + // verifyKind(opcode, result, x, location); + } + } + + /** + * Binary operation with two operands. The first source operand is combined with the * destination. The second source operand must be a register. */ public static class BinaryRegReg extends AMD64LIRInstruction { @@ -688,7 +754,8 @@ default: throw GraalInternalError.shouldNotReachHere(); } - } else { + } else if (isStackSlot(src)) { + switch (opcode) { case IADD: masm.addl(asIntReg(dst), (AMD64Address) crb.asIntAddr(src)); @@ -819,6 +886,143 @@ default: throw GraalInternalError.shouldNotReachHere(); } + } else { + switch (opcode) { + case IADD: + masm.addl(asIntReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case ISUB: + masm.subl(asIntReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case IAND: + masm.andl(asIntReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case IMUL: + masm.imull(asIntReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case IOR: + masm.orl(asIntReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case IXOR: + masm.xorl(asIntReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + + case LADD: + masm.addq(asLongReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case LSUB: + masm.subq(asLongReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case LMUL: + masm.imulq(asLongReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case LAND: + masm.andq(asLongReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case LOR: + masm.orq(asLongReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case LXOR: + masm.xorq(asLongReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + + case FADD: + masm.addss(asFloatReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case FSUB: + masm.subss(asFloatReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case FMUL: + masm.mulss(asFloatReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case FDIV: + masm.divss(asFloatReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + + case DADD: + masm.addsd(asDoubleReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case DSUB: + masm.subsd(asDoubleReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case DMUL: + masm.mulsd(asDoubleReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case DDIV: + masm.divsd(asDoubleReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + + case SQRT: + masm.sqrtsd(asDoubleReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + + case B2I: + masm.movsbl(asIntReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case S2I: + masm.movswl(asIntReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case B2L: + masm.movsbq(asLongReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case S2L: + masm.movswq(asLongReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case I2L: + masm.movslq(asLongReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case F2D: + masm.cvtss2sd(asDoubleReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case D2F: + masm.cvtsd2ss(asFloatReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case I2F: + masm.cvtsi2ssl(asFloatReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case I2D: + masm.cvtsi2sdl(asDoubleReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case L2F: + masm.cvtsi2ssq(asFloatReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case L2D: + masm.cvtsi2sdq(asDoubleReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case F2I: + masm.cvttss2sil(asIntReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case D2I: + masm.cvttsd2sil(asIntReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case F2L: + masm.cvttss2siq(asLongReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case D2L: + masm.cvttsd2siq(asLongReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case MOV_I2F: + masm.movss(asFloatReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case MOV_L2D: + masm.movsd(asDoubleReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case MOV_F2I: + masm.movl(asIntReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case MOV_D2L: + masm.movq(asLongReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case MOV_B2UI: + masm.movzbl(asIntReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + case MOV_B2UL: + masm.movzbl(asLongReg(dst), ((AMD64AddressValue) src).toAddress()); + break; + + default: + throw GraalInternalError.shouldNotReachHere(); + } } if (info != null) { diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java Wed Mar 26 20:44:11 2014 +0100 @@ -31,7 +31,6 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; -// @formatter:off public enum AMD64Compare { ICMP, LCMP, ACMP, FCMP, DCMP; @@ -54,57 +53,152 @@ @Override protected void verify() { super.verify(); - assert (name().startsWith("I") && x.getKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) - || (name().startsWith("L") && x.getKind() == Kind.Long && y.getKind() == Kind.Long) - || (name().startsWith("A") && x.getKind() == Kind.Object && y.getKind() == Kind.Object) - || (name().startsWith("F") && x.getKind() == Kind.Float && y.getKind() == Kind.Float) - || (name().startsWith("D") && x.getKind() == Kind.Double && y.getKind() == Kind.Double); + assert (name().startsWith("I") && x.getKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) || (name().startsWith("L") && x.getKind() == Kind.Long && y.getKind() == Kind.Long) || + (name().startsWith("A") && x.getKind() == Kind.Object && y.getKind() == Kind.Object) || + (name().startsWith("F") && x.getKind() == Kind.Float && y.getKind() == Kind.Float) || (name().startsWith("D") && x.getKind() == Kind.Double && y.getKind() == Kind.Double); + } + } + + public static class CompareMemoryOp extends AMD64LIRInstruction { + @Opcode private final AMD64Compare opcode; + @Use({REG, COMPOSITE}) protected Value x; + @Use({CONST, COMPOSITE}) protected Value y; + @State protected LIRFrameState state; + + /** + * Compare memory, constant or register, memory. + */ + public CompareMemoryOp(AMD64Compare opcode, Value x, Value y, LIRFrameState state) { + assert (x instanceof AMD64AddressValue && y instanceof Constant) || (x instanceof Variable && y instanceof AMD64AddressValue); + this.opcode = opcode; + this.x = x; + this.y = y; + this.state = state; + } + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + if (state != null) { + crb.recordImplicitException(masm.position(), state); + } + emit(crb, masm, opcode, x, y); + } + + @Override + protected void verify() { + super.verify(); + assert (x instanceof AMD64AddressValue && y instanceof Constant) || (x instanceof Variable && y instanceof AMD64AddressValue); } } public static void emit(CompilationResultBuilder crb, AMD64MacroAssembler masm, AMD64Compare opcode, Value x, Value y) { - if (isRegister(y)) { + if (isRegister(x) && isRegister(y)) { switch (opcode) { - case ICMP: masm.cmpl(asIntReg(x), asIntReg(y)); break; - case LCMP: masm.cmpq(asLongReg(x), asLongReg(y)); break; - case ACMP: masm.cmpptr(asObjectReg(x), asObjectReg(y)); break; - case FCMP: masm.ucomiss(asFloatReg(x), asFloatReg(y)); break; - case DCMP: masm.ucomisd(asDoubleReg(x), asDoubleReg(y)); break; - default: throw GraalInternalError.shouldNotReachHere(); + case ICMP: + masm.cmpl(asIntReg(x), asIntReg(y)); + break; + case LCMP: + masm.cmpq(asLongReg(x), asLongReg(y)); + break; + case ACMP: + masm.cmpptr(asObjectReg(x), asObjectReg(y)); + break; + case FCMP: + masm.ucomiss(asFloatReg(x), asFloatReg(y)); + break; + case DCMP: + masm.ucomisd(asDoubleReg(x), asDoubleReg(y)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); } - } else if (isConstant(y)) { + } else if (isRegister(x) && isConstant(y)) { boolean isZero = ((Constant) y).isDefaultForKind(); switch (opcode) { - case ICMP: if (isZero) { - masm.testl(asIntReg(x), asIntReg(x)); - } else { - masm.cmpl(asIntReg(x), crb.asIntConst(y)); - } - break; - case LCMP: if (isZero) { - masm.testq(asLongReg(x), asLongReg(x)); - } else { - masm.cmpq(asLongReg(x), crb.asIntConst(y)); - } - break; + case ICMP: + if (isZero) { + masm.testl(asIntReg(x), asIntReg(x)); + } else { + masm.cmpl(asIntReg(x), crb.asIntConst(y)); + } + break; + case LCMP: + if (isZero) { + masm.testq(asLongReg(x), asLongReg(x)); + } else { + masm.cmpq(asLongReg(x), crb.asIntConst(y)); + } + break; case ACMP: if (isZero) { - masm.testq(asObjectReg(x), asObjectReg(x)); break; + masm.testq(asObjectReg(x), asObjectReg(x)); + break; } else { throw GraalInternalError.shouldNotReachHere("Only null object constants are allowed in comparisons"); } - case FCMP: masm.ucomiss(asFloatReg(x), (AMD64Address) crb.asFloatConstRef(y)); break; - case DCMP: masm.ucomisd(asDoubleReg(x), (AMD64Address) crb.asDoubleConstRef(y)); break; - default: throw GraalInternalError.shouldNotReachHere(); + case FCMP: + masm.ucomiss(asFloatReg(x), (AMD64Address) crb.asFloatConstRef(y)); + break; + case DCMP: + masm.ucomisd(asDoubleReg(x), (AMD64Address) crb.asDoubleConstRef(y)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); } - } else { + } else if (isRegister(x) && isStackSlot(y)) { + switch (opcode) { + case ICMP: + masm.cmpl(asIntReg(x), (AMD64Address) crb.asIntAddr(y)); + break; + case LCMP: + masm.cmpq(asLongReg(x), (AMD64Address) crb.asLongAddr(y)); + break; + case ACMP: + masm.cmpptr(asObjectReg(x), (AMD64Address) crb.asObjectAddr(y)); + break; + case FCMP: + masm.ucomiss(asFloatReg(x), (AMD64Address) crb.asFloatAddr(y)); + break; + case DCMP: + masm.ucomisd(asDoubleReg(x), (AMD64Address) crb.asDoubleAddr(y)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } else if (isRegister(x) && y instanceof AMD64AddressValue) { switch (opcode) { - case ICMP: masm.cmpl(asIntReg(x), (AMD64Address) crb.asIntAddr(y)); break; - case LCMP: masm.cmpq(asLongReg(x), (AMD64Address) crb.asLongAddr(y)); break; - case ACMP: masm.cmpptr(asObjectReg(x), (AMD64Address) crb.asObjectAddr(y)); break; - case FCMP: masm.ucomiss(asFloatReg(x), (AMD64Address) crb.asFloatAddr(y)); break; - case DCMP: masm.ucomisd(asDoubleReg(x), (AMD64Address) crb.asDoubleAddr(y)); break; - default: throw GraalInternalError.shouldNotReachHere(); + case ICMP: + masm.cmpl(asIntReg(x), ((AMD64AddressValue) y).toAddress()); + break; + case LCMP: + masm.cmpq(asLongReg(x), ((AMD64AddressValue) y).toAddress()); + break; + case ACMP: + masm.cmpptr(asObjectReg(x), ((AMD64AddressValue) y).toAddress()); + break; + case FCMP: + masm.ucomiss(asFloatReg(x), ((AMD64AddressValue) y).toAddress()); + break; + case DCMP: + masm.ucomisd(asDoubleReg(x), ((AMD64AddressValue) y).toAddress()); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } else if (x instanceof AMD64AddressValue && isConstant(y)) { + switch (opcode) { + case ICMP: + masm.cmpl(((AMD64AddressValue) x).toAddress(), crb.asIntConst(y)); + break; + case LCMP: + if (crb.asLongConst(y) == (int) crb.asLongConst(y)) { + masm.cmpq(((AMD64AddressValue) x).toAddress(), (int) crb.asLongConst(y)); + } else { + throw GraalInternalError.shouldNotReachHere(); + } + break; + default: + throw GraalInternalError.shouldNotReachHere(); } } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Wed Mar 26 20:44:11 2014 +0100 @@ -29,6 +29,7 @@ import com.oracle.graal.amd64.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CompilationResult.RawData; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.amd64.*; @@ -171,6 +172,38 @@ } } + public static class ZeroExtendLoadOp extends MemOp { + + @Def({REG}) protected AllocatableValue result; + + public ZeroExtendLoadOp(Kind kind, AllocatableValue result, AMD64AddressValue address, LIRFrameState state) { + super(kind, address, state); + this.result = result; + } + + @Override + public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + switch (kind) { + case Boolean: + case Byte: + masm.movzbl(asRegister(result), address.toAddress()); + break; + case Char: + case Short: + masm.movzwl(asRegister(result), address.toAddress()); + break; + case Int: + masm.movl(asRegister(result), address.toAddress()); + break; + case Long: + masm.movq(asRegister(result), address.toAddress()); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } + public static class StoreOp extends MemOp { @Use({REG}) protected AllocatableValue input; @@ -277,6 +310,23 @@ } } + public static class LeaDataOp extends AMD64LIRInstruction { + + @Def({REG}) protected AllocatableValue result; + private final byte[] data; + + public LeaDataOp(AllocatableValue result, byte[] data) { + this.result = result; + this.data = data; + } + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + RawData rawData = new RawData(data, 16); + masm.leaq(asRegister(result), (AMD64Address) crb.recordDataReferenceInCode(rawData)); + } + } + public static class StackLeaOp extends AMD64LIRInstruction { @Def({REG}) protected AllocatableValue result; diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64TestMemoryOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64TestMemoryOp.java Wed Mar 26 20:44:11 2014 +0100 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2011, 2012, 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.oracle.graal.lir.amd64; + +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; + +public class AMD64TestMemoryOp extends AMD64LIRInstruction { + + @Use({COMPOSITE}) protected AMD64AddressValue x; + @Use({REG, CONST}) protected Value y; + @State protected LIRFrameState state; + + public AMD64TestMemoryOp(AMD64AddressValue x, Value y, LIRFrameState state) { + this.x = x; + this.y = y; + this.state = state; + } + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + if (state != null) { + crb.recordImplicitException(masm.position(), state); + } + emit(crb, masm, x, y); + } + + @Override + protected void verify() { + super.verify(); + // Can't check the kind of an address so just check the other input + assert (x.getKind() == Kind.Int || x.getKind() == Kind.Long) : x + " " + y; + } + + public static void emit(CompilationResultBuilder crb, AMD64MacroAssembler masm, Value x, Value y) { + if (isRegister(y)) { + switch (y.getKind()) { + case Int: + masm.testl(asIntReg(y), ((AMD64AddressValue) x).toAddress()); + break; + case Long: + masm.testq(asLongReg(y), ((AMD64AddressValue) x).toAddress()); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } else if (isConstant(y)) { + switch (y.getKind()) { + case Int: + masm.testl(((AMD64AddressValue) x).toAddress(), crb.asIntConst(y)); + break; + case Long: + masm.testq(((AMD64AddressValue) x).toAddress(), crb.asIntConst(y)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } else { + throw GraalInternalError.shouldNotReachHere(); + } + } +} diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Wed Mar 26 20:44:11 2014 +0100 @@ -23,13 +23,32 @@ package com.oracle.graal.lir.sparc; import static com.oracle.graal.api.code.ValueUtil.*; -import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import static com.oracle.graal.sparc.SPARC.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.asm.sparc.SPARCAssembler.Add; +import com.oracle.graal.asm.sparc.SPARCAssembler.Lddf; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldf; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsb; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsh; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsw; +import com.oracle.graal.asm.sparc.SPARCAssembler.Lduh; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx; +import com.oracle.graal.asm.sparc.SPARCAssembler.Membar; +import com.oracle.graal.asm.sparc.SPARCAssembler.Rdpc; +import com.oracle.graal.asm.sparc.SPARCAssembler.Stb; +import com.oracle.graal.asm.sparc.SPARCAssembler.Sth; +import com.oracle.graal.asm.sparc.SPARCAssembler.Stw; +import com.oracle.graal.asm.sparc.SPARCAssembler.Stx; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cas; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Casx; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Clr; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setuw; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx; import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.ImplicitNullCheck; diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java Wed Mar 26 20:44:11 2014 +0100 @@ -63,7 +63,7 @@ } private void findDerived(Collection bivs) { - Queue scanQueue = new LinkedList(bivs); + Queue scanQueue = new LinkedList<>(bivs); while (!scanQueue.isEmpty()) { InductionVariable baseIv = scanQueue.remove(); ValueNode baseIvNode = baseIv.valueNode(); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java Wed Mar 26 20:44:11 2014 +0100 @@ -141,7 +141,7 @@ BinaryNode result = BinaryNode.reassociate(binary, invariant); if (result != binary) { if (Debug.isLogEnabled()) { - Debug.log(MetaUtil.format("%H::%n", Debug.contextLookup(ResolvedJavaMethod.class)) + " : Reassociated %s into %s", binary, result); + Debug.log("%s : Reassociated %s into %s", MetaUtil.format("%H::%n", graph.method()), binary, result); } graph.replaceFloating(binary, result); } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java Wed Mar 26 20:44:11 2014 +0100 @@ -84,6 +84,6 @@ } } sb.append("]"); - Debug.log(sb.toString()); + Debug.log("%s", sb); } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractDeoptimizeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractDeoptimizeNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractDeoptimizeNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -30,11 +30,9 @@ * This node represents an unconditional explicit request for immediate deoptimization. * * After this node, execution will continue using a fallback execution engine (such as an - * interpreter) at the position described by the {@link #getDeoptimizationState() deoptimization - * state}. - * + * interpreter) at the position described by the {@link #stateBefore() deoptimization state}. */ -public abstract class AbstractDeoptimizeNode extends ControlSinkNode implements IterableNodeType, DeoptimizingNode { +public abstract class AbstractDeoptimizeNode extends ControlSinkNode implements IterableNodeType, DeoptimizingNode.DeoptBefore { @Input private FrameState deoptState; @@ -48,20 +46,16 @@ } @Override - public FrameState getDeoptimizationState() { + public FrameState stateBefore() { return deoptState; } @Override - public void setDeoptimizationState(FrameState f) { + public void setStateBefore(FrameState f) { updateUsages(deoptState, f); deoptState = f; } - public FrameState getState() { - return deoptState; - } - public abstract ValueNode getActionAndReason(MetaAccessProvider metaAccess); public abstract ValueNode getSpeculation(MetaAccessProvider metaAccess); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -86,7 +86,7 @@ FixedNode next = next(); setNext(null); DeoptimizeNode deopt = graph().add(new DeoptimizeNode(action, reason)); - deopt.setDeoptimizationState(getDeoptimizationState()); + deopt.setStateBefore(stateBefore()); IfNode ifNode; AbstractBeginNode noDeoptSuccessor; if (negated) { diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractStateSplit.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractStateSplit.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractStateSplit.java Wed Mar 26 20:44:11 2014 +0100 @@ -41,10 +41,6 @@ stateAfter = x; } - public FrameState getState() { - return stateAfter(); - } - public boolean hasSideEffect() { return true; } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingFixedWithNextNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingFixedWithNextNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingFixedWithNextNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -24,7 +24,7 @@ import com.oracle.graal.nodes.type.*; -public abstract class DeoptimizingFixedWithNextNode extends FixedWithNextNode implements DeoptimizingNode { +public abstract class DeoptimizingFixedWithNextNode extends FixedWithNextNode implements DeoptimizingNode.DeoptBefore { @Input(notDataflow = true) private FrameState deoptState; @@ -33,17 +33,13 @@ } @Override - public FrameState getDeoptimizationState() { + public FrameState stateBefore() { return deoptState; } @Override - public void setDeoptimizationState(FrameState f) { + public void setStateBefore(FrameState f) { updateUsages(deoptState, f); deoptState = f; } - - public FrameState getState() { - return deoptState; - } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -35,14 +35,46 @@ boolean canDeoptimize(); /** - * Gets the deoptimization information associated with this node if any. + * Interface for nodes that need a {@link FrameState} for deoptimizing to a point before their + * execution. */ - FrameState getDeoptimizationState(); + public interface DeoptBefore extends DeoptimizingNode { + + /** + * Sets the {@link FrameState} describing the program state before the execution of this + * node. + */ + void setStateBefore(FrameState state); + + FrameState stateBefore(); + } + + /** + * Interface for nodes that need a {@link FrameState} for deoptimizing to a point after their + * execution. + */ + public interface DeoptAfter extends DeoptimizingNode, StateSplit { + } /** - * Sets the deoptimization information associated with this node. - * - * @param state the {@link FrameState} which represents the deoptimization information + * Interface for nodes that need a special {@link FrameState} for deoptimizing during their + * execution (e.g. {@link Invoke}). */ - void setDeoptimizationState(FrameState state); + public interface DeoptDuring extends DeoptimizingNode, StateSplit { + + FrameState stateDuring(); + + /** + * Sets the {@link FrameState} describing the program state during the execution of this + * node. + */ + void setStateDuring(FrameState state); + + /** + * Compute the {@link FrameState} describing the program state during the execution of this + * node from an input {@link FrameState} describing the program state after finishing the + * execution of this node. + */ + void computeStateDuring(FrameState stateAfter); + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -66,7 +66,7 @@ DeoptimizeNode newDeopt = graph().add( new DeoptimizeNode(tool.getMetaAccess().decodeDeoptAction(constant), tool.getMetaAccess().decodeDeoptReason(constant), tool.getMetaAccess().decodeDebugId(constant), speculationConstant)); - newDeopt.setDeoptimizationState(getDeoptimizationState()); + newDeopt.setStateBefore(stateBefore()); return newDeopt; } return this; diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -52,7 +52,7 @@ } DeoptimizeNode deopt = graph().add(new DeoptimizeNode(getAction(), getReason())); - deopt.setDeoptimizationState(getDeoptimizationState()); + deopt.setStateBefore(stateBefore()); setNext(deopt); } this.replaceAtUsages(null); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -33,6 +33,7 @@ import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -42,7 +43,7 @@ * The {@code IfNode} represents a branch that can go one of two directions depending on the outcome * of a comparison. */ -public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable { +public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable, MemoryArithmeticLIRLowerable { @Successor private AbstractBeginNode trueSuccessor; @Successor private AbstractBeginNode falseSuccessor; @@ -131,6 +132,11 @@ } @Override + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + return gen.emitIfMemory(this, access); + } + + @Override public boolean verify() { assertTrue(condition() != null, "missing condition"); assertTrue(trueSuccessor() != null, "missing trueSuccessor"); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -51,7 +51,7 @@ @Override public boolean verify() { - return getState() != null && super.verify(); + return state != null && super.verify(); } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java Wed Mar 26 20:44:11 2014 +0100 @@ -26,7 +26,7 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -public interface Invoke extends StateSplit, Lowerable, DeoptimizingNode, GuardedNode { +public interface Invoke extends StateSplit, Lowerable, DeoptimizingNode.DeoptDuring, GuardedNode { FixedNode next(); @@ -38,10 +38,6 @@ FixedNode asNode(); - FrameState stateDuring(); - - FrameState stateAfter(); - Node predecessor(); void intrinsify(Node node); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -133,17 +133,6 @@ } @Override - public FrameState stateDuring() { - FrameState stateAfter = stateAfter(); - if (stateAfter == null) { - return null; - } - FrameState stateDuring = stateAfter.duplicateModified(bci(), stateAfter.rethrowException(), getKind()); - stateDuring.setDuringCall(true); - return stateDuring; - } - - @Override public void intrinsify(Node node) { assert !(node instanceof ValueNode) || (((ValueNode) node).getKind() == Kind.Void) == (getKind() == Kind.Void); CallTargetNode call = callTarget; @@ -174,18 +163,21 @@ } @Override - public FrameState getDeoptimizationState() { - if (deoptState == null) { - FrameState stateDuring = stateDuring(); - updateUsages(deoptState, stateDuring); - deoptState = stateDuring; - } + public FrameState stateDuring() { return deoptState; } @Override - public void setDeoptimizationState(FrameState f) { - throw new IllegalStateException("Cannot set deoptimization state " + f + " for invoke " + this); + public void setStateDuring(FrameState stateDuring) { + updateUsages(deoptState, stateDuring); + deoptState = stateDuring; + } + + @Override + public void computeStateDuring(FrameState stateAfter) { + FrameState stateDuring = stateAfter.duplicateModified(bci(), stateAfter.rethrowException(), getKind()); + stateDuring.setDuringCall(true); + setStateDuring(stateDuring); } @Override @@ -198,14 +190,4 @@ updateUsages(this.guard == null ? null : this.guard.asNode(), guard == null ? null : guard.asNode()); this.guard = guard; } - - @Override - public FrameState getState() { - if (deoptState != null) { - assert stateAfter() == null; - return deoptState; - } else { - return super.getState(); - } - } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -155,13 +155,6 @@ return LocationIdentity.ANY_LOCATION; } - public FrameState stateDuring() { - FrameState tempStateAfter = stateAfter(); - FrameState stateDuring = tempStateAfter.duplicateModified(bci(), tempStateAfter.rethrowException(), getKind()); - stateDuring.setDuringCall(true); - return stateDuring; - } - @Override public Map getDebugProperties(Map map) { Map debugProperties = super.getDebugProperties(map); @@ -219,18 +212,21 @@ } @Override - public FrameState getDeoptimizationState() { - if (deoptState == null) { - FrameState stateDuring = stateDuring(); - updateUsages(deoptState, stateDuring); - deoptState = stateDuring; - } + public FrameState stateDuring() { return deoptState; } @Override - public void setDeoptimizationState(FrameState f) { - throw new IllegalStateException(); + public void setStateDuring(FrameState stateDuring) { + updateUsages(deoptState, stateDuring); + deoptState = stateDuring; + } + + @Override + public void computeStateDuring(FrameState tempStateAfter) { + FrameState stateDuring = tempStateAfter.duplicateModified(bci(), tempStateAfter.rethrowException(), getKind()); + stateDuring.setDuringCall(true); + setStateDuring(stateDuring); } @Override @@ -244,16 +240,6 @@ this.guard = guard; } - @Override - public FrameState getState() { - if (deoptState != null) { - assert stateAfter() == null; - return deoptState; - } else { - return stateAfter(); - } - } - public MemoryCheckpoint asMemoryCheckpoint() { return this; } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -83,4 +84,13 @@ public void generate(NodeLIRGeneratorTool gen) { gen.setResult(this, gen.getLIRGeneratorTool().emitAnd(gen.operand(x()), gen.operand(y()))); } + + @Override + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + Value result = gen.emitAndMemory(x(), y(), access); + if (result != null) { + gen.setResult(this, result); + } + return result != null; + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -29,7 +29,7 @@ /** * The {@code LogicNode} class definition. */ -public abstract class BitLogicNode extends BinaryNode implements ArithmeticLIRLowerable, NarrowableArithmeticNode { +public abstract class BitLogicNode extends BinaryNode implements ArithmeticLIRLowerable, MemoryArithmeticLIRLowerable, NarrowableArithmeticNode { /** * Constructs a new logic operation node. diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; /* TODO (thomaswue/gdub) For high-level optimization purpose the compare node should be a boolean *value* (it is currently only a helper node) @@ -34,7 +35,7 @@ * Compare should probably be made a value (so that it can be canonicalized for example) and in later stages some Compare usage should be transformed * into variants that do not materialize the value (CompareIf, CompareGuard...) */ -public abstract class CompareNode extends LogicNode implements Canonicalizable, LIRLowerable { +public abstract class CompareNode extends LogicNode implements Canonicalizable, LIRLowerable, MemoryArithmeticLIRLowerable { @Input private ValueNode x; @Input private ValueNode y; @@ -192,4 +193,14 @@ return graph.unique(comparison); } + + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + return false; + } + + @Override + public boolean verify() { + assertTrue(x.stamp().isCompatible(y.stamp()), "stamps not compatible: %s, %s", x.stamp(), y.stamp()); + return super.verify(); + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -77,10 +78,19 @@ public static boolean livesLonger(ValueNode after, ValueNode value, NodeLIRGeneratorTool gen) { for (Node usage : value.usages()) { - if (usage != after && usage instanceof ValueNode && gen.operand(((ValueNode) usage)) != null) { + if (usage != after && usage instanceof ValueNode && gen.hasOperand(((ValueNode) usage))) { return true; } } return false; } + + @Override + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + Value result = gen.emitAddMemory(x(), y(), access); + if (result != null) { + gen.setResult(this, result); + } + return result != null; + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatArithmeticNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatArithmeticNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatArithmeticNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -26,7 +26,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -public abstract class FloatArithmeticNode extends BinaryNode implements ArithmeticLIRLowerable { +public abstract class FloatArithmeticNode extends BinaryNode implements ArithmeticLIRLowerable, MemoryArithmeticLIRLowerable { private final boolean isStrictFP; diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -33,7 +34,7 @@ * A {@code FloatConvert} converts between integers and floating point numbers according to Java * semantics. */ -public class FloatConvertNode extends ConvertNode implements Canonicalizable, Lowerable, ArithmeticLIRLowerable { +public class FloatConvertNode extends ConvertNode implements Canonicalizable, Lowerable, ArithmeticLIRLowerable, MemoryArithmeticLIRLowerable { public enum FloatConvert { F2I, D2I, F2L, D2L, I2F, L2F, D2F, I2D, L2D, F2D; @@ -194,4 +195,18 @@ public void generate(NodeLIRGeneratorTool gen) { gen.setResult(this, gen.getLIRGeneratorTool().emitFloatConvert(op, gen.operand(getInput()))); } + + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + Kind kind = access.nullCheckLocation().getValueKind(); + if (kind != kind.getStackKind()) { + // Doesn't work for subword operations + return false; + } + + Value result = gen.emitFloatConvertMemory(getOp(), access); + if (result != null) { + gen.setResult(this, result); + } + return result != null; + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -59,4 +60,13 @@ public void generate(NodeLIRGeneratorTool gen) { gen.setResult(this, gen.getLIRGeneratorTool().emitDiv(gen.operand(x()), gen.operand(y()), null)); } + + @Override + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + Value result = gen.emitDivMemory(x(), y(), access); + if (result != null) { + gen.setResult(this, result); + } + return result != null; + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -69,4 +70,13 @@ } gen.setResult(this, gen.getLIRGeneratorTool().emitMul(op1, op2)); } + + @Override + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + Value result = gen.emitMulMemory(x(), y(), access); + if (result != null) { + gen.setResult(this, result); + } + return result != null; + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -59,4 +60,13 @@ public void generate(NodeLIRGeneratorTool gen) { gen.setResult(this, gen.getLIRGeneratorTool().emitRem(gen.operand(x()), gen.operand(y()), null)); } + + @Override + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + Value result = gen.emitRemMemory(x(), y(), access); + if (result != null) { + gen.setResult(this, result); + } + return result != null; + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -78,4 +79,13 @@ public void generate(NodeLIRGeneratorTool gen) { gen.setResult(this, gen.getLIRGeneratorTool().emitSub(gen.operand(x()), gen.operand(y()))); } + + @Override + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + Value result = gen.emitSubMemory(x(), y(), access); + if (result != null) { + gen.setResult(this, result); + } + return result != null; + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -78,9 +79,6 @@ if (reassociated != this) { return reassociated; } - if (c < 0) { - return IntegerArithmeticNode.sub(graph(), x(), ConstantNode.forIntegerStamp(stamp(), -c, graph())); - } } if (x() instanceof NegateNode) { return IntegerArithmeticNode.sub(graph(), y(), ((NegateNode) x()).x()); @@ -102,4 +100,13 @@ } gen.setResult(this, gen.getLIRGeneratorTool().emitAdd(op1, op2)); } + + @Override + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + Value result = gen.emitAddMemory(x(), y(), access); + if (result != null) { + gen.setResult(this, result); + } + return result != null; + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -26,7 +26,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -public abstract class IntegerArithmeticNode extends BinaryNode implements ArithmeticLIRLowerable { +public abstract class IntegerArithmeticNode extends BinaryNode implements ArithmeticLIRLowerable, MemoryArithmeticLIRLowerable { public IntegerArithmeticNode(Stamp stamp, ValueNode x, ValueNode y) { super(stamp, x, y); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -31,7 +31,7 @@ /** * An {@code IntegerConvert} converts an integer to an integer of different width. */ -public abstract class IntegerConvertNode extends ConvertNode implements ArithmeticLIRLowerable, Canonicalizable { +public abstract class IntegerConvertNode extends ConvertNode implements ArithmeticLIRLowerable, Canonicalizable, MemoryArithmeticLIRLowerable { private final int resultBits; diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -26,6 +26,8 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.util.*; @NodeInfo(shortName = "==") public final class IntegerEqualsNode extends CompareNode { @@ -69,17 +71,67 @@ @Override public Node canonical(CanonicalizerTool tool) { - if (x() == y()) { + if (GraphUtil.unproxify(x()) == GraphUtil.unproxify(y())) { return LogicConstantNode.tautology(graph()); } else if (x().stamp().alwaysDistinct(y().stamp())) { return LogicConstantNode.contradiction(graph()); } - if (x() instanceof AndNode && y().isConstant() && y().asConstant().asLong() == 0) { - return graph().unique(new IntegerTestNode(((AndNode) x()).x(), ((AndNode) x()).y())); - } else if (y() instanceof AndNode && x().isConstant() && x().asConstant().asLong() == 0) { - return graph().unique(new IntegerTestNode(((AndNode) y()).x(), ((AndNode) y()).y())); + ValueNode result = canonicalizeSymmetric(x(), y()); + if (result != null) { + return result; } + + result = canonicalizeSymmetric(y(), x()); + if (result != null) { + return result; + } + return super.canonical(tool); } + + private ValueNode canonicalizeSymmetric(ValueNode x, ValueNode y) { + if (y.isConstant() && y.asConstant().asLong() == 0) { + if (x instanceof AndNode) { + return graph().unique(new IntegerTestNode(((AndNode) x).x(), ((AndNode) x).y())); + } else if (x instanceof LeftShiftNode) { + LeftShiftNode shift = (LeftShiftNode) x; + if (shift.y().isConstant()) { + int mask = shift.getShiftAmountMask(); + int amount = shift.y().asConstant().asInt() & mask; + if (shift.x().getKind() == Kind.Int) { + return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forInt(-1 >>> amount, graph()))); + } else { + assert shift.x().getKind() == Kind.Long; + return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forLong(-1L >>> amount, graph()))); + } + } + } else if (x instanceof RightShiftNode) { + RightShiftNode shift = (RightShiftNode) x; + if (shift.y().isConstant() && ((IntegerStamp) shift.x().stamp()).isPositive()) { + int mask = shift.getShiftAmountMask(); + int amount = shift.y().asConstant().asInt() & mask; + if (shift.x().getKind() == Kind.Int) { + return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forInt(-1 << amount, graph()))); + } else { + assert shift.x().getKind() == Kind.Long; + return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forLong(-1L << amount, graph()))); + } + } + } else if (x instanceof UnsignedRightShiftNode) { + UnsignedRightShiftNode shift = (UnsignedRightShiftNode) x; + if (shift.y().isConstant()) { + int mask = shift.getShiftAmountMask(); + int amount = shift.y().asConstant().asInt() & mask; + if (shift.x().getKind() == Kind.Int) { + return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forInt(-1 << amount, graph()))); + } else { + assert shift.x().getKind() == Kind.Long; + return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forLong(-1L << amount, graph()))); + } + } + } + } + return null; + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -27,6 +27,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -84,4 +85,13 @@ } gen.setResult(this, gen.getLIRGeneratorTool().emitMul(op1, op2)); } + + @Override + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + Value result = gen.emitMulMemory(x(), y(), access); + if (result != null) { + gen.setResult(this, result); + } + return result != null; + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -97,7 +98,9 @@ if (reassociated != this) { return reassociated; } - if (c < 0) { + if (c < 0 || ((IntegerStamp) StampFactory.forKind(y().getKind())).contains(-c)) { + // Adding a negative is more friendly to the backend since adds are + // commutative, so prefer add when it fits. return IntegerArithmeticNode.add(graph(), x(), ConstantNode.forIntegerStamp(stamp(), -c, graph())); } } else if (x().isConstant()) { @@ -117,4 +120,13 @@ public void generate(NodeLIRGeneratorTool gen) { gen.setResult(this, gen.getLIRGeneratorTool().emitSub(gen.operand(x()), gen.operand(y()))); } + + @Override + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + Value result = gen.emitSubMemory(x(), y(), access); + if (result != null) { + gen.setResult(this, result); + } + return result != null; + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -25,6 +25,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -33,7 +34,7 @@ * expression "(x & y) == 0", meaning that it will return true if (and only if) no bit is set in * both x and y. */ -public class IntegerTestNode extends LogicNode implements Canonicalizable, LIRLowerable { +public class IntegerTestNode extends LogicNode implements Canonicalizable, LIRLowerable, MemoryArithmeticLIRLowerable { @Input private ValueNode x; @Input private ValueNode y; @@ -76,4 +77,9 @@ } return this; } + + @Override + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + return false; + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -59,13 +59,7 @@ } else if (y().isConstant()) { int amount = y().asConstant().asInt(); int originalAmout = amount; - int mask; - if (getKind() == Kind.Int) { - mask = 0x1f; - } else { - assert getKind() == Kind.Long; - mask = 0x3f; - } + int mask = getShiftAmountMask(); amount &= mask; if (amount == 0) { return x(); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -112,4 +113,13 @@ public void generate(NodeLIRGeneratorTool gen) { gen.setResult(this, gen.getLIRGeneratorTool().emitNarrow(gen.operand(getInput()), getResultBits())); } + + @Override + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + Value result = gen.emitNarrowMemory(getResultBits(), access); + if (result != null) { + gen.setResult(this, result); + } + return result != null; + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -75,4 +76,13 @@ public void generate(NodeLIRGeneratorTool gen) { gen.setResult(this, gen.getLIRGeneratorTool().emitOr(gen.operand(x()), gen.operand(y()))); } + + @Override + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + Value result = gen.emitOrMemory(x(), y(), access); + if (result != null) { + gen.setResult(this, result); + } + return result != null; + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -34,7 +35,7 @@ * of a primitive value to some other incompatible stamp. The new stamp must have the same width as * the old stamp. */ -public class ReinterpretNode extends FloatingNode implements Canonicalizable, ArithmeticLIRLowerable { +public class ReinterpretNode extends FloatingNode implements Canonicalizable, ArithmeticLIRLowerable, MemoryArithmeticLIRLowerable { @Input private ValueNode value; @@ -106,6 +107,15 @@ gen.setResult(this, gen.getLIRGeneratorTool().emitReinterpret(kind, gen.operand(value()))); } + @Override + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + Value result = gen.emitReinterpretMemory(stamp(), access); + if (result != null) { + gen.setResult(this, result); + } + return result != null; + } + public static ValueNode reinterpret(Kind toKind, ValueNode value) { return value.graph().unique(new ReinterpretNode(toKind, value)); } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -57,13 +57,7 @@ } else if (y().isConstant()) { int amount = y().asConstant().asInt(); int originalAmout = amount; - int mask; - if (getKind() == Kind.Int) { - mask = 0x1f; - } else { - assert getKind() == Kind.Long; - mask = 0x3f; - } + int mask = getShiftAmountMask(); amount &= mask; if (amount == 0) { return x(); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ShiftNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ShiftNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ShiftNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -40,4 +41,15 @@ public ShiftNode(Stamp stamp, ValueNode x, ValueNode s) { super(stamp, x, s); } + + public int getShiftAmountMask() { + int mask; + if (getKind() == Kind.Int) { + mask = 0x1f; + } else { + assert getKind() == Kind.Long; + mask = 0x3f; + } + return mask; + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -107,4 +108,14 @@ public void generate(NodeLIRGeneratorTool gen) { gen.setResult(this, gen.getLIRGeneratorTool().emitSignExtend(gen.operand(getInput()), getInputBits(), getResultBits())); } + + @Override + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + assert !access.nullCheckLocation().getValueKind().isUnsigned() : "can't sign extend unsigned value"; + Value result = gen.emitSignExtendMemory(access, access.nullCheckLocation().getValueKind().getBitCount(), getResultBits()); + if (result != null) { + gen.setResult(this, result); + } + return result != null; + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -59,13 +59,7 @@ } else if (y().isConstant()) { int amount = y().asConstant().asInt(); int originalAmout = amount; - int mask; - if (getKind() == Kind.Int) { - mask = 0x1f; - } else { - assert getKind() == Kind.Long; - mask = 0x3f; - } + int mask = getShiftAmountMask(); amount &= mask; if (amount == 0) { return x(); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -74,4 +75,13 @@ public void generate(NodeLIRGeneratorTool gen) { gen.setResult(this, gen.getLIRGeneratorTool().emitXor(gen.operand(x()), gen.operand(y()))); } + + @Override + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + Value result = gen.emitXorMemory(x(), y(), access); + if (result != null) { + gen.setResult(this, result); + } + return result != null; + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -87,4 +88,13 @@ public void generate(NodeLIRGeneratorTool gen) { gen.setResult(this, gen.getLIRGeneratorTool().emitZeroExtend(gen.operand(getInput()), getInputBits(), getResultBits())); } + + @Override + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + Value result = gen.emitZeroExtendMemory(getInputBits(), getResultBits(), access); + if (result != null) { + gen.setResult(this, result); + } + return result != null; + } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -43,6 +43,11 @@ return object; } + protected void setObject(ValueNode x) { + updateUsages(object, x); + object = x; + } + public LocationNode location() { return (LocationNode) location; } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -67,6 +67,9 @@ @Override public Node canonical(CanonicalizerTool tool) { + if (object() instanceof PiNode && ((PiNode) object()).getGuard() == getGuard()) { + return graph().unique(new FloatingReadNode(((PiNode) object()).getOriginalValue(), location(), getLastLocationAccess(), stamp(), getGuard(), getBarrierType(), isCompressible())); + } return ReadNode.canonicalizeRead(this, location(), object(), tool, isCompressible()); } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -35,7 +35,7 @@ * Node for a {@linkplain ForeignCallDescriptor foreign} call. */ @NodeInfo(nameTemplate = "ForeignCall#{p#descriptor/s}") -public class ForeignCallNode extends AbstractMemoryCheckpoint implements LIRLowerable, DeoptimizingNode, MemoryCheckpoint.Multi { +public class ForeignCallNode extends AbstractMemoryCheckpoint implements LIRLowerable, DeoptimizingNode.DeoptDuring, MemoryCheckpoint.Multi { @Input private final NodeInputList arguments; private final ForeignCallsProvider foreignCalls; @@ -101,32 +101,25 @@ } @Override - public FrameState getDeoptimizationState() { - if (deoptState != null) { - return deoptState; - } else if (stateAfter() != null && canDeoptimize()) { - FrameState stateDuring = stateAfter(); - if ((stateDuring.stackSize() > 0 && stateDuring.stackAt(stateDuring.stackSize() - 1) == this) || (stateDuring.stackSize() > 1 && stateDuring.stackAt(stateDuring.stackSize() - 2) == this)) { - stateDuring = stateDuring.duplicateModified(stateDuring.bci, stateDuring.rethrowException(), this.getKind()); - } - setDeoptimizationState(stateDuring); - return stateDuring; - } - return null; + public FrameState stateDuring() { + return deoptState; } @Override - public void setDeoptimizationState(FrameState f) { - updateUsages(deoptState, f); - assert deoptState == null && canDeoptimize() : "shouldn't assign deoptState to " + this; - deoptState = f; + public void setStateDuring(FrameState stateDuring) { + updateUsages(deoptState, stateDuring); + deoptState = stateDuring; } @Override - public void setStateAfter(FrameState x) { - if (hasSideEffect()) { - super.setStateAfter(x); + public void computeStateDuring(FrameState stateAfter) { + FrameState stateDuring; + if ((stateAfter.stackSize() > 0 && stateAfter.stackAt(stateAfter.stackSize() - 1) == this) || (stateAfter.stackSize() > 1 && stateAfter.stackAt(stateAfter.stackSize() - 2) == this)) { + stateDuring = stateAfter.duplicateModified(stateAfter.bci, stateAfter.rethrowException(), this.getKind()); + } else { + stateDuring = stateAfter; } + setStateDuring(stateDuring); } @Override @@ -141,14 +134,4 @@ public boolean canDeoptimize() { return foreignCalls.canDeoptimize(descriptor); } - - @Override - public FrameState getState() { - if (deoptState != null) { - assert stateAfter() == null; - return deoptState; - } else { - return super.getState(); - } - } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -60,6 +60,9 @@ @Override public Node canonical(CanonicalizerTool tool) { + if (object() instanceof PiNode && ((PiNode) object()).getGuard() == getGuard()) { + return graph().add(new ReadNode(((PiNode) object()).getOriginalValue(), location(), stamp(), getGuard(), getBarrierType(), isCompressible())); + } return canonicalizeRead(this, location(), object(), tool, isCompressible()); } @@ -71,8 +74,14 @@ public static ValueNode canonicalizeRead(ValueNode read, LocationNode location, ValueNode object, CanonicalizerTool tool, boolean compressible) { MetaAccessProvider metaAccess = tool.getMetaAccess(); if (read.usages().isEmpty()) { - // Read without usages can be safely removed. - return null; + GuardingNode guard = ((Access) read).getGuard(); + if (guard != null && !(guard instanceof FixedNode)) { + // The guard is necessary even if the read goes away. + return read.graph().add(new ValueAnchorNode((ValueNode) guard)); + } else { + // Read without usages or guard can be safely removed. + return null; + } } if (tool.canonicalizeReads()) { if (metaAccess != null && object != null && object.isConstant()) { diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -22,16 +22,17 @@ */ package com.oracle.graal.nodes.extended; -import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.util.*; /** * The ValueAnchor instruction keeps non-CFG (floating) nodes above a certain point in the graph. */ -public final class ValueAnchorNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, Virtualizable, GuardingNode { +public final class ValueAnchorNode extends FixedWithNextNode implements LIRLowerable, Simplifiable, Virtualizable, GuardingNode { @Input private ValueNode anchored; @@ -50,19 +51,40 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (anchored != null && !anchored.isConstant() && !(anchored instanceof FixedNode)) { - // Found entry that needs this anchor. - return this; + public void simplify(SimplifierTool tool) { + while (next() instanceof ValueAnchorNode) { + ValueAnchorNode nextAnchor = (ValueAnchorNode) next(); + if (nextAnchor.anchored == anchored || nextAnchor.anchored == null) { + // two anchors for the same anchored -> coalesce + // nothing anchored on the next anchor -> coalesce + nextAnchor.replaceAtUsages(this); + GraphUtil.removeFixedWithUnusedInputs(nextAnchor); + } else { + break; + } + } + if (usages().isEmpty() && next() instanceof FixedAccessNode) { + FixedAccessNode next = (FixedAccessNode) next(); + if (next.getGuard() == anchored) { + GraphUtil.removeFixedWithUnusedInputs(this); + return; + } else if (next.getGuard() == null && anchored instanceof GuardNode && ((GuardNode) anchored).condition() instanceof IsNullNode) { + // coalesce null check guards into subsequent read/write + next.setGuard((GuardingNode) anchored); + tool.addToWorkList(next()); + return; + } } - if (usages().isNotEmpty()) { - // A not uses this anchor => anchor is necessary. - return this; + if (anchored != null && (anchored.isConstant() || anchored instanceof FixedNode)) { + // anchoring fixed nodes and constants is useless + removeAnchoredNode(); } - // Anchor is not necessary any more => remove. - return null; + if (anchored == null && usages().isEmpty()) { + // anchor is not necessary any more => remove. + GraphUtil.removeFixedWithUnusedInputs(this); + } } @Override diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.LocationNode.Location; import com.oracle.graal.nodes.spi.*; @@ -33,7 +34,7 @@ /** * Writes a given {@linkplain #value() value} a {@linkplain FixedAccessNode memory location}. */ -public final class WriteNode extends FixedAccessNode implements StateSplit, LIRLowerable, MemoryCheckpoint.Single, MemoryAccess, Virtualizable { +public final class WriteNode extends FixedAccessNode implements StateSplit, LIRLowerable, MemoryCheckpoint.Single, MemoryAccess, Simplifiable, Virtualizable { @Input private ValueNode value; @Input(notDataflow = true) private FrameState stateAfter; @@ -45,16 +46,6 @@ return stateAfter; } - @Override - public FrameState getState() { - if (stateAfter != null) { - assert super.getState() == null; - return stateAfter; - } else { - return super.getState(); - } - } - public void setStateAfter(FrameState x) { assert x == null || x.isAlive() : "frame state must be in a graph"; updateUsages(stateAfter, x); @@ -102,6 +93,13 @@ gen.getLIRGeneratorTool().emitStore(location().getValueKind(), address, v, this); } + @Override + public void simplify(SimplifierTool tool) { + if (object() instanceof PiNode && ((PiNode) object()).getGuard() == getGuard()) { + setObject(((PiNode) object()).getOriginalValue()); + } + } + @NodeIntrinsic public static native void writeMemory(Object object, Object value, Location location, @ConstantNodeParameter BarrierType barrierType, @ConstantNodeParameter boolean compressible); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -33,9 +33,9 @@ * The Java bytecode specification allows non-balanced locking. Graal does not handle such cases and * throws a {@link BailoutException} instead during graph building. */ -public abstract class AccessMonitorNode extends AbstractMemoryCheckpoint implements MemoryCheckpoint, DeoptimizingNode { +public abstract class AccessMonitorNode extends AbstractMemoryCheckpoint implements MemoryCheckpoint, DeoptimizingNode.DeoptBefore, DeoptimizingNode.DeoptAfter { - @Input private FrameState deoptState; + @Input private FrameState stateBefore; @Input private ValueNode object; @Input private MonitorIdNode monitorId; @@ -44,21 +44,14 @@ return true; } - @Override - public FrameState getDeoptimizationState() { - return deoptState; + public FrameState stateBefore() { + return stateBefore; } @Override - public void setDeoptimizationState(FrameState f) { - updateUsages(deoptState, f); - deoptState = f; - } - - @Override - public FrameState getState() { - assert deoptState == null || stateAfter() == null; - return deoptState == null ? stateAfter() : deoptState; + public void setStateBefore(FrameState f) { + updateUsages(stateBefore, f); + stateBefore = f; } public ValueNode object() { diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -126,15 +126,28 @@ @Override public Node canonical(CanonicalizerTool tool) { - if (!isStatic()) { + if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) { + // attempt to devirtualize the call + + // check for trivial cases (e.g. final methods, nonvirtual methods) + if (targetMethod.canBeStaticallyBound()) { + invokeKind = InvokeKind.Special; + return this; + } + + // check if the exact type of the receiver can be determined ValueNode receiver = receiver(); - if (receiver != null && ObjectStamp.isExactType(receiver) && ObjectStamp.typeOrNull(receiver) != null) { - if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) { - ResolvedJavaMethod method = ObjectStamp.typeOrNull(receiver).resolveMethod(targetMethod); - if (method != null) { - invokeKind = InvokeKind.Special; - targetMethod = method; - } + ResolvedJavaType exact = targetMethod.getDeclaringClass().asExactType(); + if (exact == null && ObjectStamp.isExactType(receiver)) { + exact = ObjectStamp.typeOrNull(receiver); + } + if (exact != null) { + // either the holder class is exact, or the receiver object has an exact type + ResolvedJavaMethod exactMethod = exact.resolveMethod(targetMethod); + if (exactMethod != null) { + invokeKind = InvokeKind.Special; + targetMethod = exactMethod; + return this; } } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -34,7 +34,7 @@ * This node is used to perform the finalizer registration at the end of the java.lang.Object * constructor. */ -public final class RegisterFinalizerNode extends AbstractStateSplit implements Canonicalizable, LIRLowerable, Virtualizable, DeoptimizingNode { +public final class RegisterFinalizerNode extends AbstractStateSplit implements Canonicalizable, LIRLowerable, Virtualizable, DeoptimizingNode.DeoptAfter { public static final ForeignCallDescriptor REGISTER_FINALIZER = new ForeignCallDescriptor("registerFinalizer", void.class, Object.class); @@ -96,17 +96,6 @@ return true; } - @Override - public FrameState getDeoptimizationState() { - return deoptState; - } - - @Override - public void setDeoptimizationState(FrameState f) { - updateUsages(deoptState, f); - deoptState = f; - } - @SuppressWarnings("unused") @NodeIntrinsic public static void register(Object thisObj) { diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRGenerator.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRGenerator.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRGenerator.java Wed Mar 26 20:44:11 2014 +0100 @@ -31,7 +31,6 @@ * This interface can be used to generate LIR for arithmetic operations. */ public interface ArithmeticLIRGenerator { - /** * TODO remove reference to {@link Stamp}. */ diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Wed Mar 26 20:44:11 2014 +0100 @@ -65,6 +65,14 @@ void emitMove(AllocatableValue dst, Value src); + /** + * Emits an op that loads the address of some raw data. + * + * @param dst the variable into which the address is loaded + * @param data the data to be installed with the generated code + */ + void emitData(AllocatableValue dst, byte[] data); + Value emitAddress(Value base, long displacement, Value index, int scale); Value emitAddress(StackSlot slot); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/MemoryArithmeticLIRLowerable.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/MemoryArithmeticLIRLowerable.java Wed Mar 26 20:44:11 2014 +0100 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014, 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.oracle.graal.nodes.spi; + +import com.oracle.graal.nodes.extended.*; + +/** + * Marks nodes which may be lowered in combination with a memory operation. + */ +public interface MemoryArithmeticLIRLowerable { + + /** + * Attempt to generate a memory form of a node operation. On platforms that support it this will + * be called when the merging is safe. + * + * @param gen + * @param access the memory input which can potentially merge into this operation. + * @return null if it's not possible to emit a memory form of this operation. A non-null value + * will be set as the operand of this node. + */ + boolean generate(MemoryArithmeticLIRLowerer gen, Access access); +} diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/MemoryArithmeticLIRLowerer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/MemoryArithmeticLIRLowerer.java Wed Mar 26 20:44:11 2014 +0100 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014, 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.oracle.graal.nodes.spi; + +import java.util.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.FloatConvertNode.FloatConvert; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.type.*; + +/** + * This interface can be used to generate LIR for arithmetic operations where one of the operations + * is load (@see ArithmeticLIRLowerable). + */ +public interface MemoryArithmeticLIRLowerer { + + Value setResult(ValueNode x, Value operand); + + Value emitAddMemory(ValueNode x, ValueNode y, Access access); + + Value emitMulMemory(ValueNode x, ValueNode y, Access access); + + Value emitSubMemory(ValueNode x, ValueNode y, Access access); + + Value emitDivMemory(ValueNode x, ValueNode y, Access access); + + Value emitRemMemory(ValueNode x, ValueNode y, Access access); + + Value emitXorMemory(ValueNode x, ValueNode y, Access access); + + Value emitOrMemory(ValueNode x, ValueNode y, Access access); + + Value emitAndMemory(ValueNode x, ValueNode y, Access access); + + Value emitReinterpretMemory(Stamp stamp, Access access); + + Value emitSignExtendMemory(Access access, int fromBits, int toBits); + + Value emitNarrowMemory(int resultBits, Access access); + + Value emitZeroExtendMemory(int inputBits, int resultBits, Access access); + + Value emitFloatConvertMemory(FloatConvert op, Access access); + + boolean memoryPeephole(Access valueNode, MemoryArithmeticLIRLowerable operation, List deferred); + + boolean emitIfMemory(IfNode ifNode, Access access); + +} diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeLIRGeneratorTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeLIRGeneratorTool.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeLIRGeneratorTool.java Wed Mar 26 20:44:11 2014 +0100 @@ -67,4 +67,6 @@ void emitOverflowCheckBranch(AbstractBeginNode overflowSuccessor, AbstractBeginNode next, double probability); Value[] visitInvokeArguments(CallingConvention cc, Collection arguments); + + MemoryArithmeticLIRLowerer getMemoryLowerer(); } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeMappableLIRGenerator.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeMappableLIRGenerator.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeMappableLIRGenerator.java Wed Mar 26 20:44:11 2014 +0100 @@ -7,6 +7,8 @@ Value operand(ValueNode object); + boolean hasOperand(ValueNode object); + Value setResult(ValueNode x, Value operand); } \ No newline at end of file diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeWithState.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeWithState.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeWithState.java Wed Mar 26 20:44:11 2014 +0100 @@ -24,25 +24,11 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -import static com.oracle.graal.nodes.StructuredGraph.GuardsStage.*; /** * Interface for nodes which have {@link FrameState} nodes as input. - *

- * Some node can implement more than one interface which requires a {@link FrameState} input (e.g. - * {@link DeoptimizingNode} and {@link StateSplit}). Since this interface can only report one - * FrameState, such nodes must ensure they only maintain a link to at most one FrameState at all - * times. Usually this is not a problem because FrameStates are associated only with StateSplit - * nodes before the {@link #AFTER_FSA} stage and only with DeoptimizingNodes after. - * */ public interface NodeWithState { - /** - * Gets the {@link FrameState} associated with this node. - * - * @return the {@link FrameState} associated with this node - */ - FrameState getState(); Node asNode(); } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java --- a/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java Wed Mar 26 20:44:11 2014 +0100 @@ -45,10 +45,14 @@ * } * */ -@SupportedSourceVersion(SourceVersion.RELEASE_7) @SupportedAnnotationTypes({"com.oracle.graal.options.Option"}) public class OptionProcessor extends AbstractProcessor { + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + private final Set processed = new HashSet<>(); private void processElement(Element element, OptionsInfo info) { diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java --- a/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java Wed Mar 26 20:44:11 2014 +0100 @@ -38,7 +38,7 @@ *

* Since the returned object is {@link AutoCloseable} the try-with-resource construct can be * used: - * + * *

      * try (OverrideScope s = OptionValue.override(myOption, myValue) {
      *     // code that depends on myOption == myValue
@@ -65,7 +65,7 @@
      * 

* Since the returned object is {@link AutoCloseable} the try-with-resource construct can be * used: - * + * *

      * Map overrides = new HashMap<>();
      * overrides.put(myOption1, myValue1);
@@ -96,13 +96,13 @@
      * 

* Since the returned object is {@link AutoCloseable} the try-with-resource construct can be * used: - * + * *

      * try (OverrideScope s = OptionValue.override(myOption1, myValue1, myOption2, myValue2) {
      *     // code that depends on myOption == myValue
      * }
      * 
- * + * * @param overrides overrides in the form {@code [option1, override1, option2, override2, ...]} */ public static OverrideScope override(Object... overrides) { @@ -221,14 +221,14 @@ /** * Gets the values of this option including overridden values. - * + * * @param c the collection to which the values are added. If null, one is allocated. * @return the collection to which the values were added in order from most overridden to * current value */ @SuppressWarnings("unchecked") public Collection getValues(Collection c) { - Collection values = c == null ? new ArrayList() : c; + Collection values = c == null ? new ArrayList<>() : c; if (!(this instanceof StableOptionValue)) { OverrideScope overrideScope = overrideScopes.get(); if (overrideScope != null) { diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Wed Mar 26 20:44:11 2014 +0100 @@ -273,10 +273,10 @@ // @formatter:on private boolean performReplacement(final Node node, Node canonical) { if (canonical == node) { - Debug.log("Canonicalizer: work on %s", node); + Debug.log("Canonicalizer: work on %1s", node); return false; } else { - Debug.log("Canonicalizer: replacing %s with %s", node, canonical); + Debug.log("Canonicalizer: replacing %1s with %1s", node, canonical); METRIC_CANONICALIZED_NODES.increment(); StructuredGraph graph = (StructuredGraph) node.graph(); if (node instanceof FloatingNode) { diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java Wed Mar 26 20:44:11 2014 +0100 @@ -88,6 +88,9 @@ } for (int i = 0; i < mergePredecessors.size(); ++i) { AbstractEndNode mergePredecessor = mergePredecessors.get(i); + if (!mergePredecessor.isAlive()) { + break; + } if (xs[i] == null) { continue; } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java Wed Mar 26 20:44:11 2014 +0100 @@ -82,7 +82,7 @@ } } if (obsoletes != null) { - ((DynamicDeoptimizeNode) ((MergeNode) target).next()).setDeoptimizationState(fs); + ((DynamicDeoptimizeNode) ((MergeNode) target).next()).setStateBefore(fs); for (AbstractDeoptimizeNode obsolete : obsoletes) { obsolete.safeDelete(); } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java Wed Mar 26 20:44:11 2014 +0100 @@ -49,24 +49,41 @@ @Override protected FrameState processNode(FixedNode node, FrameState currentState) { - if (node instanceof DeoptimizingNode) { - DeoptimizingNode deopt = (DeoptimizingNode) node; - if (deopt.canDeoptimize() && deopt.getDeoptimizationState() == null) { + if (node instanceof DeoptimizingNode.DeoptBefore) { + DeoptimizingNode.DeoptBefore deopt = (DeoptimizingNode.DeoptBefore) node; + if (deopt.canDeoptimize() && deopt.stateBefore() == null) { GraalInternalError.guarantee(currentState != null, "no FrameState at DeoptimizingNode %s", deopt); - deopt.setDeoptimizationState(currentState); + deopt.setStateBefore(currentState); } } + FrameState newState = currentState; if (node instanceof StateSplit) { StateSplit stateSplit = (StateSplit) node; FrameState stateAfter = stateSplit.stateAfter(); if (stateAfter != null) { - FrameState newState = stateAfter; + newState = stateAfter; stateSplit.setStateAfter(null); - return newState; } } - return currentState; + + if (node instanceof DeoptimizingNode.DeoptDuring) { + DeoptimizingNode.DeoptDuring deopt = (DeoptimizingNode.DeoptDuring) node; + if (deopt.canDeoptimize()) { + GraalInternalError.guarantee(newState != null, "no FrameState at DeoptimizingNode %s", deopt); + deopt.computeStateDuring(newState); + } + } + + if (node instanceof DeoptimizingNode.DeoptAfter) { + DeoptimizingNode.DeoptAfter deopt = (DeoptimizingNode.DeoptAfter) node; + if (deopt.canDeoptimize() && deopt.stateAfter() == null) { + GraalInternalError.guarantee(newState != null, "no FrameState at DeoptimizingNode %s", deopt); + deopt.setStateAfter(newState); + } + } + + return newState; } @Override diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Wed Mar 26 20:44:11 2014 +0100 @@ -55,6 +55,9 @@ * does the actual control-flow expansion of the remaining {@link GuardNode GuardNodes}. */ public class GuardLoweringPhase extends BasePhase { + + private static final DebugMetric metricImplicitNullCheck = Debug.metric("ImplicitNullCheck"); + private static class UseImplicitNullChecks extends ScheduledNodeIterator { private final IdentityHashMap nullGuarded = new IdentityHashMap<>(); @@ -88,6 +91,7 @@ private void processAccess(Access access) { GuardNode guard = nullGuarded.get(access.object()); if (guard != null && isImplicitNullCheck(access.nullCheckLocation())) { + metricImplicitNullCheck.increment(); access.setGuard(guard.getGuard()); FixedAccessNode fixedAccess; if (access instanceof FloatingAccessNode) { diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Wed Mar 26 20:44:11 2014 +0100 @@ -173,7 +173,10 @@ public static void logInliningDecision(final String msg, final Object... args) { try (Scope s = Debug.scope(inliningDecisionsScopeString)) { - Debug.log(msg, args); + // Can't use log here since we are varargs + if (Debug.isLogEnabled()) { + Debug.logv(msg, args); + } } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ProfileCompiledMethodsPhase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ProfileCompiledMethodsPhase.java Wed Mar 26 20:44:11 2014 +0100 @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2012, 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.oracle.graal.phases.common; + +import java.util.*; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.cfg.*; +import com.oracle.graal.nodes.debug.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.util.*; +import com.oracle.graal.nodes.virtual.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.graph.*; +import com.oracle.graal.phases.schedule.*; + +/** + * This phase add counters for the dynamically executed number of nodes. Incrementing the counter + * for each node would be too costly, so this phase takes the compromise that it trusts split + * probabilities, but not loop frequencies. This means that it will insert counters at the start of + * a method and at each loop header. + * + * A schedule is created so that floating nodes can also be taken into account. The weight of a node + * is determined heuristically in the + * {@link ProfileCompiledMethodsPhase#getNodeWeight(ScheduledNode)} method. + * + * Additionally, there's a second counter that's only increased for code sections without invokes. + */ +public class ProfileCompiledMethodsPhase extends Phase { + + private static final String GROUP_NAME = "~profiled weight"; + private static final String GROUP_NAME_WITHOUT = "~profiled weight (invoke-free sections)"; + + private static final boolean WITH_SECTION_HEADER = false; + + @Override + protected void run(StructuredGraph graph) { + ComputeProbabilityClosure closure = new ComputeProbabilityClosure(graph); + NodesToDoubles probabilities = closure.apply(); + SchedulePhase schedule = new SchedulePhase(); + schedule.apply(graph, false); + + ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, true); + for (Loop loop : cfg.getLoops()) { + double loopProbability = probabilities.get(loop.loopBegin()); + if (loopProbability > (1D / Integer.MAX_VALUE)) { + addSectionCounters(loop.loopBegin(), loop.blocks, loop.children, schedule, probabilities); + } + } + addSectionCounters(graph.start(), Arrays.asList(cfg.getBlocks()), Arrays.asList(cfg.getLoops()), schedule, probabilities); + } + + private static void addSectionCounters(FixedWithNextNode start, Collection sectionBlocks, Collection childLoops, SchedulePhase schedule, NodesToDoubles probabilities) { + HashSet blocks = new HashSet<>(sectionBlocks); + for (Loop loop : childLoops) { + blocks.removeAll(loop.blocks); + } + double weight = getSectionWeight(schedule, probabilities, blocks) / probabilities.get(start); + DynamicCounterNode.addCounterBefore(GROUP_NAME, sectionHead(start), (long) weight, true, start.next()); + if (!hasInvoke(blocks)) { + DynamicCounterNode.addCounterBefore(GROUP_NAME_WITHOUT, sectionHead(start), (long) weight, true, start.next()); + } + } + + private static String sectionHead(Node node) { + if (WITH_SECTION_HEADER) { + return node.toString(); + } else { + return ""; + } + } + + private static double getSectionWeight(SchedulePhase schedule, NodesToDoubles probabilities, Collection blocks) { + double count = 0; + for (Block block : blocks) { + double blockProbability = probabilities.get(block.getBeginNode()); + for (ScheduledNode node : schedule.getBlockToNodesMap().get(block)) { + count += blockProbability * getNodeWeight(node); + } + } + return count; + } + + private static double getNodeWeight(ScheduledNode node) { + if (node instanceof MergeNode) { + return ((MergeNode) node).phiPredecessorCount(); + } else if (node instanceof AbstractBeginNode || node instanceof AbstractEndNode || node instanceof MonitorIdNode || node instanceof ConstantNode || node instanceof ParameterNode || + node instanceof CallTargetNode || node instanceof ValueProxy || node instanceof VirtualObjectNode || node instanceof ReinterpretNode) { + return 0; + } else if (node instanceof AccessMonitorNode) { + return 10; + } else if (node instanceof Access) { + return 2; + } else if (node instanceof LogicNode || node instanceof ConvertNode || node instanceof BinaryNode || node instanceof NotNode) { + return 1; + } else if (node instanceof IntegerDivNode || node instanceof FloatDivNode || node instanceof IntegerRemNode || node instanceof FloatRemNode) { + return 10; + } else if (node instanceof IntegerMulNode || node instanceof FloatMulNode) { + return 3; + } else if (node instanceof Invoke) { + return 5; + } else if (node instanceof IfNode || node instanceof SafepointNode) { + return 1; + } else if (node instanceof SwitchNode) { + return node.successors().count(); + } else if (node instanceof ReturnNode || node instanceof UnwindNode || node instanceof DeoptimizeNode) { + return node.successors().count(); + } else if (node instanceof AbstractNewObjectNode) { + return 10; + } + return 2; + } + + private static boolean hasInvoke(Collection blocks) { + boolean hasInvoke = false; + for (Block block : blocks) { + for (FixedNode fixed : block.getNodes()) { + if (fixed instanceof Invoke) { + hasInvoke = true; + } + } + } + return hasInvoke; + } +} diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java Wed Mar 26 20:44:11 2014 +0100 @@ -76,7 +76,7 @@ AbstractBeginNode nonTrappingContinuation = ifNode.falseSuccessor(); AbstractBeginNode trappingContinuation = ifNode.trueSuccessor(); NullCheckNode trappingNullCheck = deopt.graph().add(new NullCheckNode(isNullNode.object())); - trappingNullCheck.setDeoptimizationState(deopt.getDeoptimizationState()); + trappingNullCheck.setStateBefore(deopt.stateBefore()); deopt.graph().replaceSplit(ifNode, trappingNullCheck, nonTrappingContinuation); GraphUtil.killCFG(trappingContinuation); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java Wed Mar 26 20:44:11 2014 +0100 @@ -73,7 +73,7 @@ BasePhase.this.run(graph, context); phaseMetric.increment(); if (dumpGraph) { - Debug.dump(graph, "After phase %s", name); + Debug.dump(graph, "After phase %s", getName()); } assert graph.verify(); } catch (Throwable t) { diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Wed Mar 26 20:44:11 2014 +0100 @@ -271,6 +271,8 @@ public static final OptionValue OptDevirtualizeInvokesOptimistically = new OptionValue<>(true); @Option(help = "") public static final OptionValue OptPushThroughPi = new OptionValue<>(true); + @Option(help = "Allow backend to emit arithmetic and compares directly against memory.") + public static final OptionValue OptFoldMemory = new OptionValue<>(true); /** diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Wed Mar 26 20:44:11 2014 +0100 @@ -59,7 +59,7 @@ /** * This constructor creates a {@link SchedulingError} with a message assembled via * {@link String#format(String, Object...)}. - * + * * @param format a {@linkplain Formatter format} string * @param args parameters to {@link String#format(String, Object...)} */ @@ -164,9 +164,9 @@ /** * gather all kill locations by iterating trough the nodes assigned to a block. - * + * * assumptions: {@link MemoryCheckpoint MemoryCheckPoints} are {@link FixedNode FixedNodes}. - * + * * @param block block to analyze * @param excludeNode if null, compute normal set of kill locations. if != null, don't add kills * until we reach excludeNode. @@ -457,9 +457,9 @@ * this method tries to find the "optimal" schedule for a read, by pushing it down towards its * latest schedule starting by the earliest schedule. By doing this, it takes care of memory * dependencies using kill sets. - * + * * In terms of domination relation, it looks like this: - * + * *
      *    U      upperbound block, defined by last access location of the floating read
      *    ▲
@@ -469,9 +469,9 @@
      *    ▲
      *    L      latest block
      * 
- * + * * i.e. upperbound `dom` earliest `dom` optimal `dom` latest. - * + * */ private Block optimalBlock(FloatingReadNode n, SchedulingStrategy strategy) { assert memsched == MemoryScheduling.OPTIMAL; @@ -540,7 +540,7 @@ /** * compute path in dominator tree from earliest schedule to latest schedule. - * + * * @return the order of the stack is such as the first element is the earliest schedule. */ private static Deque computePathInDominatorTree(Block earliestBlock, Block latestBlock) { @@ -582,7 +582,7 @@ /** * Calculates the last block that the given node could be scheduled in, i.e., the common * dominator of all usages. To do so all usages are also assigned to blocks. - * + * * @param strategy */ private Block latestBlock(ScheduledNode node, SchedulingStrategy strategy) { @@ -680,7 +680,7 @@ * Schedules a node out of loop based on its earliest schedule. Note that this movement is only * valid if it's done for every other node in the schedule, otherwise this movement is * not valid. - * + * * @param n Node to schedule * @param latestBlock latest possible schedule for {@code n} * @param earliest earliest possible schedule for {@code n} @@ -705,7 +705,7 @@ /** * Passes all blocks that a specific usage of a node is in to a given closure. This is more * complex than just taking the usage's block because of of PhiNodes and FrameStates. - * + * * @param node the node that needs to be scheduled * @param usage the usage whose blocks need to be considered * @param closure the closure that will be called for each block @@ -966,14 +966,18 @@ return; } - FrameState state = null; + FrameState stateAfter = null; + if (i instanceof StateSplit) { + stateAfter = ((StateSplit) i).stateAfter(); + } + for (Node input : i.inputs()) { if (input instanceof FrameState) { - assert state == null; - state = (FrameState) input; + if (input != stateAfter) { + addUnscheduledToLatestSorting(b, (FrameState) input, sortedInstructions, visited, reads, beforeLastLocation); + } } else { addToLatestSorting(b, (ScheduledNode) input, sortedInstructions, visited, reads, beforeLastLocation); - } } @@ -991,7 +995,7 @@ addToLatestSorting(b, (ScheduledNode) i.predecessor(), sortedInstructions, visited, reads, beforeLastLocation); visited.mark(i); - addUnscheduledToLatestSorting(b, state, sortedInstructions, visited, reads, beforeLastLocation); + addUnscheduledToLatestSorting(b, stateAfter, sortedInstructions, visited, reads, beforeLastLocation); // Now predecessors and inputs are scheduled => we can add this node. if (!sortedInstructions.contains(i)) { @@ -1038,7 +1042,7 @@ } if (instruction instanceof AbstractBeginNode) { - ArrayList proxies = (instruction instanceof LoopExitNode) ? new ArrayList() : null; + ArrayList proxies = (instruction instanceof LoopExitNode) ? new ArrayList<>() : null; for (ScheduledNode inBlock : blockToNodesMap.get(b)) { if (!visited.isMarked(inBlock)) { if (inBlock instanceof ProxyNode) { diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java Wed Mar 26 20:44:11 2014 +0100 @@ -60,7 +60,13 @@ if (input instanceof FrameState && node instanceof StateSplit && input == ((StateSplit) node).stateAfter()) { // nothing to do - after frame states are known, allowed cycles } else { - assert false : "unexpected cycle detected at input " + node + " -> " + input; + /* + * TODO assertion does not hold for Substrate VM (in general for all + * notDataflow inputs) + * + * assert false : "unexpected cycle detected at input " + node + " -> " + * + input; + */ } } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyDebugUsage.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyDebugUsage.java Wed Mar 26 20:44:11 2014 +0100 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013, 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.oracle.graal.phases.verify; + +import static com.oracle.graal.api.meta.MetaUtil.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.tiers.*; + +/** + * Verifies that no argument to one of the {@link Debug#log(String)} methods is the result of + * {@link StringBuilder#toString()} or {@link StringBuffer#toString()}. Instead, one of the + * multi-parameter {@code log()} methods should be used. The goal is to minimize/prevent allocation + * at logging call sites. + */ +public class VerifyDebugUsage extends VerifyPhase { + + @Override + protected boolean verify(StructuredGraph graph, PhaseContext context) { + for (MethodCallTargetNode t : graph.getNodes(MethodCallTargetNode.class)) { + ResolvedJavaMethod callee = t.targetMethod(); + ResolvedJavaType debugType = context.getMetaAccess().lookupJavaType(Debug.class); + if (callee.getDeclaringClass().equals(debugType)) { + if (callee.getName().equals("log")) { + int argIdx = 1; + for (ValueNode arg : t.arguments()) { + if (arg instanceof Invoke) { + Invoke invoke = (Invoke) arg; + CallTargetNode callTarget = invoke.callTarget(); + if (callTarget instanceof MethodCallTargetNode) { + ResolvedJavaMethod m = ((MethodCallTargetNode) callTarget).targetMethod(); + if (m.getName().equals("toString")) { + String holder = m.getDeclaringClass().getName(); + if (holder.equals("Ljava/lang/StringBuilder;") || holder.equals("Ljava/lang/StringBuffer;")) { + StackTraceElement e = graph.method().asStackTraceElement(invoke.bci()); + throw new VerificationError(String.format("%s: parameter %d of call to %s appears to be a String concatenation expression.%n" + + " Use one of the multi-parameter Debug.log() methods or Debug.logv() instead.", e, argIdx, format("%H.%n(%p)", callee))); + } + } + } + } + argIdx++; + } + } + } + } + return true; + } +} diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java Wed Mar 26 20:44:11 2014 +0100 @@ -115,7 +115,7 @@ if (PrintBinaryGraphs.getValue()) { printer = new BinaryGraphPrinter(FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW)); } else { - printer = new IdealGraphPrinter(new FileOutputStream(file)); + printer = new IdealGraphPrinter(new FileOutputStream(file), true); } TTY.println("Dumping IGV graphs to %s", file.getName()); } catch (IOException e) { @@ -132,7 +132,7 @@ if (PrintBinaryGraphs.getValue()) { printer = new BinaryGraphPrinter(SocketChannel.open(new InetSocketAddress(host, port))); } else { - IdealGraphPrinter xmlPrinter = new IdealGraphPrinter(new Socket(host, port).getOutputStream()); + IdealGraphPrinter xmlPrinter = new IdealGraphPrinter(new Socket(host, port).getOutputStream(), true); printer = xmlPrinter; } TTY.println("Connected to the IGV on %s:%d", host, port); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java Wed Mar 26 20:44:11 2014 +0100 @@ -42,12 +42,18 @@ */ public class IdealGraphPrinter extends BasicIdealGraphPrinter implements GraphPrinter { + private final boolean tryToSchedule; + /** * Creates a new {@link IdealGraphPrinter} that writes to the specified output stream. + * + * @param tryToSchedule If false, no scheduling is done, which avoids exceptions for + * non-schedulable graphs. */ - public IdealGraphPrinter(OutputStream stream) { + public IdealGraphPrinter(OutputStream stream, boolean tryToSchedule) { super(stream); this.begin(); + this.tryToSchedule = tryToSchedule; } /** @@ -80,7 +86,7 @@ beginGraph(title); Set noBlockNodes = new HashSet<>(); SchedulePhase schedule = predefinedSchedule; - if (schedule == null) { + if (schedule == null && tryToSchedule) { try { schedule = new SchedulePhase(); schedule.apply((StructuredGraph) graph); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/VerifierAnnotationProcessor.java --- a/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/VerifierAnnotationProcessor.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/VerifierAnnotationProcessor.java Wed Mar 26 20:44:11 2014 +0100 @@ -30,12 +30,16 @@ import javax.lang.model.element.*; import javax.lang.model.type.*; -@SupportedSourceVersion(SourceVersion.RELEASE_7) public class VerifierAnnotationProcessor extends AbstractProcessor { private List verifiers; @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { if (!roundEnv.processingOver()) { for (AbstractVerifier verifier : getVerifiers()) { diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java Wed Mar 26 20:44:11 2014 +0100 @@ -175,7 +175,7 @@ for (Node returnSideEffect : returnSideEffects) { if (!unwindSideEffects.contains(returnSideEffect) && !maskedSideEffects.contains(returnSideEffect)) { StateSplit split = (StateSplit) returnSideEffect; - if (split.getState() != null) { + if (split.stateAfter() != null) { split.setStateAfter(graph.add(new FrameState(FrameState.AFTER_BCI))); } } @@ -184,7 +184,7 @@ for (Node unwindSideEffect : unwindSideEffects) { if (!returnSideEffects.contains(unwindSideEffect) && !maskedSideEffects.contains(unwindSideEffect)) { StateSplit split = (StateSplit) unwindSideEffect; - if (split.getState() != null) { + if (split.stateAfter() != null) { split.setStateAfter(graph.add(new FrameState(FrameState.AFTER_EXCEPTION_BCI))); } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Wed Mar 26 20:44:11 2014 +0100 @@ -40,6 +40,7 @@ import com.oracle.graal.debug.internal.*; import com.oracle.graal.graph.*; import com.oracle.graal.java.*; +import com.oracle.graal.java.GraphBuilderPhase.Instance; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; @@ -233,7 +234,9 @@ } else { original = metaAccess.lookupJavaConstructor((Constructor) originalMember); } - Debug.log("substitution: " + MetaUtil.format("%H.%n(%p) %r", original) + " --> " + MetaUtil.format("%H.%n(%p) %r", substitute)); + if (Debug.isLogEnabled()) { + Debug.log("substitution: %s --> %s", MetaUtil.format("%H.%n(%p) %r", original), MetaUtil.format("%H.%n(%p) %r", substitute)); + } registeredMethodSubstitutions.put(original, substitute); return original; @@ -340,7 +343,7 @@ public StructuredGraph makeGraph(final SnippetInliningPolicy policy) { try (Scope s = Debug.scope("BuildSnippetGraph", method)) { - StructuredGraph graph = parseGraph(method, policy); + StructuredGraph graph = parseGraph(method, policy, 0); // Cannot have a finalized version of a graph in the cache graph = graph.copy(); @@ -380,12 +383,14 @@ new DeadCodeEliminationPhase().apply(graph); } - private StructuredGraph parseGraph(final ResolvedJavaMethod methodToParse, final SnippetInliningPolicy policy) { + private static final int MAX_GRAPH_INLINING_DEPTH = 100; // more than enough + + private StructuredGraph parseGraph(final ResolvedJavaMethod methodToParse, final SnippetInliningPolicy policy, int inliningDepth) { StructuredGraph graph = graphCache.get(methodToParse); if (graph == null) { StructuredGraph newGraph = null; try (Scope s = Debug.scope("ParseGraph", methodToParse)) { - newGraph = buildGraph(methodToParse, policy == null ? inliningPolicy(methodToParse) : policy); + newGraph = buildGraph(methodToParse, policy == null ? inliningPolicy(methodToParse) : policy, inliningDepth); } catch (Throwable e) { throw Debug.handle(e); } @@ -404,7 +409,7 @@ final StructuredGraph graph = new StructuredGraph(methodToParse); try (Scope s = Debug.scope("buildInitialGraph", graph)) { MetaAccessProvider metaAccess = providers.getMetaAccess(); - new GraphBuilderPhase.Instance(metaAccess, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph); + createGraphBuilder(metaAccess, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph); new WordTypeVerificationPhase(metaAccess, target.wordKind).apply(graph); new WordTypeRewriterPhase(metaAccess, target.wordKind).apply(graph); @@ -417,6 +422,10 @@ return graph; } + protected Instance createGraphBuilder(MetaAccessProvider metaAccess, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) { + return new GraphBuilderPhase.Instance(metaAccess, graphBuilderConfig, optimisticOpts); + } + protected Object beforeInline(@SuppressWarnings("unused") MethodCallTargetNode callTarget, @SuppressWarnings("unused") StructuredGraph callee) { return null; } @@ -445,7 +454,8 @@ } } - private StructuredGraph buildGraph(final ResolvedJavaMethod methodToParse, final SnippetInliningPolicy policy) { + private StructuredGraph buildGraph(final ResolvedJavaMethod methodToParse, final SnippetInliningPolicy policy, int inliningDepth) { + assert inliningDepth < MAX_GRAPH_INLINING_DEPTH : "inlining limit exceeded"; assert isInlinableSnippet(methodToParse) : methodToParse; final StructuredGraph graph = buildInitialGraph(methodToParse); try (Scope s = Debug.scope("buildGraph", graph)) { @@ -477,7 +487,7 @@ " while preparing replacement " + format("%H.%n(%p)", method) + ". Placing \"//JaCoCo Exclude\" anywhere in " + methodToParse.getDeclaringClass().getSourceFileName() + " should fix this."); } - targetGraph = parseGraph(callee, policy); + targetGraph = parseGraph(callee, policy, inliningDepth + 1); } Object beforeInlineData = beforeInline(callTarget, targetGraph); InliningUtil.inline(callTarget.invoke(), targetGraph, true); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Wed Mar 26 20:44:11 2014 +0100 @@ -99,8 +99,8 @@ protected SnippetInfo(ResolvedJavaMethod method) { this.method = method; - instantiationCounter = Debug.metric("SnippetInstantiationCount[%#s]", method); - instantiationTimer = Debug.timer("SnippetInstantiationTime[%#s]", method); + instantiationCounter = Debug.metric("SnippetInstantiationCount[%s]", method); + instantiationTimer = Debug.timer("SnippetInstantiationTime[%s]", method); assert Modifier.isStatic(method.getModifiers()) : "snippet method must be static: " + MetaUtil.format("%H.%n", method); int count = method.getSignature().getParameterCount(false); constantParameters = new boolean[count]; @@ -728,8 +728,8 @@ private final ArrayList sideEffectNodes; /** - * Nodes that inherit the {@link DeoptimizingNode#getDeoptimizationState()} from the replacee - * during instantiation. + * Nodes that inherit a deoptimization {@link FrameState} from the replacee during + * instantiation. */ private final ArrayList deoptNodes; @@ -1024,11 +1024,50 @@ if (replacee instanceof DeoptimizingNode) { DeoptimizingNode replaceeDeopt = (DeoptimizingNode) replacee; - FrameState state = replaceeDeopt.getDeoptimizationState(); + + FrameState stateBefore = null; + FrameState stateDuring = null; + FrameState stateAfter = null; + if (replaceeDeopt.canDeoptimize()) { + if (replaceeDeopt instanceof DeoptimizingNode.DeoptBefore) { + stateBefore = ((DeoptimizingNode.DeoptBefore) replaceeDeopt).stateBefore(); + } + if (replaceeDeopt instanceof DeoptimizingNode.DeoptDuring) { + stateDuring = ((DeoptimizingNode.DeoptDuring) replaceeDeopt).stateDuring(); + } + if (replaceeDeopt instanceof DeoptimizingNode.DeoptAfter) { + stateAfter = ((DeoptimizingNode.DeoptAfter) replaceeDeopt).stateAfter(); + } + } + for (DeoptimizingNode deoptNode : deoptNodes) { DeoptimizingNode deoptDup = (DeoptimizingNode) duplicates.get(deoptNode); - assert replaceeDeopt.canDeoptimize() || !deoptDup.canDeoptimize(); - deoptDup.setDeoptimizationState(state); + if (deoptDup.canDeoptimize()) { + if (deoptDup instanceof DeoptimizingNode.DeoptBefore) { + ((DeoptimizingNode.DeoptBefore) deoptDup).setStateBefore(stateBefore); + } + if (deoptDup instanceof DeoptimizingNode.DeoptDuring) { + DeoptimizingNode.DeoptDuring deoptDupDuring = (DeoptimizingNode.DeoptDuring) deoptDup; + if (stateDuring != null) { + deoptDupDuring.setStateDuring(stateDuring); + } else if (stateAfter != null) { + deoptDupDuring.computeStateDuring(stateAfter); + } else if (stateBefore != null) { + assert !deoptDupDuring.hasSideEffect() : "can't use stateBefore as stateDuring for state split " + deoptDupDuring; + deoptDupDuring.setStateDuring(stateBefore); + } + } + if (deoptDup instanceof DeoptimizingNode.DeoptAfter) { + DeoptimizingNode.DeoptAfter deoptDupAfter = (DeoptimizingNode.DeoptAfter) deoptDup; + if (stateAfter != null) { + deoptDupAfter.setStateAfter(stateAfter); + } else { + assert !deoptDupAfter.hasSideEffect() : "can't use stateBefore as stateAfter for state split " + deoptDupAfter; + deoptDupAfter.setStateAfter(stateBefore); + } + + } + } } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -88,7 +88,7 @@ public Constant evalConst(Constant... inputs) { assert inputs.length == 1; - return Constant.forDouble(compute(inputs[0].asDouble(), operation())); + return Constant.forDouble(doCompute(inputs[0].asDouble(), operation())); } @Override @@ -101,6 +101,10 @@ @NodeIntrinsic public static double compute(double value, @ConstantNodeParameter Operation op) { + return doCompute(value, op); + } + + private static double doCompute(double value, Operation op) throws GraalInternalError { switch (op) { case ABS: return Math.abs(value); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.service.processor/src/com/oracle/graal/service/processor/ServiceProviderProcessor.java --- a/graal/com.oracle.graal.service.processor/src/com/oracle/graal/service/processor/ServiceProviderProcessor.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.service.processor/src/com/oracle/graal/service/processor/ServiceProviderProcessor.java Wed Mar 26 20:44:11 2014 +0100 @@ -34,12 +34,16 @@ import com.oracle.graal.api.runtime.*; -@SupportedSourceVersion(SourceVersion.RELEASE_7) @SupportedAnnotationTypes("com.oracle.graal.api.runtime.ServiceProvider") public class ServiceProviderProcessor extends AbstractProcessor { private final Set processed = new HashSet<>(); + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + private boolean verifyAnnotation(TypeMirror serviceInterface, TypeElement serviceProvider) { if (!processingEnv.getTypeUtils().isSubtype(serviceProvider.asType(), serviceInterface)) { String msg = String.format("Service provider class %s doesn't implement service interface %s", serviceProvider.getSimpleName(), serviceInterface); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalTest.java --- a/graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalTest.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalTest.java Wed Mar 26 20:44:11 2014 +0100 @@ -48,6 +48,15 @@ found = m; } } + if (found == null) { + /* Now look for non-public methods (but this does not look in superclasses). */ + for (Method m : clazz.getDeclaredMethods()) { + if (m.getName().equals(methodName)) { + Assert.assertNull(found); + found = m; + } + } + } if (found != null) { return found; } else { diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java Wed Mar 26 20:44:11 2014 +0100 @@ -137,6 +137,13 @@ callAndLoopCount++; } + void reportInlinedCall() { + callCount++; + callAndLoopCount++; + compilationCallThreshold++; + compilationCallAndLoopThreshold++; + } + void reportInterpreterCalls(int calls) { this.callCount += calls; this.callAndLoopCount += calls; diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java Wed Mar 26 20:44:11 2014 +0100 @@ -78,7 +78,7 @@ throw new IllegalStateException("CallNode must be adopted before it is split."); } - return replace(new InlinedOptimizedCallNode(getCallTarget(), getSplitCallTarget(), getCurrentCallTarget().getRootNode(), callCount)); + return replace(new InlinedOptimizedCallNode(getCallTarget(), getSplitCallTarget(), callCount)); } public static OptimizedCallNode create(OptimizedCallTarget target) { @@ -211,12 +211,10 @@ private static final class InlinedOptimizedCallNode extends OptimizedCallNode { - private final RootNode inlinedRoot; private final OptimizedCallTarget splittedTarget; - public InlinedOptimizedCallNode(OptimizedCallTarget target, OptimizedCallTarget splittedTarget, RootNode inlinedRoot, int callCount) { + public InlinedOptimizedCallNode(OptimizedCallTarget target, OptimizedCallTarget splittedTarget, int callCount) { super(target); - this.inlinedRoot = inlinedRoot; this.splittedTarget = splittedTarget; this.callCount = callCount; } @@ -226,7 +224,7 @@ if (CompilerDirectives.inInterpreter()) { callCount++; } - return inlinedRoot.execute(Truffle.getRuntime().createVirtualFrame(caller, arguments, inlinedRoot.getFrameDescriptor())); + return getCurrentCallTarget().callInlined(caller, arguments); } @Override diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNodeProfile.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNodeProfile.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNodeProfile.java Wed Mar 26 20:44:11 2014 +0100 @@ -45,6 +45,7 @@ private final int targetShallowNodeCount; private final double averageFrequency; private final double score; + private final boolean leaf; private String reason; public OptimizedCallNodeProfile(OptimizedCallTarget target, OptimizedCallNode callNode) { @@ -56,6 +57,22 @@ this.compilationRoots = findCompilationRoots(callNode); this.averageFrequency = calculateFrequency(); this.score = calculateScore(); + this.leaf = calculateLeaf(); + + } + + private boolean calculateLeaf() { + return NodeUtil.countNodes(callNode.getCurrentRootNode(), new NodeCountFilter() { + public boolean isCounted(Node node) { + if (node instanceof CallNode) { + CallNode childCall = (CallNode) node; + if (!childCall.isInlined()) { + return true; + } + } + return false; + } + }, true) <= 0; } private double calculateFrequency() { @@ -71,7 +88,7 @@ } public double calculateScore() { - return averageFrequency / targetDeepNodeCount; + return averageFrequency / Math.max(1, targetDeepNodeCount); } public boolean isInliningAllowed() { @@ -188,17 +205,13 @@ for (OptimizedCallNode c : callStack) { int childCallCount = c.getCallCount(); frequency *= childCallCount / (double) parentCallCount; - if (c.isInlined() || c.isSplit()) { - parentCallCount = childCallCount; - } else { - parentCallCount = c.getCurrentCallTarget().getCompilationProfile().getCallCount(); - } + parentCallCount = c.getCurrentCallTarget().getCompilationProfile().getCallCount(); } return frequency; } double calculateSimpleFrequency() { - return callNode.getCallCount() / (double) callTarget.getCompilationProfile().getCallCount(); + return callNode.getCallCount() / (double) ((OptimizedCallTarget) callNode.getRootNode().getCallTarget()).getCompilationProfile().getCallCount(); } static List findCompilationRoots(Node call) { @@ -218,7 +231,11 @@ public int compareTo(TruffleInliningProfile o) { if (o instanceof OptimizedCallNodeProfile) { - return Double.compare(((OptimizedCallNodeProfile) o).getScore(), getScore()); + int cmp = Boolean.compare(((OptimizedCallNodeProfile) o).leaf, leaf); + if (cmp == 0) { + return Double.compare(((OptimizedCallNodeProfile) o).getScore(), getScore()); + } + return cmp; } return 0; } @@ -231,7 +248,7 @@ properties.put("inlinedTotalCount", calculateInlinedTotalNodeCount(getCallNode())); properties.put("score", score); properties.put("frequency", averageFrequency); - properties.put("callCount", callNode.getCallCount()); + properties.put("leaf", leaf); properties.put("reason", reason); return properties; } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Wed Mar 26 20:44:11 2014 +0100 @@ -102,6 +102,13 @@ return callHelper(caller, args); } + public Object callInlined(PackedFrame caller, Arguments arguments) { + if (CompilerDirectives.inInterpreter()) { + compilationProfile.reportInlinedCall(); + } + return executeHelper(caller, arguments); + } + private Object callHelper(PackedFrame caller, Arguments args) { if (installedCode != null && installedCode.isValid()) { reinstallCallMethodShortcut(); @@ -196,8 +203,8 @@ while (callSite != null) { if (callSite.isInliningAllowed()) { OptimizedCallNode callNode = callSite.getCallNode(); + RootNode inlinedRoot = callNode.inlineImpl().getCurrentRootNode(); logInlined(this, callSite); - RootNode inlinedRoot = callNode.inlineImpl().getCurrentRootNode(); assert inlinedRoot != null; queueCallSitesForInlining(this, inlinedRoot, visitedCallNodes, queue); } else { @@ -334,7 +341,7 @@ } } - private static void logInlined(@SuppressWarnings("unused") final OptimizedCallTarget target, TruffleInliningProfile callSite) { + private static void logInlined(final OptimizedCallTarget target, TruffleInliningProfile callSite) { if (TraceTruffleInliningDetails.getValue() || TraceTruffleInlining.getValue()) { log(2, "inline success", callSite.getCallNode().getCurrentCallTarget().toString(), callSite.getDebugProperties()); @@ -348,13 +355,23 @@ OptimizedCallNode callNode = ((OptimizedCallNode) node); RootNode inlinedRoot = callNode.getCurrentRootNode(); - if (inlinedRoot != null && callNode.isInlined()) { + if (inlinedRoot != null) { Map properties = new LinkedHashMap<>(); addASTSizeProperty(callNode.getCurrentRootNode(), properties); - log(2 + (depth * 2), "inline success", callNode.getCurrentCallTarget().toString(), properties); - depth++; - inlinedRoot.accept(this); - depth--; + properties.putAll(callNode.createInliningProfile(target).getDebugProperties()); + String message; + if (callNode.isInlined()) { + message = "inline success"; + } else { + message = "inline dispatch"; + } + log(2 + (depth * 2), message, callNode.getCurrentCallTarget().toString(), properties); + + if (callNode.isInlined()) { + depth++; + inlinedRoot.accept(this); + depth--; + } } } return true; @@ -566,4 +583,5 @@ }); } } + } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java Wed Mar 26 20:44:11 2014 +0100 @@ -43,7 +43,7 @@ } public void preExpand(MethodCallTargetNode callTarget, StructuredGraph inliningGraph) { - ResolvedJavaMethod sourceMethod = callTarget.invoke().getState().method(); + ResolvedJavaMethod sourceMethod = callTarget.invoke().stateAfter().method(); int sourceMethodBci = callTarget.invoke().bci(); ResolvedJavaMethod targetMethod = callTarget.targetMethod(); diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java Wed Mar 26 20:44:11 2014 +0100 @@ -42,8 +42,8 @@ } public static final void trace(String format, Object... obj) { - if (TraceEscapeAnalysis.getValue()) { - Debug.log(format, obj); + if (TraceEscapeAnalysis.getValue() && Debug.isLogEnabled()) { + Debug.logv(format, obj); } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Wed Mar 26 20:44:11 2014 +0100 @@ -132,75 +132,78 @@ } private void processNodeWithState(NodeWithState nodeWithState, final BlockT state, final GraphEffectList effects) { - FrameState frameState = nodeWithState.getState(); - if (frameState != null) { - if (frameState.usages().count() > 1) { - nodeWithState.asNode().replaceFirstInput(frameState, frameState.copyWithInputs()); - frameState = nodeWithState.getState(); - } - final Set virtual = new ArraySet<>(); - frameState.applyToNonVirtual(new NodeClosure() { + for (Node input : nodeWithState.asNode().inputs()) { + if (input instanceof FrameState) { + FrameState frameState = (FrameState) input; + if (frameState.usages().count() > 1) { + FrameState copy = (FrameState) frameState.copyWithInputs(); + nodeWithState.asNode().replaceFirstInput(frameState, copy); + frameState = copy; + } + final Set virtual = new ArraySet<>(); + frameState.applyToNonVirtual(new NodeClosure() { - @Override - public void apply(Node usage, ValueNode value) { - ObjectState valueObj = getObjectState(state, value); - if (valueObj != null) { - virtual.add(valueObj); - effects.replaceFirstInput(usage, value, valueObj.virtual); - } else if (value instanceof VirtualObjectNode) { - ObjectState virtualObj = null; - for (ObjectState obj : state.getStates()) { - if (value == obj.virtual) { - virtualObj = obj; - break; + @Override + public void apply(Node usage, ValueNode value) { + ObjectState valueObj = getObjectState(state, value); + if (valueObj != null) { + virtual.add(valueObj); + effects.replaceFirstInput(usage, value, valueObj.virtual); + } else if (value instanceof VirtualObjectNode) { + ObjectState virtualObj = null; + for (ObjectState obj : state.getStates()) { + if (value == obj.virtual) { + virtualObj = obj; + break; + } + } + if (virtualObj != null) { + virtual.add(virtualObj); } } - if (virtualObj != null) { - virtual.add(virtualObj); - } + } + }); + for (ObjectState obj : state.getStates()) { + if (obj.isVirtual() && obj.hasLocks()) { + virtual.add(obj); } } - }); - for (ObjectState obj : state.getStates()) { - if (obj.isVirtual() && obj.hasLocks()) { - virtual.add(obj); - } - } - ArrayDeque queue = new ArrayDeque<>(virtual); - while (!queue.isEmpty()) { - ObjectState obj = queue.removeLast(); - if (obj.isVirtual()) { - for (ValueNode field : obj.getEntries()) { - if (field instanceof VirtualObjectNode) { - ObjectState fieldObj = state.getObjectState((VirtualObjectNode) field); - if (fieldObj.isVirtual() && !virtual.contains(fieldObj)) { - virtual.add(fieldObj); - queue.addLast(fieldObj); + ArrayDeque queue = new ArrayDeque<>(virtual); + while (!queue.isEmpty()) { + ObjectState obj = queue.removeLast(); + if (obj.isVirtual()) { + for (ValueNode field : obj.getEntries()) { + if (field instanceof VirtualObjectNode) { + ObjectState fieldObj = state.getObjectState((VirtualObjectNode) field); + if (fieldObj.isVirtual() && !virtual.contains(fieldObj)) { + virtual.add(fieldObj); + queue.addLast(fieldObj); + } } } } } - } - for (ObjectState obj : virtual) { - EscapeObjectState v; - if (obj.isVirtual()) { - ValueNode[] fieldState = obj.getEntries().clone(); - for (int i = 0; i < fieldState.length; i++) { - ObjectState valueObj = getObjectState(state, fieldState[i]); - if (valueObj != null) { - if (valueObj.isVirtual()) { - fieldState[i] = valueObj.virtual; - } else { - fieldState[i] = valueObj.getMaterializedValue(); + for (ObjectState obj : virtual) { + EscapeObjectState v; + if (obj.isVirtual()) { + ValueNode[] fieldState = obj.getEntries().clone(); + for (int i = 0; i < fieldState.length; i++) { + ObjectState valueObj = getObjectState(state, fieldState[i]); + if (valueObj != null) { + if (valueObj.isVirtual()) { + fieldState[i] = valueObj.virtual; + } else { + fieldState[i] = valueObj.getMaterializedValue(); + } } } + v = new VirtualObjectState(obj.virtual, fieldState); + } else { + v = new MaterializedObjectState(obj.virtual, obj.getMaterializedValue()); } - v = new VirtualObjectState(obj.virtual, fieldState); - } else { - v = new MaterializedObjectState(obj.virtual, obj.getMaterializedValue()); + effects.addVirtualMapping(frameState, v); } - effects.addVirtualMapping(frameState, v); } } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Wed Mar 26 20:44:11 2014 +0100 @@ -94,6 +94,9 @@ ReadCacheEntry identifier = new ReadCacheEntry(object, read.location()); ValueNode cachedValue = state.getCacheEntry(identifier); if (cachedValue != null) { + if (read.getGuard() != null && !(read.getGuard() instanceof FixedNode)) { + effects.addFixedNodeBefore(new ValueAnchorNode((ValueNode) read.getGuard()), read); + } effects.replaceAtUsages(read, cachedValue); addScalarAlias(read, cachedValue); deleted = true; diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java Wed Mar 26 20:44:11 2014 +0100 @@ -109,8 +109,8 @@ } public static void trace(String format, Object... obj) { - if (TraceEscapeAnalysis.getValue()) { - Debug.log(format, obj); + if (TraceEscapeAnalysis.getValue() && Debug.isLogEnabled()) { + Debug.logv(format, obj); } } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Wed Mar 26 20:44:11 2014 +0100 @@ -214,7 +214,7 @@ } else { location = makeLocation(graph, arguments.get(1), readKind, arguments.get(2)); } - replace(invoke, readOp(graph, arguments.get(0), invoke, location, readKind, BarrierType.NONE, false)); + replace(invoke, readOp(graph, arguments.get(0), invoke, location, StampFactory.forKind(readKind.getStackKind()), BarrierType.NONE, false)); break; } case READ_HEAP: { @@ -222,7 +222,8 @@ Kind readKind = asKind(callTargetNode.returnType()); LocationNode location = makeLocation(graph, arguments.get(1), readKind, ANY_LOCATION); BarrierType barrierType = (BarrierType) arguments.get(2).asConstant().asObject(); - replace(invoke, readOp(graph, arguments.get(0), invoke, location, readKind, barrierType, arguments.get(3).asConstant().asInt() == 0 ? false : true)); + boolean compressible = arguments.get(3).asConstant().asInt() != 0; + replace(invoke, readOp(graph, arguments.get(0), invoke, location, StampFactory.forKind(readKind.getStackKind()), barrierType, compressible)); break; } case WRITE: @@ -369,8 +370,8 @@ return IndexedLocationNode.create(locationIdentity, readKind, 0, fromSigned(graph, offset), graph, 1); } - protected ValueNode readOp(StructuredGraph graph, ValueNode base, Invoke invoke, LocationNode location, Kind readKind, BarrierType barrierType, boolean compressible) { - ReadNode read = graph.add(new ReadNode(base, location, StampFactory.forKind(readKind.getStackKind()), barrierType, compressible)); + protected ValueNode readOp(StructuredGraph graph, ValueNode base, Invoke invoke, LocationNode location, Stamp stamp, BarrierType barrierType, boolean compressible) { + ReadNode read = graph.add(new ReadNode(base, location, stamp, barrierType, compressible)); graph.addBeforeFixed(invoke.asNode(), read); /* * The read must not float outside its block otherwise it may float above an explicit zero diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java Wed Mar 26 20:44:11 2014 +0100 @@ -64,7 +64,7 @@ TestRootNode node = TestHelper.createRoot(Node1Factory.getInstance()); assertEquals("(int,boolean)", executeWith(node, 42, false)); assertEquals("(int,int)", executeWith(node, 42, 42)); - assertEquals(NodeCost.NONE, node.getNode().getCost()); + assertEquals(NodeCost.POLYMORPHIC, node.getNode().getCost()); assertParent(node.getNode(), node.getNode().getLeft()); assertParent(node.getNode(), node.getNode().getRight()); } @@ -75,7 +75,7 @@ assertEquals("(int,boolean)", executeWith(node, 42, false)); assertEquals("(boolean,boolean)", executeWith(node, true, false)); assertEquals("(int,int)", executeWith(node, 42, 42)); - assertEquals(NodeCost.NONE, node.getNode().getCost()); + assertEquals(NodeCost.POLYMORPHIC, node.getNode().getCost()); assertParent(node.getNode(), node.getNode().getLeft()); assertParent(node.getNode(), node.getNode().getRight()); } diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java Wed Mar 26 20:44:11 2014 +0100 @@ -42,7 +42,7 @@ assertEquals(21, executeWith(node, false, false)); assertEquals(42, executeWith(node, 21, 21)); assertEquals("(boolean,int)", executeWith(node, false, 42)); - assertEquals(NodeCost.NONE, node.getNode().getCost()); + assertEquals(NodeCost.POLYMORPHIC, node.getNode().getCost()); } @SuppressWarnings("unused") diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Wed Mar 26 20:44:11 2014 +0100 @@ -122,6 +122,20 @@ return unsafe.getObject(node, offset); } } + + @Override + public int hashCode() { + return kind.hashCode() | type.hashCode() | name.hashCode() | ((Long) offset).hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof NodeField) { + NodeField other = (NodeField) obj; + return offset == other.offset && name.equals(other.name) && type.equals(other.type) && kind.equals(other.kind); + } + return false; + } } /** @@ -198,6 +212,21 @@ public long[] getChildrenOffsets() { return childrenOffsets; } + + @Override + public int hashCode() { + return Arrays.hashCode(fields) ^ Arrays.hashCode(childOffsets) ^ Arrays.hashCode(childrenOffsets) ^ ((Long) parentOffset).hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof NodeClass) { + NodeClass other = (NodeClass) obj; + return Arrays.equals(fields, other.fields) && Arrays.equals(childOffsets, other.childOffsets) && Arrays.equals(childrenOffsets, other.childrenOffsets) && + parentOffset == other.parentOffset; + } + return false; + } } static class NodeIterator implements Iterator { diff -r 97a0878202c2 -r fbae9be45c95 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Wed Mar 26 17:02:45 2014 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Wed Mar 26 20:44:11 2014 +0100 @@ -98,13 +98,17 @@ return param.getLocalName(); } - private static CodeTree createAccessChild(NodeExecutionData targetExecution) { + private static CodeTree createAccessChild(NodeExecutionData targetExecution, String thisReference) { + String reference = thisReference; + if (reference == null) { + reference = "this"; + } CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); Element accessElement = targetExecution.getChild().getAccessElement(); if (accessElement == null || accessElement.getKind() == ElementKind.METHOD) { - builder.string("this.").string(targetExecution.getChild().getName()); + builder.string(reference).string(".").string(targetExecution.getChild().getName()); } else if (accessElement.getKind() == ElementKind.FIELD) { - builder.string("this.").string(accessElement.getSimpleName().toString()); + builder.string(reference).string(".").string(accessElement.getSimpleName().toString()); } else { throw new AssertionError(); } @@ -357,7 +361,7 @@ nodes.nullLiteral(); arguments.string(valueName(parameter.getPreviousParameter())); } - nodes.tree(createAccessChild(executionData)); + nodes.tree(createAccessChild(executionData, null)); arguments.string(valueName(parameter)); empty = false; } @@ -928,12 +932,6 @@ var.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getChildAnnotation())); clazz.add(var); - CodeExecutableElement setter = new CodeExecutableElement(modifiers(PROTECTED), context.getType(void.class), "setNext0"); - setter.getParameters().add(new CodeVariableElement(clazz.asType(), "next0")); - CodeTreeBuilder builder = setter.createBuilder(); - builder.statement("this.next0 = insert(next0)"); - clazz.add(setter); - CodeExecutableElement genericCachedExecute = createCachedExecute(node, node.getPolymorphicSpecialization()); clazz.add(genericCachedExecute); @@ -948,41 +946,21 @@ } if (needsInvokeCopyConstructorMethod()) { - clazz.add(createInvokeCopyConstructor(clazz.asType(), null)); - clazz.add(createCopyPolymorphicConstructor(clazz.asType())); + clazz.add(createCopy(clazz.asType(), null)); } if (node.getGenericSpecialization() != null && node.getGenericSpecialization().isReachable()) { clazz.add(createGenericExecute(node, rootGroup)); } - clazz.add(createGetCost(node, null, NodeCost.MONOMORPHIC)); } protected boolean needsInvokeCopyConstructorMethod() { return getModel().getNode().isPolymorphic(); } - protected CodeExecutableElement createGetCost(NodeData node, SpecializationData specialization, NodeCost cost) { - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getTruffleTypes().getNodeCost(), "getCost"); - - TypeMirror nodeInfoKind = context.getTruffleTypes().getNodeCost(); - - CodeTreeBuilder builder = method.createBuilder(); - if (node.isPolymorphic() && specialization == null) { - // assume next0 exists - builder.startIf().string("next0 != null && next0.getCost() != ").staticReference(nodeInfoKind, "UNINITIALIZED").end(); - builder.startBlock(); - builder.startReturn().staticReference(nodeInfoKind, "POLYMORPHIC").end(); - builder.end(); - } - - builder.startReturn().staticReference(nodeInfoKind, cost.name()).end(); - return method; - } - - protected CodeExecutableElement createInvokeCopyConstructor(TypeMirror baseType, SpecializationData specialization) { - CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), baseType, "invokeCopyConstructor"); + protected CodeExecutableElement createCopy(TypeMirror baseType, SpecializationData specialization) { + CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), baseType, "copyWithConstructor"); if (specialization == null) { method.getModifiers().add(ABSTRACT); } else { @@ -998,36 +976,6 @@ return method; } - protected CodeExecutableElement createCopyPolymorphicConstructor(TypeMirror baseType) { - CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), baseType, "copyPolymorphic"); - CodeTreeBuilder builder = method.createBuilder(); - CodeTreeBuilder nullBuilder = builder.create(); - CodeTreeBuilder oldBuilder = builder.create(); - CodeTreeBuilder resetBuilder = builder.create(); - - for (ActualParameter param : getModel().getSignatureParameters()) { - NodeExecutionData execution = param.getSpecification().getExecution(); - - CodeTree access = createAccessChild(execution); - - String oldName = "old" + Utils.firstLetterUpperCase(param.getLocalName()); - oldBuilder.declaration(execution.getChild().getNodeData().getNodeType(), oldName, access); - nullBuilder.startStatement().tree(access).string(" = null").end(); - resetBuilder.startStatement().tree(access).string(" = ").string(oldName).end(); - } - - builder.tree(oldBuilder.getRoot()); - builder.tree(nullBuilder.getRoot()); - - builder.startStatement().type(baseType).string(" copy = "); - builder.startCall("invokeCopyConstructor").end(); - builder.end(); - - builder.tree(resetBuilder.getRoot()); - builder.startReturn().string("copy").end(); - return method; - } - private List createImplicitChildrenAccessors() { NodeData node = getModel().getNode(); // Map> expectTypes = new HashMap<>(); @@ -1280,7 +1228,7 @@ private CodeExecutableElement createGenericExecuteAndSpecialize(final NodeData node, SpecializationGroup rootGroup) { TypeMirror genericReturnType = node.getGenericSpecialization().getReturnType().getType(); - CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), genericReturnType, EXECUTE_SPECIALIZE_NAME); + CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), genericReturnType, EXECUTE_SPECIALIZE_NAME); method.addParameter(new CodeVariableElement(getContext().getType(int.class), "minimumState")); addInternalValueParameters(method, node.getGenericSpecialization(), true, false); method.addParameter(new CodeVariableElement(getContext().getType(String.class), "reason")); @@ -1341,7 +1289,7 @@ private CodeExecutableElement createGenericExecute(NodeData node, SpecializationGroup group) { TypeMirror genericReturnType = node.getGenericSpecialization().getReturnType().getType(); - CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), genericReturnType, EXECUTE_GENERIC_NAME); + CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), genericReturnType, EXECUTE_GENERIC_NAME); if (!node.needsFrame(getContext())) { method.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getSlowPath())); @@ -1816,11 +1764,16 @@ String uninitializedName = nodeSpecializationClassName(node.getUninitializedSpecialization()); CodeTreeBuilder builder = parent.create(); - builder.declaration(getElement().asType(), "currentCopy", currentNode + ".copyPolymorphic()"); + builder.declaration(getElement().asType(), "currentCopy", currentNode + ".copyWithConstructor()"); + for (ActualParameter param : getModel().getSignatureParameters()) { + NodeExecutionData execution = param.getSpecification().getExecution(); + builder.startStatement().tree(createAccessChild(execution, "currentCopy")).string(" = ").nullLiteral().end(); + } + builder.startStatement().string("currentCopy.next0 = ").startNew(uninitializedName).string("currentCopy").end().end(); + builder.declaration(polyClassName, "polymorphic", builder.create().startNew(polyClassName).string(currentNode).end()); + builder.startStatement().string("polymorphic.next0 = ").string("currentCopy").end(); builder.startStatement().startCall(currentNode, "replace").string("polymorphic").string("message").end().end(); - builder.startStatement().startCall("polymorphic", "setNext0").string("currentCopy").end().end(); - builder.startStatement().startCall("currentCopy", "setNext0").startNew(uninitializedName).string(currentNode).end().end().end(); builder.startReturn(); builder.startCall("currentCopy.next0", EXECUTE_POLYMORPHIC_NAME); @@ -2300,7 +2253,7 @@ private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeExecutionData targetExecution, ExecutableTypeData targetExecutable, ActualParameter unexpectedParameter) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); if (targetExecution != null) { - builder.tree(createAccessChild(targetExecution)); + builder.tree(createAccessChild(targetExecution, null)); builder.string("."); } @@ -2465,7 +2418,7 @@ } CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodePolymorphicClassName(node), baseType, false); - clazz.getAnnotationMirrors().add(createNodeInfo(node, NodeCost.NONE)); + clazz.getAnnotationMirrors().add(createNodeInfo(node, NodeCost.POLYMORPHIC)); for (ActualParameter polymorphParameter : polymorph.getSignatureParameters()) { if (!polymorphParameter.getTypeSystemType().isGeneric()) { @@ -2508,11 +2461,10 @@ } if (needsInvokeCopyConstructorMethod()) { - clazz.add(createInvokeCopyConstructor(nodeGen.asType(), specialization)); + clazz.add(createCopy(nodeGen.asType(), specialization)); } createCachedExecuteMethods(specialization); - clazz.add(createGetCost(specialization.getNode(), specialization, NodeCost.NONE)); } private ExecutableElement createUpdateType(ActualParameter parameter) { @@ -2558,7 +2510,7 @@ } else if (specialization.isUninitialized()) { cost = NodeCost.UNINITIALIZED; } else if (specialization.isPolymorphic()) { - cost = NodeCost.NONE; + cost = NodeCost.POLYMORPHIC; } else if (specialization.isSpecialized()) { cost = NodeCost.MONOMORPHIC; } else { @@ -2594,13 +2546,7 @@ getElement().add(createUpdateTypes(nodeGen.asType())); } if (needsInvokeCopyConstructorMethod()) { - clazz.add(createInvokeCopyConstructor(nodeGen.asType(), specialization)); - } - - if (specialization.isGeneric()) { - clazz.add(createGetCost(specialization.getNode(), specialization, NodeCost.MEGAMORPHIC)); - } else if (specialization.isUninitialized()) { - clazz.add(createGetCost(specialization.getNode(), specialization, NodeCost.UNINITIALIZED)); + clazz.add(createCopy(nodeGen.asType(), specialization)); } } @@ -2726,9 +2672,9 @@ builder.end(); builder.startElseBlock(); - builder.startStatement().startCall("setNext0"); + builder.startStatement().string("next0 = "); builder.startNew(nodeSpecializationClassName(node.getUninitializedSpecialization())).string("this").end(); - builder.end().end(); + builder.end(); CodeTreeBuilder specializeCall = new CodeTreeBuilder(builder); specializeCall.startCall(EXECUTE_SPECIALIZE_NAME); diff -r 97a0878202c2 -r fbae9be45c95 mx/mx_graal.py --- a/mx/mx_graal.py Wed Mar 26 17:02:45 2014 +0100 +++ b/mx/mx_graal.py Wed Mar 26 20:44:11 2014 +0100 @@ -79,7 +79,8 @@ _make_eclipse_launch = False -_minVersion = mx.VersionSpec('1.7.0_04') +# @CallerSensitive introduced in 7u25 +_minVersion = mx.VersionSpec('1.7.0_25') JDK_UNIX_PERMISSIONS = 0755 @@ -647,11 +648,17 @@ env.setdefault('ALT_BOOTDIR', mx.java().jdk) # extract latest release tag for graal - tags = [x.split(' ')[0] for x in subprocess.check_output(['hg', 'tags']).split('\n') if x.startswith("graal-")] + try: + tags = [x.split(' ')[0] for x in subprocess.check_output(['hg', 'tags']).split('\n') if x.startswith("graal-")] + except: + # not a mercurial repository or hg commands are not available. + tags = None + if tags: # extract the most recent tag tag = sorted(tags, key=lambda e: [int(x) for x in e[len("graal-"):].split('.')], reverse=True)[0] env.setdefault('USER_RELEASE_SUFFIX', tag) + if not mx._opts.verbose: runCmd.append('MAKE_VERBOSE=') env['JAVA_HOME'] = jdk @@ -784,7 +791,7 @@ matches = lambda line: len([a for a in annotations if line == a or line.startswith(a + '(')]) != 0 return p.find_classes_with_matching_source_line(pkgRoot, matches, includeInnerClasses) -def _extract_VM_args(args, allowClasspath=False, useDoubleDash=False): +def _extract_VM_args(args, allowClasspath=False, useDoubleDash=False, defaultAllVMArgs=True): """ Partitions a command line into a leading sequence of HotSpot VM options and the rest. """ @@ -805,7 +812,10 @@ remainder = args[i:] return vmArgs, remainder - return args, [] + if defaultAllVMArgs: + return args, [] + else: + return [], args def _run_tests(args, harness, annotations, testfile): @@ -1139,6 +1149,11 @@ t.abort('Checkstyle warnings were found') tasks.append(t.stop()) + t = Task('FindBugs') + if findbugs([]) != 0: + t.abort('FindBugs warnings were found') + tasks.append(t.stop()) + if exists('jacoco.exec'): os.unlink('jacoco.exec') diff -r 97a0878202c2 -r fbae9be45c95 mx/projects --- a/mx/projects Wed Mar 26 17:02:45 2014 +0100 +++ b/mx/projects Wed Mar 26 20:44:11 2014 +0100 @@ -39,7 +39,7 @@ library@OKRA_WITH_SIM@sourceUrls=http://cr.openjdk.java.net/~tdeneau/okra-1.8-with-sim-src.jar library@JAVA_ALLOCATION_INSTRUMENTER@path=lib/java-allocation-instrumenter.jar -library@JAVA_ALLOCATION_INSTRUMENTER@urls=http://lafo.ssw.uni-linz.ac.at/java-allocation-instrumenter/java-allocation-instrumenter.jar +library@JAVA_ALLOCATION_INSTRUMENTER@urls=http://lafo.ssw.uni-linz.ac.at/java-allocation-instrumenter/java-allocation-instrumenter-67ad4ee8beb6.jar library@JAVA_ALLOCATION_INSTRUMENTER@sha1=1cd4073f57d7d461a53b0ddc1ea4ee2aa0c60e66 distribution@GRAAL@path=graal.jar @@ -56,7 +56,7 @@ project@com.oracle.graal.api.runtime@subDir=graal project@com.oracle.graal.api.runtime@sourceDirs=src project@com.oracle.graal.api.runtime@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.api.runtime@javaCompliance=1.7 +project@com.oracle.graal.api.runtime@javaCompliance=1.8 project@com.oracle.graal.api.runtime@workingSets=API,Graal # graal.api.test @@ -64,14 +64,14 @@ project@com.oracle.graal.api.test@sourceDirs=src project@com.oracle.graal.api.test@dependencies=JUNIT,com.oracle.graal.api.runtime project@com.oracle.graal.api.test@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.api.test@javaCompliance=1.7 +project@com.oracle.graal.api.test@javaCompliance=1.8 project@com.oracle.graal.api.test@workingSets=API,Graal,Test # graal.api.meta project@com.oracle.graal.api.meta@subDir=graal project@com.oracle.graal.api.meta@sourceDirs=src project@com.oracle.graal.api.meta@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.api.meta@javaCompliance=1.7 +project@com.oracle.graal.api.meta@javaCompliance=1.8 project@com.oracle.graal.api.meta@workingSets=API,Graal # graal.api.meta.test @@ -79,7 +79,7 @@ project@com.oracle.graal.api.meta.test@sourceDirs=src project@com.oracle.graal.api.meta.test@dependencies=JUNIT,com.oracle.graal.runtime,com.oracle.graal.java project@com.oracle.graal.api.meta.test@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.api.meta.test@javaCompliance=1.7 +project@com.oracle.graal.api.meta.test@javaCompliance=1.8 project@com.oracle.graal.api.meta.test@workingSets=API,Graal,Test # graal.api.meta.jdk8.test @@ -95,7 +95,7 @@ project@com.oracle.graal.api.code@sourceDirs=src project@com.oracle.graal.api.code@dependencies=com.oracle.graal.api.meta project@com.oracle.graal.api.code@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.api.code@javaCompliance=1.7 +project@com.oracle.graal.api.code@javaCompliance=1.8 project@com.oracle.graal.api.code@workingSets=API,Graal # graal.api.replacements @@ -103,7 +103,7 @@ project@com.oracle.graal.api.replacements@sourceDirs=src project@com.oracle.graal.api.replacements@dependencies=com.oracle.graal.api.meta project@com.oracle.graal.api.replacements@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.api.replacements@javaCompliance=1.7 +project@com.oracle.graal.api.replacements@javaCompliance=1.8 project@com.oracle.graal.api.replacements@workingSets=API,Graal,Replacements # graal.service.processor @@ -111,7 +111,7 @@ project@com.oracle.graal.service.processor@sourceDirs=src project@com.oracle.graal.service.processor@dependencies=com.oracle.graal.api.runtime project@com.oracle.graal.service.processor@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.service.processor@javaCompliance=1.7 +project@com.oracle.graal.service.processor@javaCompliance=1.8 project@com.oracle.graal.service.processor@workingSets=Codegen,HotSpot # graal.amd64 @@ -119,7 +119,7 @@ project@com.oracle.graal.amd64@sourceDirs=src project@com.oracle.graal.amd64@dependencies=com.oracle.graal.api.code project@com.oracle.graal.amd64@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.amd64@javaCompliance=1.7 +project@com.oracle.graal.amd64@javaCompliance=1.8 project@com.oracle.graal.amd64@workingSets=Graal,AMD64 # graal.ptx @@ -127,7 +127,7 @@ project@com.oracle.graal.ptx@sourceDirs=src project@com.oracle.graal.ptx@dependencies=com.oracle.graal.api.code project@com.oracle.graal.ptx@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.ptx@javaCompliance=1.7 +project@com.oracle.graal.ptx@javaCompliance=1.8 project@com.oracle.graal.ptx@workingSets=Graal,PTX # graal.sparc @@ -135,7 +135,7 @@ project@com.oracle.graal.sparc@sourceDirs=src project@com.oracle.graal.sparc@dependencies=com.oracle.graal.api.code project@com.oracle.graal.sparc@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.sparc@javaCompliance=1.7 +project@com.oracle.graal.sparc@javaCompliance=1.8 project@com.oracle.graal.sparc@workingSets=Graal,SPARC # graal.hotspot @@ -144,7 +144,7 @@ project@com.oracle.graal.hotspot@dependencies=com.oracle.graal.replacements,com.oracle.graal.runtime,com.oracle.graal.printer, com.oracle.graal.baseline project@com.oracle.graal.hotspot@checkstyle=com.oracle.graal.graph project@com.oracle.graal.hotspot@annotationProcessors=com.oracle.graal.replacements.verifier,com.oracle.graal.service.processor -project@com.oracle.graal.hotspot@javaCompliance=1.7 +project@com.oracle.graal.hotspot@javaCompliance=1.8 project@com.oracle.graal.hotspot@workingSets=Graal,HotSpot # graal.hotspot.amd64 @@ -153,7 +153,7 @@ project@com.oracle.graal.hotspot.amd64@dependencies=com.oracle.graal.compiler.amd64,com.oracle.graal.hotspot,com.oracle.graal.replacements.amd64 project@com.oracle.graal.hotspot.amd64@checkstyle=com.oracle.graal.graph project@com.oracle.graal.hotspot.amd64@annotationProcessors=com.oracle.graal.service.processor -project@com.oracle.graal.hotspot.amd64@javaCompliance=1.7 +project@com.oracle.graal.hotspot.amd64@javaCompliance=1.8 project@com.oracle.graal.hotspot.amd64@workingSets=Graal,HotSpot,AMD64 # graal.hotspot.sparc @@ -162,7 +162,7 @@ project@com.oracle.graal.hotspot.sparc@dependencies=com.oracle.graal.compiler.sparc project@com.oracle.graal.hotspot.sparc@checkstyle=com.oracle.graal.graph project@com.oracle.graal.hotspot.sparc@annotationProcessors=com.oracle.graal.service.processor -project@com.oracle.graal.hotspot.sparc@javaCompliance=1.7 +project@com.oracle.graal.hotspot.sparc@javaCompliance=1.8 project@com.oracle.graal.hotspot.sparc@workingSets=Graal,HotSpot,SPARC # graal.hotspot.ptx @@ -171,7 +171,7 @@ project@com.oracle.graal.hotspot.ptx@dependencies=com.oracle.graal.ptx,com.oracle.graal.compiler.ptx,com.oracle.graal.hotspot project@com.oracle.graal.hotspot.ptx@checkstyle=com.oracle.graal.graph project@com.oracle.graal.hotspot.ptx@annotationProcessors=com.oracle.graal.service.processor -project@com.oracle.graal.hotspot.ptx@javaCompliance=1.7 +project@com.oracle.graal.hotspot.ptx@javaCompliance=1.8 project@com.oracle.graal.hotspot.ptx@workingSets=Graal,HotSpot,PTX # graal.hotspot.hsail @@ -180,7 +180,7 @@ project@com.oracle.graal.hotspot.hsail@dependencies=com.oracle.graal.replacements.hsail,com.oracle.graal.hotspot project@com.oracle.graal.hotspot.hsail@checkstyle=com.oracle.graal.graph project@com.oracle.graal.hotspot.hsail@annotationProcessors=com.oracle.graal.service.processor -project@com.oracle.graal.hotspot.hsail@javaCompliance=1.7 +project@com.oracle.graal.hotspot.hsail@javaCompliance=1.8 project@com.oracle.graal.hotspot.hsail@workingSets=Graal,HotSpot,PTX # graal.hotspot.server @@ -188,7 +188,7 @@ project@com.oracle.graal.hotspot.server@sourceDirs=src project@com.oracle.graal.hotspot.server@dependencies=com.oracle.graal.hotspot project@com.oracle.graal.hotspot.server@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.hotspot.server@javaCompliance=1.7 +project@com.oracle.graal.hotspot.server@javaCompliance=1.8 project@com.oracle.graal.hotspot.server@workingSets=Graal,HotSpot # graal.hotspot.test @@ -196,7 +196,7 @@ project@com.oracle.graal.hotspot.test@sourceDirs=src project@com.oracle.graal.hotspot.test@dependencies=com.oracle.graal.replacements.test,com.oracle.graal.hotspot project@com.oracle.graal.hotspot.test@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.hotspot.test@javaCompliance=1.7 +project@com.oracle.graal.hotspot.test@javaCompliance=1.8 project@com.oracle.graal.hotspot.test@workingSets=Graal,HotSpot,Test # graal.hotspot.jdk8.test @@ -212,14 +212,14 @@ project@com.oracle.graal.hotspot.amd64.test@sourceDirs=src project@com.oracle.graal.hotspot.amd64.test@dependencies=com.oracle.graal.asm.amd64,com.oracle.graal.compiler.test project@com.oracle.graal.hotspot.amd64.test@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.hotspot.amd64.test@javaCompliance=1.7 +project@com.oracle.graal.hotspot.amd64.test@javaCompliance=1.8 project@com.oracle.graal.hotspot.amd64.test@workingSets=Graal,HotSpot,AMD64,Test # graal.options project@com.oracle.graal.options@subDir=graal project@com.oracle.graal.options@sourceDirs=src project@com.oracle.graal.options@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.options@javaCompliance=1.7 +project@com.oracle.graal.options@javaCompliance=1.8 project@com.oracle.graal.options@annotationProcessorForDependents=true project@com.oracle.graal.options@workingSets=Graal,Codegen @@ -228,14 +228,14 @@ project@com.oracle.graal.options.test@sourceDirs=src project@com.oracle.graal.options.test@dependencies=com.oracle.graal.options,JUNIT project@com.oracle.graal.options.test@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.options.test@javaCompliance=1.7 +project@com.oracle.graal.options.test@javaCompliance=1.8 project@com.oracle.graal.options.test@workingSets=Graal # graal.graph project@com.oracle.graal.graph@subDir=graal project@com.oracle.graal.graph@sourceDirs=src project@com.oracle.graal.graph@dependencies=com.oracle.graal.debug,com.oracle.graal.api.code -project@com.oracle.graal.graph@javaCompliance=1.7 +project@com.oracle.graal.graph@javaCompliance=1.8 project@com.oracle.graal.graph@workingSets=Graal,Graph # graal.graph.test @@ -243,14 +243,14 @@ project@com.oracle.graal.graph.test@sourceDirs=src project@com.oracle.graal.graph.test@checkstyle=com.oracle.graal.graph project@com.oracle.graal.graph.test@dependencies=JUNIT,com.oracle.graal.graph -project@com.oracle.graal.graph.test@javaCompliance=1.7 +project@com.oracle.graal.graph.test@javaCompliance=1.8 project@com.oracle.graal.graph.test@workingSets=Graal,Graph,Test # graal.debug project@com.oracle.graal.debug@subDir=graal project@com.oracle.graal.debug@sourceDirs=src project@com.oracle.graal.debug@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.debug@javaCompliance=1.7 +project@com.oracle.graal.debug@javaCompliance=1.8 project@com.oracle.graal.debug@workingSets=Graal,Debug # graal.debug.test @@ -258,7 +258,7 @@ project@com.oracle.graal.debug.test@sourceDirs=src project@com.oracle.graal.debug.test@dependencies=JUNIT,com.oracle.graal.debug project@com.oracle.graal.debug.test@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.debug.test@javaCompliance=1.7 +project@com.oracle.graal.debug.test@javaCompliance=1.8 project@com.oracle.graal.debug.test@workingSets=Graal,Debug,Test # graal.lir @@ -266,7 +266,7 @@ project@com.oracle.graal.lir@sourceDirs=src project@com.oracle.graal.lir@dependencies=com.oracle.graal.asm,com.oracle.graal.nodes project@com.oracle.graal.lir@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.lir@javaCompliance=1.7 +project@com.oracle.graal.lir@javaCompliance=1.8 project@com.oracle.graal.lir@workingSets=Graal,LIR # graal.lir.amd64 @@ -274,7 +274,7 @@ project@com.oracle.graal.lir.amd64@sourceDirs=src project@com.oracle.graal.lir.amd64@dependencies=com.oracle.graal.lir,com.oracle.graal.asm.amd64 project@com.oracle.graal.lir.amd64@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.lir.amd64@javaCompliance=1.7 +project@com.oracle.graal.lir.amd64@javaCompliance=1.8 project@com.oracle.graal.lir.amd64@workingSets=Graal,LIR,AMD64 # graal.lir.ptx @@ -282,7 +282,7 @@ project@com.oracle.graal.lir.ptx@sourceDirs=src project@com.oracle.graal.lir.ptx@dependencies=com.oracle.graal.asm.ptx project@com.oracle.graal.lir.ptx@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.lir.ptx@javaCompliance=1.7 +project@com.oracle.graal.lir.ptx@javaCompliance=1.8 project@com.oracle.graal.lir.ptx@workingSets=Graal,LIR,PTX # graal.lir.sparc @@ -290,7 +290,7 @@ project@com.oracle.graal.lir.sparc@sourceDirs=src project@com.oracle.graal.lir.sparc@dependencies=com.oracle.graal.asm.sparc project@com.oracle.graal.lir.sparc@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.lir.sparc@javaCompliance=1.7 +project@com.oracle.graal.lir.sparc@javaCompliance=1.8 project@com.oracle.graal.lir.sparc@workingSets=Graal,LIR,SPARC # graal.alloc @@ -298,7 +298,7 @@ project@com.oracle.graal.alloc@sourceDirs=src project@com.oracle.graal.alloc@dependencies=com.oracle.graal.nodes project@com.oracle.graal.alloc@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.alloc@javaCompliance=1.7 +project@com.oracle.graal.alloc@javaCompliance=1.8 project@com.oracle.graal.alloc@workingSets=Graal # graal.word @@ -306,7 +306,7 @@ project@com.oracle.graal.word@sourceDirs=src project@com.oracle.graal.word@dependencies=com.oracle.graal.phases project@com.oracle.graal.word@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.word@javaCompliance=1.7 +project@com.oracle.graal.word@javaCompliance=1.8 project@com.oracle.graal.word@workingSets=API,Graal # graal.replacements @@ -314,7 +314,7 @@ project@com.oracle.graal.replacements@sourceDirs=src project@com.oracle.graal.replacements@dependencies=com.oracle.graal.compiler,com.oracle.graal.java,com.oracle.graal.word project@com.oracle.graal.replacements@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.replacements@javaCompliance=1.7 +project@com.oracle.graal.replacements@javaCompliance=1.8 project@com.oracle.graal.replacements@annotationProcessors=com.oracle.graal.replacements.verifier,com.oracle.graal.service.processor project@com.oracle.graal.replacements@workingSets=Graal,Replacements @@ -323,7 +323,7 @@ project@com.oracle.graal.replacements.amd64@sourceDirs=src project@com.oracle.graal.replacements.amd64@dependencies=com.oracle.graal.replacements project@com.oracle.graal.replacements.amd64@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.replacements.amd64@javaCompliance=1.7 +project@com.oracle.graal.replacements.amd64@javaCompliance=1.8 project@com.oracle.graal.replacements.amd64@annotationProcessors=com.oracle.graal.service.processor project@com.oracle.graal.replacements.amd64@workingSets=Graal,Replacements,AMD64 @@ -332,7 +332,7 @@ project@com.oracle.graal.replacements.hsail@sourceDirs=src project@com.oracle.graal.replacements.hsail@dependencies=com.oracle.graal.compiler.hsail project@com.oracle.graal.replacements.hsail@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.replacements.hsail@javaCompliance=1.7 +project@com.oracle.graal.replacements.hsail@javaCompliance=1.8 project@com.oracle.graal.replacements.hsail@workingSets=Graal,Replacements,HSAIL # graal.replacements.test @@ -340,7 +340,7 @@ project@com.oracle.graal.replacements.test@sourceDirs=src project@com.oracle.graal.replacements.test@dependencies=com.oracle.graal.compiler.test,com.oracle.graal.replacements project@com.oracle.graal.replacements.test@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.replacements.test@javaCompliance=1.7 +project@com.oracle.graal.replacements.test@javaCompliance=1.8 project@com.oracle.graal.replacements.test@workingSets=Graal,Replacements,Test # graal.replacements.verifier @@ -348,7 +348,7 @@ project@com.oracle.graal.replacements.verifier@sourceDirs=src project@com.oracle.graal.replacements.verifier@dependencies=com.oracle.graal.api.replacements,com.oracle.graal.graph project@com.oracle.graal.replacements.verifier@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.replacements.verifier@javaCompliance=1.7 +project@com.oracle.graal.replacements.verifier@javaCompliance=1.8 project@com.oracle.graal.replacements.verifier@workingSets=Graal,Replacements # graal.nodes @@ -356,7 +356,7 @@ project@com.oracle.graal.nodes@sourceDirs=src project@com.oracle.graal.nodes@dependencies=com.oracle.graal.graph,com.oracle.graal.api.replacements project@com.oracle.graal.nodes@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.nodes@javaCompliance=1.7 +project@com.oracle.graal.nodes@javaCompliance=1.8 project@com.oracle.graal.nodes@annotationProcessors=com.oracle.graal.replacements.verifier project@com.oracle.graal.nodes@workingSets=Graal,Graph @@ -365,7 +365,7 @@ project@com.oracle.graal.nodes.test@sourceDirs=src project@com.oracle.graal.nodes.test@dependencies=com.oracle.graal.compiler.test project@com.oracle.graal.nodes.test@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.nodes.test@javaCompliance=1.7 +project@com.oracle.graal.nodes.test@javaCompliance=1.8 project@com.oracle.graal.nodes.test@workingSets=Graal,Graph # graal.phases @@ -373,7 +373,7 @@ project@com.oracle.graal.phases@sourceDirs=src project@com.oracle.graal.phases@dependencies=com.oracle.graal.nodes,com.oracle.graal.options project@com.oracle.graal.phases@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.phases@javaCompliance=1.7 +project@com.oracle.graal.phases@javaCompliance=1.8 project@com.oracle.graal.phases@workingSets=Graal,Phases # graal.phases.common @@ -381,7 +381,7 @@ project@com.oracle.graal.phases.common@sourceDirs=src project@com.oracle.graal.phases.common@dependencies=com.oracle.graal.phases project@com.oracle.graal.phases.common@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.phases.common@javaCompliance=1.7 +project@com.oracle.graal.phases.common@javaCompliance=1.8 project@com.oracle.graal.phases.common@workingSets=Graal,Phases # graal.virtual @@ -389,7 +389,7 @@ project@com.oracle.graal.virtual@sourceDirs=src project@com.oracle.graal.virtual@dependencies=com.oracle.graal.phases.common project@com.oracle.graal.virtual@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.virtual@javaCompliance=1.7 +project@com.oracle.graal.virtual@javaCompliance=1.8 project@com.oracle.graal.virtual@workingSets=Graal,Phases # graal.loop @@ -397,7 +397,7 @@ project@com.oracle.graal.loop@sourceDirs=src project@com.oracle.graal.loop@dependencies=com.oracle.graal.phases.common project@com.oracle.graal.loop@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.loop@javaCompliance=1.7 +project@com.oracle.graal.loop@javaCompliance=1.8 project@com.oracle.graal.loop@workingSets=Graal,Phases # graal.compiler @@ -405,7 +405,7 @@ project@com.oracle.graal.compiler@sourceDirs=src project@com.oracle.graal.compiler@dependencies=com.oracle.graal.api.runtime,com.oracle.graal.virtual,com.oracle.graal.loop,com.oracle.graal.alloc,com.oracle.graal.lir project@com.oracle.graal.compiler@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.compiler@javaCompliance=1.7 +project@com.oracle.graal.compiler@javaCompliance=1.8 project@com.oracle.graal.compiler@annotationProcessors=com.oracle.graal.service.processor project@com.oracle.graal.compiler@workingSets=Graal @@ -414,7 +414,7 @@ project@com.oracle.graal.compiler.amd64@sourceDirs=src project@com.oracle.graal.compiler.amd64@dependencies=com.oracle.graal.compiler,com.oracle.graal.lir.amd64 project@com.oracle.graal.compiler.amd64@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.compiler.amd64@javaCompliance=1.7 +project@com.oracle.graal.compiler.amd64@javaCompliance=1.8 project@com.oracle.graal.compiler.amd64@workingSets=Graal,AMD64 # graal.compiler.amd64.test @@ -422,7 +422,7 @@ project@com.oracle.graal.compiler.amd64.test@sourceDirs=src project@com.oracle.graal.compiler.amd64.test@dependencies=com.oracle.graal.compiler.test project@com.oracle.graal.compiler.amd64.test@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.compiler.amd64.test@javaCompliance=1.7 +project@com.oracle.graal.compiler.amd64.test@javaCompliance=1.8 project@com.oracle.graal.compiler.amd64.test@workingSets=Graal,AMD64,Test # graal.compiler.ptx @@ -430,7 +430,7 @@ project@com.oracle.graal.compiler.ptx@sourceDirs=src project@com.oracle.graal.compiler.ptx@dependencies=com.oracle.graal.lir.ptx,com.oracle.graal.compiler project@com.oracle.graal.compiler.ptx@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.compiler.ptx@javaCompliance=1.7 +project@com.oracle.graal.compiler.ptx@javaCompliance=1.8 project@com.oracle.graal.compiler.ptx@workingSets=Graal,PTX # graal.compiler.ptx.test @@ -438,7 +438,7 @@ project@com.oracle.graal.compiler.ptx.test@sourceDirs=src project@com.oracle.graal.compiler.ptx.test@dependencies=com.oracle.graal.hotspot.ptx,com.oracle.graal.compiler.test project@com.oracle.graal.compiler.ptx.test@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.compiler.ptx.test@javaCompliance=1.7 +project@com.oracle.graal.compiler.ptx.test@javaCompliance=1.8 project@com.oracle.graal.compiler.ptx.test@workingSets=Graal,PTX,Test # graal.compiler.sparc @@ -446,7 +446,7 @@ project@com.oracle.graal.compiler.sparc@sourceDirs=src project@com.oracle.graal.compiler.sparc@dependencies=com.oracle.graal.lir.sparc project@com.oracle.graal.compiler.sparc@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.compiler.sparc@javaCompliance=1.7 +project@com.oracle.graal.compiler.sparc@javaCompliance=1.8 project@com.oracle.graal.compiler.sparc@workingSets=Graal,SPARC # graal.compiler.sparc.test @@ -454,7 +454,7 @@ project@com.oracle.graal.compiler.sparc.test@sourceDirs=src project@com.oracle.graal.compiler.sparc.test@dependencies=com.oracle.graal.compiler.test project@com.oracle.graal.compiler.sparc.test@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.compiler.sparc.test@javaCompliance=1.7 +project@com.oracle.graal.compiler.sparc.test@javaCompliance=1.8 project@com.oracle.graal.compiler.sparc.test@workingSets=Graal,SPARC,Test # graal.runtime @@ -462,14 +462,14 @@ project@com.oracle.graal.runtime@sourceDirs=src project@com.oracle.graal.runtime@dependencies=com.oracle.graal.compiler project@com.oracle.graal.runtime@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.runtime@javaCompliance=1.7 +project@com.oracle.graal.runtime@javaCompliance=1.8 project@com.oracle.graal.runtime@workingSets=Graal # graal.bytecode project@com.oracle.graal.bytecode@subDir=graal project@com.oracle.graal.bytecode@sourceDirs=src project@com.oracle.graal.bytecode@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.bytecode@javaCompliance=1.7 +project@com.oracle.graal.bytecode@javaCompliance=1.8 project@com.oracle.graal.bytecode@workingSets=Graal,Java # graal.java @@ -477,7 +477,7 @@ project@com.oracle.graal.java@sourceDirs=src project@com.oracle.graal.java@dependencies=com.oracle.graal.phases,com.oracle.graal.bytecode project@com.oracle.graal.java@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.java@javaCompliance=1.7 +project@com.oracle.graal.java@javaCompliance=1.8 project@com.oracle.graal.java@workingSets=Graal,Java # graal.baseline @@ -485,7 +485,7 @@ project@com.oracle.graal.baseline@sourceDirs=src project@com.oracle.graal.baseline@dependencies=com.oracle.graal.java,com.oracle.graal.lir,com.oracle.graal.compiler project@com.oracle.graal.baseline@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.baseline@javaCompliance=1.7 +project@com.oracle.graal.baseline@javaCompliance=1.8 project@com.oracle.graal.baseline@workingSets=Graal,Java # graal.java.decompiler @@ -493,7 +493,7 @@ project@com.oracle.graal.java.decompiler@sourceDirs=src project@com.oracle.graal.java.decompiler@dependencies=com.oracle.graal.java project@com.oracle.graal.java.decompiler@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.java.decompiler@javaCompliance=1.7 +project@com.oracle.graal.java.decompiler@javaCompliance=1.8 project@com.oracle.graal.java.decompiler@workingSets=Graal # graal.java.decompiler.test @@ -501,7 +501,7 @@ project@com.oracle.graal.java.decompiler.test@sourceDirs=src project@com.oracle.graal.java.decompiler.test@dependencies=JUNIT,com.oracle.graal.printer,com.oracle.graal.runtime project@com.oracle.graal.java.decompiler.test@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.java.decompiler.test@javaCompliance=1.7 +project@com.oracle.graal.java.decompiler.test@javaCompliance=1.8 project@com.oracle.graal.java.decompiler.test@workingSets=Graal,Test # graal.printer @@ -509,7 +509,7 @@ project@com.oracle.graal.printer@sourceDirs=src project@com.oracle.graal.printer@dependencies=com.oracle.graal.java.decompiler,com.oracle.graal.compiler project@com.oracle.graal.printer@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.printer@javaCompliance=1.7 +project@com.oracle.graal.printer@javaCompliance=1.8 project@com.oracle.graal.printer@workingSets=Graal,Graph # graal.test @@ -517,7 +517,7 @@ project@com.oracle.graal.test@sourceDirs=src project@com.oracle.graal.test@dependencies=JUNIT project@com.oracle.graal.test@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.test@javaCompliance=1.7 +project@com.oracle.graal.test@javaCompliance=1.8 project@com.oracle.graal.test@workingSets=Graal,Test # graal.compiler.test @@ -525,7 +525,7 @@ project@com.oracle.graal.compiler.test@sourceDirs=src project@com.oracle.graal.compiler.test@dependencies=com.oracle.graal.test,com.oracle.graal.printer,com.oracle.graal.runtime,com.oracle.graal.baseline,JAVA_ALLOCATION_INSTRUMENTER project@com.oracle.graal.compiler.test@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.compiler.test@javaCompliance=1.7 +project@com.oracle.graal.compiler.test@javaCompliance=1.8 project@com.oracle.graal.compiler.test@workingSets=Graal,Test # graal.jtt @@ -533,7 +533,7 @@ project@com.oracle.graal.jtt@sourceDirs=src project@com.oracle.graal.jtt@dependencies=com.oracle.graal.compiler.test project@com.oracle.graal.jtt@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.jtt@javaCompliance=1.7 +project@com.oracle.graal.jtt@javaCompliance=1.8 project@com.oracle.graal.jtt@workingSets=Graal,Test # graal.asm @@ -541,7 +541,7 @@ project@com.oracle.graal.asm@sourceDirs=src project@com.oracle.graal.asm@dependencies=com.oracle.graal.api.code project@com.oracle.graal.asm@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.asm@javaCompliance=1.7 +project@com.oracle.graal.asm@javaCompliance=1.8 project@com.oracle.graal.asm@workingSets=Graal,Assembler # graal.asm.test @@ -549,7 +549,7 @@ project@com.oracle.graal.asm.test@sourceDirs=src project@com.oracle.graal.asm.test@dependencies=com.oracle.graal.test,com.oracle.graal.runtime project@com.oracle.graal.asm.test@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.asm.test@javaCompliance=1.7 +project@com.oracle.graal.asm.test@javaCompliance=1.8 project@com.oracle.graal.asm.test@workingSets=Graal,Assembler,Test # graal.asm.amd64 @@ -557,7 +557,7 @@ project@com.oracle.graal.asm.amd64@sourceDirs=src project@com.oracle.graal.asm.amd64@dependencies=com.oracle.graal.asm,com.oracle.graal.amd64 project@com.oracle.graal.asm.amd64@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.asm.amd64@javaCompliance=1.7 +project@com.oracle.graal.asm.amd64@javaCompliance=1.8 project@com.oracle.graal.asm.amd64@workingSets=Graal,Assembler,AMD64 # graal.asm.amd64.test @@ -565,7 +565,7 @@ project@com.oracle.graal.asm.amd64.test@sourceDirs=src project@com.oracle.graal.asm.amd64.test@dependencies=com.oracle.graal.asm.test,com.oracle.graal.asm.amd64 project@com.oracle.graal.asm.amd64.test@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.asm.amd64.test@javaCompliance=1.7 +project@com.oracle.graal.asm.amd64.test@javaCompliance=1.8 project@com.oracle.graal.asm.amd64.test@workingSets=Graal,Assembler,AMD64,Test # graal.hsail @@ -573,49 +573,49 @@ project@com.oracle.graal.hsail@sourceDirs=src project@com.oracle.graal.hsail@dependencies=com.oracle.graal.graph project@com.oracle.graal.hsail@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.hsail@javaCompliance=1.7 +project@com.oracle.graal.hsail@javaCompliance=1.8 # graal.lir.hsail project@com.oracle.graal.lir.hsail@subDir=graal project@com.oracle.graal.lir.hsail@sourceDirs=src project@com.oracle.graal.lir.hsail@dependencies=com.oracle.graal.lir,com.oracle.graal.asm.hsail project@com.oracle.graal.lir.hsail@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.lir.hsail@javaCompliance=1.7 +project@com.oracle.graal.lir.hsail@javaCompliance=1.8 # graal.compiler.hsail project@com.oracle.graal.compiler.hsail@subDir=graal project@com.oracle.graal.compiler.hsail@sourceDirs=src project@com.oracle.graal.compiler.hsail@dependencies=com.oracle.graal.compiler,com.oracle.graal.lir.hsail project@com.oracle.graal.compiler.hsail@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.compiler.hsail@javaCompliance=1.7 +project@com.oracle.graal.compiler.hsail@javaCompliance=1.8 # graal.compiler.hsail.test.infra - HSAIL compiler test infrastructure project@com.oracle.graal.compiler.hsail.test.infra@subDir=graal project@com.oracle.graal.compiler.hsail.test.infra@sourceDirs=src project@com.oracle.graal.compiler.hsail.test.infra@dependencies=com.oracle.graal.hotspot.hsail,JUNIT,OKRA_WITH_SIM project@com.oracle.graal.compiler.hsail.test.infra@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.compiler.hsail.test.infra@javaCompliance=1.7 +project@com.oracle.graal.compiler.hsail.test.infra@javaCompliance=1.8 # graal.compiler.hsail.test project@com.oracle.graal.compiler.hsail.test@subDir=graal project@com.oracle.graal.compiler.hsail.test@sourceDirs=src project@com.oracle.graal.compiler.hsail.test@dependencies=com.oracle.graal.compiler.hsail.test.infra,com.oracle.graal.compiler.test project@com.oracle.graal.compiler.hsail.test@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.compiler.hsail.test@javaCompliance=1.7 +project@com.oracle.graal.compiler.hsail.test@javaCompliance=1.8 # graal.asm.hsail project@com.oracle.graal.asm.hsail@subDir=graal project@com.oracle.graal.asm.hsail@sourceDirs=src project@com.oracle.graal.asm.hsail@dependencies=com.oracle.graal.hsail,OKRA,com.oracle.graal.asm project@com.oracle.graal.asm.hsail@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.asm.hsail@javaCompliance=1.7 +project@com.oracle.graal.asm.hsail@javaCompliance=1.8 # graal.asm.ptx project@com.oracle.graal.asm.ptx@subDir=graal project@com.oracle.graal.asm.ptx@sourceDirs=src project@com.oracle.graal.asm.ptx@dependencies=com.oracle.graal.lir project@com.oracle.graal.asm.ptx@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.asm.ptx@javaCompliance=1.7 +project@com.oracle.graal.asm.ptx@javaCompliance=1.8 project@com.oracle.graal.asm.ptx@workingSets=Graal,Assembler,PTX # graal.asm.sparc @@ -623,7 +623,7 @@ project@com.oracle.graal.asm.sparc@sourceDirs=src project@com.oracle.graal.asm.sparc@dependencies=com.oracle.graal.hotspot,com.oracle.graal.sparc project@com.oracle.graal.asm.sparc@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.asm.sparc@javaCompliance=1.7 +project@com.oracle.graal.asm.sparc@javaCompliance=1.8 project@com.oracle.graal.asm.sparc@workingSets=Graal,Assembler,SPARC # truffle.api @@ -688,7 +688,7 @@ project@com.oracle.graal.truffle@sourceDirs=src project@com.oracle.graal.truffle@dependencies=com.oracle.truffle.api,com.oracle.graal.replacements,com.oracle.graal.runtime,com.oracle.graal.printer project@com.oracle.graal.truffle@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.truffle@javaCompliance=1.7 +project@com.oracle.graal.truffle@javaCompliance=1.8 project@com.oracle.graal.truffle@workingSets=Graal,Truffle # graal.truffle.test @@ -696,7 +696,7 @@ project@com.oracle.graal.truffle.test@sourceDirs=src project@com.oracle.graal.truffle.test@dependencies=com.oracle.graal.truffle,com.oracle.graal.compiler.test project@com.oracle.graal.truffle.test@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.truffle.test@javaCompliance=1.7 +project@com.oracle.graal.truffle.test@javaCompliance=1.8 project@com.oracle.graal.truffle.test@workingSets=Graal,Truffle,Test # graal.truffle.hotspot @@ -704,7 +704,7 @@ project@com.oracle.graal.truffle.hotspot@sourceDirs=src project@com.oracle.graal.truffle.hotspot@dependencies=com.oracle.graal.truffle,com.oracle.graal.hotspot project@com.oracle.graal.truffle.hotspot@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.truffle.hotspot@javaCompliance=1.7 +project@com.oracle.graal.truffle.hotspot@javaCompliance=1.8 project@com.oracle.graal.truffle.hotspot@annotationProcessors=com.oracle.graal.service.processor project@com.oracle.graal.truffle.hotspot@workingSets=Graal,Truffle @@ -713,6 +713,6 @@ project@com.oracle.graal.truffle.hotspot.amd64@sourceDirs=src project@com.oracle.graal.truffle.hotspot.amd64@dependencies=com.oracle.graal.truffle.hotspot,com.oracle.graal.hotspot.amd64 project@com.oracle.graal.truffle.hotspot.amd64@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.truffle.hotspot.amd64@javaCompliance=1.7 +project@com.oracle.graal.truffle.hotspot.amd64@javaCompliance=1.8 project@com.oracle.graal.truffle.hotspot.amd64@annotationProcessors=com.oracle.graal.service.processor project@com.oracle.graal.truffle.hotspot.amd64@workingSets=Graal,Truffle diff -r 97a0878202c2 -r fbae9be45c95 mxtool/mx.py --- a/mxtool/mx.py Wed Mar 26 17:02:45 2014 +0100 +++ b/mxtool/mx.py Wed Mar 26 20:44:11 2014 +0100 @@ -54,7 +54,7 @@ _primary_suite_path = None _primary_suite = None _opts = None -_java = None +_java_homes = None _warn = False """ @@ -117,6 +117,13 @@ self.workingSets = workingSets self.dir = d + # Verify that a JDK exists for this project if its compliance level is + # less than the compliance level of the default JDK + jdk = java(self.javaCompliance) + if jdk is None and self.javaCompliance < java().javaCompliance: + abort('Cannot find ' + str(self.javaCompliance) + ' JDK required by ' + name + '. ' + + 'Specify it with --extra-java-homes option or EXTRA_JAVA_HOMES environment variable.') + # Create directories for projects that don't yet exist if not exists(d): os.mkdir(d) @@ -1036,7 +1043,8 @@ self.add_argument('--Jp', action='append', dest='java_args_pfx', help='prefix Java VM arguments (e.g. --Jp @-dsa)', metavar='@', default=[]) self.add_argument('--Ja', action='append', dest='java_args_sfx', help='suffix Java VM arguments (e.g. --Ja @-dsa)', metavar='@', default=[]) self.add_argument('--user-home', help='users home directory', metavar='', default=os.path.expanduser('~')) - self.add_argument('--java-home', help='bootstrap JDK installation directory (must be JDK 6 or later)', metavar='') + self.add_argument('--java-home', help='primary JDK directory (must be JDK 7 or later)', metavar='') + self.add_argument('--extra-java-homes', help='secondary JDK directories separated by "' + os.pathsep + '"', metavar='') self.add_argument('--ignore-project', action='append', dest='ignored_projects', help='name of project to ignore', metavar='', default=[]) self.add_argument('--kill-with-sigquit', action='store_true', dest='killwithsigquit', help='send sigquit first before killing child processes') if get_os() != 'windows': @@ -1061,6 +1069,8 @@ if opts.java_home is None: opts.java_home = os.environ.get('JAVA_HOME') + if opts.extra_java_homes is None: + opts.extra_java_homes = os.environ.get('EXTRA_JAVA_HOMES') if opts.java_home is None or opts.java_home == '': opts.java_home = _handle_missing_java_home() @@ -1089,12 +1099,21 @@ msg += ' {0:<20} {1}\n'.format(cmd, doc.split('\n', 1)[0]) return msg + '\n' -def java(): +def java(requiredCompliance=None): """ Get a JavaConfig object containing Java commands launch details. + If requiredCompliance is None, the compliance level specified by --java-home/JAVA_HOME + is returned. Otherwise, the JavaConfig exactly matching requiredCompliance is returned + or None if there is no exact match. """ - assert _java is not None - return _java + assert _java_homes + if not requiredCompliance: + return _java_homes[0] + for java in _java_homes: + if java.javaCompliance == requiredCompliance: + return java + return None + def run_java(args, nonZeroIsFatal=True, out=None, err=None, cwd=None, addDefaultArgs=True): return run(java().format_cmd(args, addDefaultArgs), nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, cwd=cwd) @@ -1350,9 +1369,9 @@ A JavaConfig object encapsulates info on how Java commands are run. """ class JavaConfig: - def __init__(self, opts): - self.jdk = opts.java_home - self.debug_port = opts.java_dbg_port + def __init__(self, java_home, java_dbg_port): + self.jdk = java_home + self.debug_port = java_dbg_port self.jar = exe_suffix(join(self.jdk, 'bin', 'jar')) self.java = exe_suffix(join(self.jdk, 'bin', 'java')) self.javac = exe_suffix(join(self.jdk, 'bin', 'javac')) @@ -1361,7 +1380,7 @@ self._bootclasspath = None if not exists(self.java): - abort('Java launcher derived from JAVA_HOME does not exist: ' + self.java) + abort('Java launcher does not exist: ' + self.java) def delAtAndSplit(s): return shlex.split(s.lstrip('@')) @@ -1389,6 +1408,14 @@ if self.debug_port is not None: self.java_args += ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(self.debug_port)] + def __hash__(self): + return hash(self.jdk) + + def __cmp__(self, other): + if isinstance(other, JavaConfig): + return cmp(self.javaCompliance, other.javaCompliance) + raise TypeError() + def format_cmd(self, args, addDefaultArgs): if addDefaultArgs: return [self.java] + self.processArgs(args) @@ -1624,14 +1651,12 @@ if not suppliedParser: parser = ArgumentParser(prog='mx build') - javaCompliance = java().javaCompliance - defaultEcjPath = get_env('JDT', join(_primary_suite.mxDir, 'ecj.jar')) parser = parser if parser is not None else ArgumentParser(prog='mx build') parser.add_argument('-f', action='store_true', dest='force', help='force build (disables timestamp checking)') parser.add_argument('-c', action='store_true', dest='clean', help='removes existing build output') - parser.add_argument('--source', dest='compliance', help='Java compliance level for projects without an explicit one', default=str(javaCompliance)) + parser.add_argument('--source', dest='compliance', help='Java compliance level for projects without an explicit one') parser.add_argument('--Wapi', action='store_true', dest='warnAPI', help='show warnings about using internal APIs') parser.add_argument('--projects', action='store', help='comma separated projects to build (omit to build all projects)') parser.add_argument('--only', action='store', help='comma separated projects to build, without checking their dependencies (omit to build all projects)') @@ -1710,9 +1735,12 @@ continue # skip building this Java project if its Java compliance level is "higher" than the configured JDK - if javaCompliance < p.javaCompliance: - log('Excluding {0} from build (Java compliance level {1} required)'.format(p.name, p.javaCompliance)) + requiredCompliance = p.javaCompliance if p.javaCompliance else JavaCompliance(args.compliance) if args.compliance else None + jdk = java(requiredCompliance) + if not jdk: + log('Excluding {0} from build (Java compliance level {1} required)'.format(p.name, requiredCompliance)) continue + compliance = str(jdk.javaCompliance) outputDir = prepareOutputDirs(p, args.clean) @@ -1817,14 +1845,11 @@ toBeDeleted = [argfileName] try: - compliance = str(p.javaCompliance) if p.javaCompliance is not None else args.compliance if jdtJar is None: log('Compiling Java sources for {0} with javac...'.format(p.name)) - - - javacCmd = [java().javac, '-g', '-J-Xmx1g', '-source', compliance, '-target', compliance, '-classpath', cp, '-d', outputDir] - if java().debug_port is not None: - javacCmd += ['-J-Xdebug', '-J-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(java().debug_port)] + javacCmd = [jdk.javac, '-g', '-J-Xmx1g', '-source', compliance, '-target', compliance, '-classpath', cp, '-d', outputDir] + if jdk.debug_port is not None: + javacCmd += ['-J-Xdebug', '-J-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(jdk.debug_port)] javacCmd += processorArgs javacCmd += ['@' + argfile.name] @@ -1834,9 +1859,9 @@ else: log('Compiling Java sources for {0} with JDT...'.format(p.name)) - jdtArgs = [java().java, '-Xmx1g'] - if java().debug_port is not None: - jdtArgs += ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(java().debug_port)] + jdtArgs = [jdk.java, '-Xmx1g'] + if jdk.debug_port is not None: + jdtArgs += ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(jdk.debug_port)] jdtArgs += ['-jar', jdtJar, '-' + compliance, @@ -1912,13 +1937,14 @@ projects = [project(name) for name in args.projects.split(',')] class Batch: - def __init__(self, settingsFile): + def __init__(self, settingsFile, javaCompliance): self.path = settingsFile + self.javaCompliance = javaCompliance self.javafiles = list() def settings(self): with open(self.path) as fp: - return fp.read() + return fp.read() + java(self.javaCompliance).java class FileInfo: def __init__(self, path): @@ -1943,7 +1969,7 @@ continue sourceDirs = p.source_dirs() - batch = Batch(join(p.dir, '.settings', 'org.eclipse.jdt.core.prefs')) + batch = Batch(join(p.dir, '.settings', 'org.eclipse.jdt.core.prefs'), p.javaCompliance) if not exists(batch.path): if _opts.verbose: @@ -1962,8 +1988,15 @@ if res is not batch: res.javafiles = res.javafiles + batch.javafiles + print "we have: " + str(len(batches)) + " batches" for batch in batches.itervalues(): - run([args.eclipse_exe, '-nosplash', '-application', 'org.eclipse.jdt.core.JavaCodeFormatter', '-config', batch.path] + [f.path for f in batch.javafiles]) + run([args.eclipse_exe, + '-nosplash', + '-application', + 'org.eclipse.jdt.core.JavaCodeFormatter', + '-vm', java(batch.javaCompliance).java, + '-config', batch.path] + + [f.path for f in batch.javafiles]) for fi in batch.javafiles: if fi.update(): modified.append(fi) @@ -2115,7 +2148,8 @@ else: p = dep # skip a Java project if its Java compliance level is "higher" than the configured JDK - if java().javaCompliance < p.javaCompliance: + jdk = java(p.javaCompliance) + if not jdk: log('Excluding {0} from {2} (Java compliance level {1} required)'.format(p.name, p.javaCompliance, d.path)) continue @@ -2296,7 +2330,8 @@ abort('ERROR: .checkstyle for Project {0} is missing'.format(p.name)) # skip checking this Java project if its Java compliance level is "higher" than the configured JDK - if java().javaCompliance < p.javaCompliance: + jdk = java(p.javaCompliance) + if not jdk: log('Excluding {0} from checking (Java compliance level {1} required)'.format(p.name, p.javaCompliance)) continue @@ -2720,6 +2755,10 @@ if p.native: continue + if not java(p.javaCompliance): + log('Excluding {0} (JDK with compliance level {1} not available)'.format(p.name, p.javaCompliance)) + continue + if not exists(p.dir): os.makedirs(p.dir) @@ -2867,20 +2906,41 @@ if not exists(settingsDir): os.mkdir(settingsDir) + # collect the defaults from mxtool + defaultEclipseSettingsDir = join(dirname(__file__), 'eclipse-settings') + esdict = {} + if exists(defaultEclipseSettingsDir): + for name in os.listdir(defaultEclipseSettingsDir): + if isfile(join(defaultEclipseSettingsDir, name)): + esdict[name] = os.path.abspath(join(defaultEclipseSettingsDir, name)) + + # check for suite overrides eclipseSettingsDir = join(p.suite.mxDir, 'eclipse-settings') if exists(eclipseSettingsDir): for name in os.listdir(eclipseSettingsDir): - if name == "org.eclipse.jdt.apt.core.prefs" and not len(p.annotation_processors()) > 0: - continue - path = join(eclipseSettingsDir, name) - if isfile(path): - with open(join(eclipseSettingsDir, name)) as f: - content = f.read() - content = content.replace('${javaCompliance}', str(p.javaCompliance)) - if len(p.annotation_processors()) > 0: - content = content.replace('org.eclipse.jdt.core.compiler.processAnnotations=disabled', 'org.eclipse.jdt.core.compiler.processAnnotations=enabled') - update_file(join(settingsDir, name), content) - files.append(join(settingsDir, name)) + if isfile(join(eclipseSettingsDir, name)): + esdict[name] = os.path.abspath(join(eclipseSettingsDir, name)) + + # check for project overrides + projectSettingsDir = join(p.dir, 'eclipse-settings') + if exists(projectSettingsDir): + for name in os.listdir(projectSettingsDir): + if isfile(join(projectSettingsDir, name)): + esdict[name] = os.path.abspath(join(projectSettingsDir, name)) + + # copy a possibly modified file to the project's .settings directory + for name, path in esdict.iteritems(): + # ignore this file altogether if this project has no annotation processors + if name == "org.eclipse.jdt.apt.core.prefs" and not len(p.annotation_processors()) > 0: + continue + + with open(path) as f: + content = f.read() + content = content.replace('${javaCompliance}', str(p.javaCompliance)) + if len(p.annotation_processors()) > 0: + content = content.replace('org.eclipse.jdt.core.compiler.processAnnotations=disabled', 'org.eclipse.jdt.core.compiler.processAnnotations=enabled') + update_file(join(settingsDir, name), content) + files.append(join(settingsDir, name)) if len(p.annotation_processors()) > 0: out = XMLDoc() @@ -2943,7 +3003,7 @@ launchOut.open('launchConfiguration', {'type' : 'org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType'}) launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.core.capture_output', 'value': consoleOn}) launchOut.open('mapAttribute', {'key' : 'org.eclipse.debug.core.environmentVariables'}) - launchOut.element('mapEntry', {'key' : 'JAVA_HOME', 'value' : java().jdk}) + launchOut.element('mapEntry', {'key' : 'JAVA_HOME', 'value' : java(p.javaCompliance).jdk}) launchOut.close('mapAttribute') if refresh: @@ -3190,6 +3250,7 @@ updated = False files = [] libFiles = [] + jdks = set() for p in suite.projects: if p.native: continue @@ -3200,13 +3261,21 @@ if not exists(join(p.dir, 'nbproject')): os.makedirs(join(p.dir, 'nbproject')) + jdk = java(p.javaCompliance) + + if not jdk: + log('Excluding {0} (JDK with compliance level {1} not available)'.format(p.name, p.javaCompliance)) + continue + + jdks.add(jdk) + out = XMLDoc() out.open('project', {'name' : p.name, 'default' : 'default', 'basedir' : '.'}) out.element('description', data='Builds, tests, and runs the project ' + p.name + '.') out.element('import', {'file' : 'nbproject/build-impl.xml'}) out.open('target', {'name' : '-post-compile'}) out.open('exec', {'executable' : sys.executable}) - out.element('env', {'key' : 'JAVA_HOME', 'value' : java().jdk}) + out.element('env', {'key' : 'JAVA_HOME', 'value' : jdk.jdk}) out.element('arg', {'value' : os.path.abspath(__file__)}) out.element('arg', {'value' : 'archive'}) out.element('arg', {'value' : '@GRAAL'}) @@ -3261,7 +3330,7 @@ files.append(join(p.dir, 'nbproject', 'project.xml')) out = StringIO.StringIO() - jdkPlatform = 'JDK_' + str(java().version) + jdkPlatform = 'JDK_' + str(jdk.version) annotationProcessorEnabled = "false" annotationProcessorReferences = "" @@ -3324,7 +3393,7 @@ manifest.file=manifest.mf meta.inf.dir=${src.dir}/META-INF mkdist.disabled=false -platforms.""" + jdkPlatform + """.home=""" + java().jdk + """ +platforms.""" + jdkPlatform + """.home=""" + jdk.jdk + """ platform.active=""" + jdkPlatform + """ run.classpath=\\ ${javac.classpath}:\\ @@ -3404,7 +3473,9 @@ if updated: log('If using NetBeans:') - log(' 1. Ensure that a platform named "JDK_' + str(java().version) + '" is defined (Tools -> Java Platforms)') + log(' 1. Ensure that the following platform(s) are defined (Tools -> Java Platforms):') + for jdk in jdks: + log(' JDK_' + str(jdk.version)) log(' 2. Open/create a Project Group for the directory containing the projects (File -> Project Group -> New Group... -> Folder of Projects)') _zip_files(files, suite.dir, configZip.path) @@ -3575,7 +3646,7 @@ windowTitle = ['-windowtitle', p.name + ' javadoc'] try: log('Generating {2} for {0} in {1}'.format(p.name, out, docDir)) - run([java().javadoc, memory, + run([java(p.javaCompliance).javadoc, memory, '-XDignore.symbol.file', '-classpath', cp, '-quiet', @@ -3604,7 +3675,7 @@ sp += p.source_dirs() names.append(p.name) - links = ['-link', 'http://docs.oracle.com/javase/' + str(_java.javaCompliance.value) + '/docs/api/'] + links = ['-link', 'http://docs.oracle.com/javase/' + str(java().javaCompliance.value) + '/docs/api/'] out = join(_primary_suite.dir, docDir) if args.base is not None: out = join(args.base, docDir) @@ -4084,9 +4155,16 @@ opts, commandAndArgs = _argParser._parse_cmd_line() - global _opts, _java + global _opts, _java_homes _opts = opts - _java = JavaConfig(opts) + defaultJdk = JavaConfig(opts.java_home, opts.java_dbg_port) + _java_homes = [defaultJdk] + if opts.extra_java_homes: + for java_home in opts.extra_java_homes.split(os.pathsep): + extraJdk = JavaConfig(java_home, opts.java_dbg_port) + if extraJdk > defaultJdk: + abort('Secondary JDK ' + extraJdk.jdk + ' has higher compliance level than default JDK ' + defaultJdk.jdk) + _java_homes.append(extraJdk) for s in suites(): s._post_init(opts) diff -r 97a0878202c2 -r fbae9be45c95 src/cpu/sparc/vm/graalGlobals_sparc.hpp --- a/src/cpu/sparc/vm/graalGlobals_sparc.hpp Wed Mar 26 17:02:45 2014 +0100 +++ b/src/cpu/sparc/vm/graalGlobals_sparc.hpp Wed Mar 26 20:44:11 2014 +0100 @@ -45,7 +45,7 @@ define_pd_global(intx, NewSizeThreadIncrease, 4*K ); define_pd_global(uintx,MetaspaceSize, 12*M ); define_pd_global(bool, NeverActAsServerClassMachine, false); -define_pd_global(uint64_t,MaxRAM, 1ULL*G); +define_pd_global(uint64_t,MaxRAM, 128ULL*G); define_pd_global(bool, CICompileOSR, true ); define_pd_global(bool, ProfileTraps, true ); define_pd_global(bool, UseOnStackReplacement, true ); diff -r 97a0878202c2 -r fbae9be45c95 src/cpu/x86/vm/graalGlobals_x86.hpp --- a/src/cpu/x86/vm/graalGlobals_x86.hpp Wed Mar 26 17:02:45 2014 +0100 +++ b/src/cpu/x86/vm/graalGlobals_x86.hpp Wed Mar 26 20:44:11 2014 +0100 @@ -45,7 +45,7 @@ define_pd_global(intx, NewSizeThreadIncrease, 4*K ); define_pd_global(uintx,MetaspaceSize, 12*M ); define_pd_global(bool, NeverActAsServerClassMachine, false); -define_pd_global(uint64_t,MaxRAM, 1ULL*G); +define_pd_global(uint64_t,MaxRAM, 128ULL*G); define_pd_global(bool, CICompileOSR, true ); define_pd_global(bool, ProfileTraps, true ); define_pd_global(bool, UseOnStackReplacement, true ); diff -r 97a0878202c2 -r fbae9be45c95 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Wed Mar 26 17:02:45 2014 +0100 +++ b/src/share/vm/classfile/systemDictionary.hpp Wed Mar 26 20:44:11 2014 +0100 @@ -184,6 +184,7 @@ do_klass(Long_klass, java_lang_Long, Pre ) \ \ /* Support for Graal */ \ + do_klass(CompilerThread_klass, com_oracle_graal_compiler_CompilerThread, Opt) \ do_klass(BitSet_klass, java_util_BitSet, Opt) \ /* graal.hotspot */ \ do_klass(HotSpotCompiledCode_klass, com_oracle_graal_hotspot_HotSpotCompiledCode, Opt) \ @@ -203,7 +204,6 @@ do_klass(HotSpotResolvedJavaMethod_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod, Opt) \ do_klass(HotSpotResolvedObjectType_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType, Opt) \ do_klass(HotSpotMonitorValue_klass, com_oracle_graal_hotspot_meta_HotSpotMonitorValue, Opt) \ - do_klass(CompilerThread_klass, com_oracle_graal_hotspot_CompilerThread, Opt) \ /* graal.api.code */ \ do_klass(Assumptions_klass, com_oracle_graal_api_code_Assumptions, Opt) \ do_klass(Assumptions_ConcreteMethod_klass, com_oracle_graal_api_code_Assumptions_ConcreteMethod, Opt) \ diff -r 97a0878202c2 -r fbae9be45c95 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Wed Mar 26 17:02:45 2014 +0100 +++ b/src/share/vm/classfile/vmSymbols.hpp Wed Mar 26 20:44:11 2014 +0100 @@ -288,10 +288,11 @@ NOT_LP64( do_alias(intptr_signature, int_signature) ) \ LP64_ONLY( do_alias(intptr_signature, long_signature) ) \ template(selectAlternative_signature, "(ZLjava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;") \ - \ - /* Support for Graal */ \ - template(java_util_BitSet, "java/util/BitSet") \ - /* graal.hotspot */ \ + \ + /* Support for Graal */ \ + template(com_oracle_graal_compiler_CompilerThread, "com/oracle/graal/compiler/CompilerThread") \ + template(java_util_BitSet, "java/util/BitSet") \ + /* graal.hotspot */ \ template(com_oracle_graal_hotspot_HotSpotGraalRuntime, "com/oracle/graal/hotspot/HotSpotGraalRuntime") \ template(com_oracle_graal_hotspot_HotSpotKlassOop, "com/oracle/graal/hotspot/HotSpotKlassOop") \ template(com_oracle_graal_hotspot_HotSpotOptions, "com/oracle/graal/hotspot/HotSpotOptions") \ @@ -314,7 +315,6 @@ template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod, "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod") \ template(com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType, "com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType") \ template(com_oracle_graal_hotspot_meta_HotSpotMonitorValue, "com/oracle/graal/hotspot/meta/HotSpotMonitorValue") \ - template(com_oracle_graal_hotspot_CompilerThread, "com/oracle/graal/hotspot/CompilerThread") \ /* graal.api.meta */ \ template(com_oracle_graal_api_meta_Constant, "com/oracle/graal/api/meta/Constant") \ template(com_oracle_graal_api_meta_ConstantPool, "com/oracle/graal/api/meta/ConstantPool") \ diff -r 97a0878202c2 -r fbae9be45c95 src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp Wed Mar 26 17:02:45 2014 +0100 +++ b/src/share/vm/code/nmethod.cpp Wed Mar 26 20:44:11 2014 +0100 @@ -105,7 +105,6 @@ // PrintC1Statistics, PrintOptoStatistics, LogVMOutput, and LogCompilation. // (In the latter two cases, they like other stats are printed to the log only.) -#ifndef PRODUCT // These variables are put into one block to reduce relocations // and make it simpler to print from the debugger. struct java_nmethod_stats_struct { @@ -233,7 +232,6 @@ unknown_java_nmethod_stats.note_nmethod(nm); } } -#endif //--------------------------------------------------------------------------------- @@ -536,7 +534,7 @@ code_buffer, frame_size, basic_lock_owner_sp_offset, basic_lock_sp_offset, oop_maps); - NOT_PRODUCT(if (nm != NULL) note_java_nmethod(nm)); + if (nm != NULL) note_java_nmethod(nm); if (PrintAssembly && nm != NULL) { Disassembler::decode(nm); } @@ -572,7 +570,7 @@ nm = new (nmethod_size) nmethod(method(), nmethod_size, &offsets, code_buffer, frame_size); - NOT_PRODUCT(if (nm != NULL) note_java_nmethod(nm)); + if (nm != NULL) note_java_nmethod(nm); if (PrintAssembly && nm != NULL) { Disassembler::decode(nm); } @@ -652,7 +650,7 @@ // record this nmethod as dependent on this klass InstanceKlass::cast(klass)->add_dependent_nmethod(nm); } - NOT_PRODUCT(if (nm != NULL) note_java_nmethod(nm)); + if (nm != NULL) note_java_nmethod(nm); if (PrintAssembly || CompilerOracle::has_option_string(method, "PrintAssembly")) { Disassembler::decode(nm); } @@ -3058,6 +3056,7 @@ void nmethod::print_nul_chk_table() { ImplicitExceptionTable(this).print(code_begin()); } +#endif // PRODUCT void nmethod::print_statistics() { ttyLocker ttyl; @@ -3078,4 +3077,3 @@ Dependencies::print_statistics(); if (xtty != NULL) xtty->tail("statistics"); } -#endif // PRODUCT diff -r 97a0878202c2 -r fbae9be45c95 src/share/vm/code/nmethod.hpp --- a/src/share/vm/code/nmethod.hpp Wed Mar 26 17:02:45 2014 +0100 +++ b/src/share/vm/code/nmethod.hpp Wed Mar 26 20:44:11 2014 +0100 @@ -694,7 +694,7 @@ // Prints a comment for one native instruction (reloc info, pc desc) void print_code_comment_on(outputStream* st, int column, address begin, address end); - static void print_statistics() PRODUCT_RETURN; + static void print_statistics(); // Compiler task identification. Note that all OSR methods // are numbered in an independent sequence if CICountOSR is true, diff -r 97a0878202c2 -r fbae9be45c95 src/share/vm/compiler/disassembler.cpp --- a/src/share/vm/compiler/disassembler.cpp Wed Mar 26 17:02:45 2014 +0100 +++ b/src/share/vm/compiler/disassembler.cpp Wed Mar 26 20:44:11 2014 +0100 @@ -159,397 +159,397 @@ nmethod* _nm; CodeBlob* _code; CodeStrings _strings; - outputStream* _output; - address _start, _end; - - char _option_buf[512]; - char _print_raw; - bool _print_pc; - bool _print_bytes; - address _cur_insn; - int _total_ticks; - int _bytes_per_line; // arch-specific formatting option - - static bool match(const char* event, const char* tag) { - size_t taglen = strlen(tag); - if (strncmp(event, tag, taglen) != 0) - return false; - char delim = event[taglen]; - return delim == '\0' || delim == ' ' || delim == '/' || delim == '='; - } - - void collect_options(const char* p) { - if (p == NULL || p[0] == '\0') return; - size_t opt_so_far = strlen(_option_buf); - if (opt_so_far + 1 + strlen(p) + 1 > sizeof(_option_buf)) return; - char* fillp = &_option_buf[opt_so_far]; - if (opt_so_far > 0) *fillp++ = ','; - strcat(fillp, p); - // replace white space by commas: - char* q = fillp; - while ((q = strpbrk(q, " \t\n")) != NULL) - *q++ = ','; - // Note that multiple PrintAssemblyOptions flags accumulate with \n, - // which we want to be changed to a comma... - } - - void print_insn_labels(); - void print_insn_bytes(address pc0, address pc); - void print_address(address value); - - public: + outputStream* _output; + address _start, _end; + + char _option_buf[512]; + char _print_raw; + bool _print_pc; + bool _print_bytes; + address _cur_insn; + int _total_ticks; + int _bytes_per_line; // arch-specific formatting option + + static bool match(const char* event, const char* tag) { + size_t taglen = strlen(tag); + if (strncmp(event, tag, taglen) != 0) + return false; + char delim = event[taglen]; + return delim == '\0' || delim == ' ' || delim == '/' || delim == '='; + } + + void collect_options(const char* p) { + if (p == NULL || p[0] == '\0') return; + size_t opt_so_far = strlen(_option_buf); + if (opt_so_far + 1 + strlen(p) + 1 > sizeof(_option_buf)) return; + char* fillp = &_option_buf[opt_so_far]; + if (opt_so_far > 0) *fillp++ = ','; + strcat(fillp, p); + // replace white space by commas: + char* q = fillp; + while ((q = strpbrk(q, " \t\n")) != NULL) + *q++ = ','; + // Note that multiple PrintAssemblyOptions flags accumulate with \n, + // which we want to be changed to a comma... + } + + void print_insn_labels(); + void print_insn_bytes(address pc0, address pc); + void print_address(address value); + + public: decode_env(CodeBlob* code, outputStream* output, CodeStrings c = CodeStrings()); - - address decode_instructions(address start, address end); - - void start_insn(address pc) { - _cur_insn = pc; - output()->bol(); - print_insn_labels(); - } - - void end_insn(address pc) { - address pc0 = cur_insn(); - outputStream* st = output(); - if (_print_bytes && pc > pc0) - print_insn_bytes(pc0, pc); - if (_nm != NULL) { - _nm->print_code_comment_on(st, COMMENT_COLUMN, pc0, pc); - // this calls reloc_string_for which calls oop::print_value_on - } - - // Output pc bucket ticks if we have any - if (total_ticks() != 0) { - address bucket_pc = FlatProfiler::bucket_start_for(pc); - if (bucket_pc != NULL && bucket_pc > pc0 && bucket_pc <= pc) { - int bucket_count = FlatProfiler::bucket_count_for(pc0); - if (bucket_count != 0) { - st->bol(); - st->print_cr("%3.1f%% [%d]", bucket_count*100.0/total_ticks(), bucket_count); - } - } - } - // follow each complete insn by a nice newline - st->cr(); - } - - address handle_event(const char* event, address arg); - - outputStream* output() { return _output; } - address cur_insn() { return _cur_insn; } - int total_ticks() { return _total_ticks; } - void set_total_ticks(int n) { _total_ticks = n; } - const char* options() { return _option_buf; } -}; - + + address decode_instructions(address start, address end); + + void start_insn(address pc) { + _cur_insn = pc; + output()->bol(); + print_insn_labels(); + } + + void end_insn(address pc) { + address pc0 = cur_insn(); + outputStream* st = output(); + if (_print_bytes && pc > pc0) + print_insn_bytes(pc0, pc); + if (_nm != NULL) { + _nm->print_code_comment_on(st, COMMENT_COLUMN, pc0, pc); + // this calls reloc_string_for which calls oop::print_value_on + } + + // Output pc bucket ticks if we have any + if (total_ticks() != 0) { + address bucket_pc = FlatProfiler::bucket_start_for(pc); + if (bucket_pc != NULL && bucket_pc > pc0 && bucket_pc <= pc) { + int bucket_count = FlatProfiler::bucket_count_for(pc0); + if (bucket_count != 0) { + st->bol(); + st->print_cr("%3.1f%% [%d]", bucket_count*100.0/total_ticks(), bucket_count); + } + } + } + // follow each complete insn by a nice newline + st->cr(); + } + + address handle_event(const char* event, address arg); + + outputStream* output() { return _output; } + address cur_insn() { return _cur_insn; } + int total_ticks() { return _total_ticks; } + void set_total_ticks(int n) { _total_ticks = n; } + const char* options() { return _option_buf; } +}; + decode_env::decode_env(CodeBlob* code, outputStream* output, CodeStrings c) { - memset(this, 0, sizeof(*this)); - _output = output ? output : tty; - _code = code; - if (code != NULL && code->is_nmethod()) - _nm = (nmethod*) code; + memset(this, 0, sizeof(*this)); + _output = output ? output : tty; + _code = code; + if (code != NULL && code->is_nmethod()) + _nm = (nmethod*) code; _strings.assign(c); - - // by default, output pc but not bytes: - _print_pc = true; - _print_bytes = false; - _bytes_per_line = Disassembler::pd_instruction_alignment(); - - // parse the global option string: - collect_options(Disassembler::pd_cpu_opts()); - collect_options(PrintAssemblyOptions); - - if (strstr(options(), "hsdis-")) { - if (strstr(options(), "hsdis-print-raw")) - _print_raw = (strstr(options(), "xml") ? 2 : 1); - if (strstr(options(), "hsdis-print-pc")) - _print_pc = !_print_pc; - if (strstr(options(), "hsdis-print-bytes")) - _print_bytes = !_print_bytes; - } - if (strstr(options(), "help")) { - tty->print_cr("PrintAssemblyOptions help:"); - tty->print_cr(" hsdis-print-raw test plugin by requesting raw output"); - tty->print_cr(" hsdis-print-raw-xml test plugin by requesting raw xml"); - tty->print_cr(" hsdis-print-pc turn off PC printing (on by default)"); - tty->print_cr(" hsdis-print-bytes turn on instruction byte output"); - tty->print_cr("combined options: %s", options()); - } -} - -address decode_env::handle_event(const char* event, address arg) { - if (match(event, "insn")) { - start_insn(arg); - } else if (match(event, "/insn")) { - end_insn(arg); - } else if (match(event, "addr")) { - if (arg != NULL) { - print_address(arg); - return arg; - } - } else if (match(event, "mach")) { - static char buffer[32] = { 0, }; - if (strcmp(buffer, (const char*)arg) != 0 || - strlen((const char*)arg) > sizeof(buffer) - 1) { - // Only print this when the mach changes - strncpy(buffer, (const char*)arg, sizeof(buffer) - 1); - output()->print_cr("[Disassembling for mach='%s']", arg); - } - } else if (match(event, "format bytes-per-line")) { - _bytes_per_line = (int) (intptr_t) arg; - } else { - // ignore unrecognized markup - } - return NULL; -} - -// called by the disassembler to print out jump targets and data addresses -void decode_env::print_address(address adr) { - outputStream* st = _output; - - if (adr == NULL) { - st->print("NULL"); - return; - } - - int small_num = (int)(intptr_t)adr; - if ((intptr_t)adr == (intptr_t)small_num - && -1 <= small_num && small_num <= 9) { - st->print("%d", small_num); - return; - } - - if (Universe::is_fully_initialized()) { - if (StubRoutines::contains(adr)) { - StubCodeDesc* desc = StubCodeDesc::desc_for(adr); - if (desc == NULL) - desc = StubCodeDesc::desc_for(adr + frame::pc_return_offset); - if (desc != NULL) { - st->print("Stub::%s", desc->name()); - if (desc->begin() != adr) - st->print("%+d 0x%p",adr - desc->begin(), adr); - else if (WizardMode) st->print(" " PTR_FORMAT, adr); - return; - } - st->print("Stub:: " PTR_FORMAT, adr); - return; - } - - BarrierSet* bs = Universe::heap()->barrier_set(); - if (bs->kind() == BarrierSet::CardTableModRef && - adr == (address)((CardTableModRefBS*)(bs))->byte_map_base) { - st->print("word_map_base"); - if (WizardMode) st->print(" " INTPTR_FORMAT, (intptr_t)adr); - return; - } - - oop obj; - if (_nm != NULL - && (obj = _nm->embeddedOop_at(cur_insn())) != NULL - && (address) obj == adr - && Universe::heap()->is_in(obj) - && Universe::heap()->is_in(obj->klass())) { - julong c = st->count(); - obj->print_value_on(st); - if (st->count() == c) { - // No output. (Can happen in product builds.) - st->print("(a %s)", obj->klass()->external_name()); - } - return; - } - } - - // Fall through to a simple (hexadecimal) numeral. - st->print(PTR_FORMAT, adr); -} - -void decode_env::print_insn_labels() { - address p = cur_insn(); - outputStream* st = output(); - CodeBlob* cb = _code; - if (cb != NULL) { - cb->print_block_comment(st, p); - } + + // by default, output pc but not bytes: + _print_pc = true; + _print_bytes = false; + _bytes_per_line = Disassembler::pd_instruction_alignment(); + + // parse the global option string: + collect_options(Disassembler::pd_cpu_opts()); + collect_options(PrintAssemblyOptions); + + if (strstr(options(), "hsdis-")) { + if (strstr(options(), "hsdis-print-raw")) + _print_raw = (strstr(options(), "xml") ? 2 : 1); + if (strstr(options(), "hsdis-print-pc")) + _print_pc = !_print_pc; + if (strstr(options(), "hsdis-print-bytes")) + _print_bytes = !_print_bytes; + } + if (strstr(options(), "help")) { + tty->print_cr("PrintAssemblyOptions help:"); + tty->print_cr(" hsdis-print-raw test plugin by requesting raw output"); + tty->print_cr(" hsdis-print-raw-xml test plugin by requesting raw xml"); + tty->print_cr(" hsdis-print-pc turn off PC printing (on by default)"); + tty->print_cr(" hsdis-print-bytes turn on instruction byte output"); + tty->print_cr("combined options: %s", options()); + } +} + +address decode_env::handle_event(const char* event, address arg) { + if (match(event, "insn")) { + start_insn(arg); + } else if (match(event, "/insn")) { + end_insn(arg); + } else if (match(event, "addr")) { + if (arg != NULL) { + print_address(arg); + return arg; + } + } else if (match(event, "mach")) { + static char buffer[32] = { 0, }; + if (strcmp(buffer, (const char*)arg) != 0 || + strlen((const char*)arg) > sizeof(buffer) - 1) { + // Only print this when the mach changes + strncpy(buffer, (const char*)arg, sizeof(buffer) - 1); + output()->print_cr("[Disassembling for mach='%s']", arg); + } + } else if (match(event, "format bytes-per-line")) { + _bytes_per_line = (int) (intptr_t) arg; + } else { + // ignore unrecognized markup + } + return NULL; +} + +// called by the disassembler to print out jump targets and data addresses +void decode_env::print_address(address adr) { + outputStream* st = _output; + + if (adr == NULL) { + st->print("NULL"); + return; + } + + int small_num = (int)(intptr_t)adr; + if ((intptr_t)adr == (intptr_t)small_num + && -1 <= small_num && small_num <= 9) { + st->print("%d", small_num); + return; + } + + if (Universe::is_fully_initialized()) { + if (StubRoutines::contains(adr)) { + StubCodeDesc* desc = StubCodeDesc::desc_for(adr); + if (desc == NULL) + desc = StubCodeDesc::desc_for(adr + frame::pc_return_offset); + if (desc != NULL) { + st->print("Stub::%s", desc->name()); + if (desc->begin() != adr) + st->print("%+d 0x%p",adr - desc->begin(), adr); + else if (WizardMode) st->print(" " PTR_FORMAT, adr); + return; + } + st->print("Stub:: " PTR_FORMAT, adr); + return; + } + + BarrierSet* bs = Universe::heap()->barrier_set(); + if (bs->kind() == BarrierSet::CardTableModRef && + adr == (address)((CardTableModRefBS*)(bs))->byte_map_base) { + st->print("word_map_base"); + if (WizardMode) st->print(" " INTPTR_FORMAT, (intptr_t)adr); + return; + } + + oop obj; + if (_nm != NULL + && (obj = _nm->embeddedOop_at(cur_insn())) != NULL + && (address) obj == adr + && Universe::heap()->is_in(obj) + && Universe::heap()->is_in(obj->klass())) { + julong c = st->count(); + obj->print_value_on(st); + if (st->count() == c) { + // No output. (Can happen in product builds.) + st->print("(a %s)", obj->klass()->external_name()); + } + return; + } + } + + // Fall through to a simple (hexadecimal) numeral. + st->print(PTR_FORMAT, adr); +} + +void decode_env::print_insn_labels() { + address p = cur_insn(); + outputStream* st = output(); + CodeBlob* cb = _code; + if (cb != NULL) { + cb->print_block_comment(st, p); + } _strings.print_block_comment(st, (intptr_t)(p - _start)); - if (_print_pc) { - st->print(" " PTR_FORMAT ": ", p); - } -} - -void decode_env::print_insn_bytes(address pc, address pc_limit) { - outputStream* st = output(); - size_t incr = 1; - size_t perline = _bytes_per_line; - if ((size_t) Disassembler::pd_instruction_alignment() >= sizeof(int) - && !((uintptr_t)pc % sizeof(int)) - && !((uintptr_t)pc_limit % sizeof(int))) { - incr = sizeof(int); - if (perline % incr) perline += incr - (perline % incr); - } - while (pc < pc_limit) { - // tab to the desired column: - st->move_to(COMMENT_COLUMN); - address pc0 = pc; - address pc1 = pc + perline; - if (pc1 > pc_limit) pc1 = pc_limit; - for (; pc < pc1; pc += incr) { - if (pc == pc0) - st->print(BYTES_COMMENT); - else if ((uint)(pc - pc0) % sizeof(int) == 0) - st->print(" "); // put out a space on word boundaries - if (incr == sizeof(int)) - st->print("%08lx", *(int*)pc); - else st->print("%02x", (*pc)&0xFF); - } - st->cr(); - } -} - - -static void* event_to_env(void* env_pv, const char* event, void* arg) { - decode_env* env = (decode_env*) env_pv; - return env->handle_event(event, (address) arg); -} - -static int printf_to_env(void* env_pv, const char* format, ...) { - decode_env* env = (decode_env*) env_pv; - outputStream* st = env->output(); - size_t flen = strlen(format); - const char* raw = NULL; - if (flen == 0) return 0; - if (flen == 1 && format[0] == '\n') { st->bol(); return 1; } - if (flen < 2 || - strchr(format, '%') == NULL) { - raw = format; - } else if (format[0] == '%' && format[1] == '%' && - strchr(format+2, '%') == NULL) { - // happens a lot on machines with names like %foo - flen--; - raw = format+1; - } - if (raw != NULL) { - st->print_raw(raw, (int) flen); - return (int) flen; - } - va_list ap; - va_start(ap, format); - julong cnt0 = st->count(); - st->vprint(format, ap); - julong cnt1 = st->count(); - va_end(ap); - return (int)(cnt1 - cnt0); -} - -address decode_env::decode_instructions(address start, address end) { - _start = start; _end = end; - - assert(((((intptr_t)start | (intptr_t)end) % Disassembler::pd_instruction_alignment()) == 0), "misaligned insn addr"); - - const int show_bytes = false; // for disassembler debugging - - //_version = Disassembler::pd_cpu_version(); - - if (!Disassembler::can_decode()) { - return NULL; - } - - // decode a series of instructions and return the end of the last instruction - - if (_print_raw) { - // Print whatever the library wants to print, w/o fancy callbacks. - // This is mainly for debugging the library itself. - FILE* out = stdout; - FILE* xmlout = (_print_raw > 1 ? out : NULL); - return use_new_version ? - (address) - (*Disassembler::_decode_instructions_virtual)((uintptr_t)start, (uintptr_t)end, - start, end - start, - NULL, (void*) xmlout, - NULL, (void*) out, - options(), 0/*nice new line*/) - : - (address) - (*Disassembler::_decode_instructions)(start, end, - NULL, (void*) xmlout, - NULL, (void*) out, - options()); - } - - return use_new_version ? - (address) - (*Disassembler::_decode_instructions_virtual)((uintptr_t)start, (uintptr_t)end, - start, end - start, - &event_to_env, (void*) this, - &printf_to_env, (void*) this, - options(), 0/*nice new line*/) - : - (address) - (*Disassembler::_decode_instructions)(start, end, - &event_to_env, (void*) this, - &printf_to_env, (void*) this, - options()); -} - - -void Disassembler::decode(CodeBlob* cb, outputStream* st) { - if (!load_library()) return; - decode_env env(cb, st); - env.output()->print_cr("----------------------------------------------------------------------"); - env.output()->print_cr("%s at [" PTR_FORMAT ", " PTR_FORMAT "] %d bytes", cb->name(), cb->code_begin(), cb->code_end(), ((jlong)(cb->code_end() - cb->code_begin())) * sizeof(unsigned char*)); - env.decode_instructions(cb->code_begin(), cb->code_end()); -} - -void Disassembler::decode(address start, address end, outputStream* st, CodeStrings c) { - if (!load_library()) return; - decode_env env(CodeCache::find_blob_unsafe(start), st, c); - env.decode_instructions(start, end); -} - -void Disassembler::decode(nmethod* nm, outputStream* st) { - if (!load_library()) return; - decode_env env(nm, st); - env.output()->print_cr("----------------------------------------------------------------------"); - -#ifdef SHARK - SharkEntry* entry = (SharkEntry *) nm->code_begin(); - unsigned char* p = entry->code_start(); - unsigned char* end = entry->code_limit(); -#else - unsigned char* p = nm->code_begin(); - unsigned char* end = nm->code_end(); -#endif // SHARK - - nm->method()->method_holder()->name()->print_symbol_on(env.output()); - env.output()->print("."); - nm->method()->name()->print_symbol_on(env.output()); - env.output()->print_cr(" [" PTR_FORMAT ", " PTR_FORMAT "] %d bytes", p, end, ((jlong)(end - p)) * sizeof(unsigned char*)); - - // If there has been profiling, print the buckets. - if (FlatProfiler::bucket_start_for(p) != NULL) { - unsigned char* p1 = p; - int total_bucket_count = 0; - while (p1 < end) { - unsigned char* p0 = p1; - p1 += pd_instruction_alignment(); - address bucket_pc = FlatProfiler::bucket_start_for(p1); - if (bucket_pc != NULL && bucket_pc > p0 && bucket_pc <= p1) - total_bucket_count += FlatProfiler::bucket_count_for(p0); - } - env.set_total_ticks(total_bucket_count); - } - - // Print constant table. - if (nm->consts_size() > 0) { - nm->print_nmethod_labels(env.output(), nm->consts_begin()); - int offset = 0; - for (address p = nm->consts_begin(); p < nm->consts_end(); p += 4, offset += 4) { - if ((offset % 8) == 0) { - env.output()->print_cr(" " PTR_FORMAT " (offset: %4d): " PTR32_FORMAT " " PTR64_FORMAT, p, offset, *((int32_t*) p), *((int64_t*) p)); - } else { - env.output()->print_cr(" " PTR_FORMAT " (offset: %4d): " PTR32_FORMAT, p, offset, *((int32_t*) p)); - } - } - } - - env.decode_instructions(p, end); -} + if (_print_pc) { + st->print(" " PTR_FORMAT ": ", p); + } +} + +void decode_env::print_insn_bytes(address pc, address pc_limit) { + outputStream* st = output(); + size_t incr = 1; + size_t perline = _bytes_per_line; + if ((size_t) Disassembler::pd_instruction_alignment() >= sizeof(int) + && !((uintptr_t)pc % sizeof(int)) + && !((uintptr_t)pc_limit % sizeof(int))) { + incr = sizeof(int); + if (perline % incr) perline += incr - (perline % incr); + } + while (pc < pc_limit) { + // tab to the desired column: + st->move_to(COMMENT_COLUMN); + address pc0 = pc; + address pc1 = pc + perline; + if (pc1 > pc_limit) pc1 = pc_limit; + for (; pc < pc1; pc += incr) { + if (pc == pc0) + st->print(BYTES_COMMENT); + else if ((uint)(pc - pc0) % sizeof(int) == 0) + st->print(" "); // put out a space on word boundaries + if (incr == sizeof(int)) + st->print("%08lx", *(int*)pc); + else st->print("%02x", (*pc)&0xFF); + } + st->cr(); + } +} + + +static void* event_to_env(void* env_pv, const char* event, void* arg) { + decode_env* env = (decode_env*) env_pv; + return env->handle_event(event, (address) arg); +} + +static int printf_to_env(void* env_pv, const char* format, ...) { + decode_env* env = (decode_env*) env_pv; + outputStream* st = env->output(); + size_t flen = strlen(format); + const char* raw = NULL; + if (flen == 0) return 0; + if (flen == 1 && format[0] == '\n') { st->bol(); return 1; } + if (flen < 2 || + strchr(format, '%') == NULL) { + raw = format; + } else if (format[0] == '%' && format[1] == '%' && + strchr(format+2, '%') == NULL) { + // happens a lot on machines with names like %foo + flen--; + raw = format+1; + } + if (raw != NULL) { + st->print_raw(raw, (int) flen); + return (int) flen; + } + va_list ap; + va_start(ap, format); + julong cnt0 = st->count(); + st->vprint(format, ap); + julong cnt1 = st->count(); + va_end(ap); + return (int)(cnt1 - cnt0); +} + +address decode_env::decode_instructions(address start, address end) { + _start = start; _end = end; + + assert(((((intptr_t)start | (intptr_t)end) % Disassembler::pd_instruction_alignment()) == 0), "misaligned insn addr"); + + const int show_bytes = false; // for disassembler debugging + + //_version = Disassembler::pd_cpu_version(); + + if (!Disassembler::can_decode()) { + return NULL; + } + + // decode a series of instructions and return the end of the last instruction + + if (_print_raw) { + // Print whatever the library wants to print, w/o fancy callbacks. + // This is mainly for debugging the library itself. + FILE* out = stdout; + FILE* xmlout = (_print_raw > 1 ? out : NULL); + return use_new_version ? + (address) + (*Disassembler::_decode_instructions_virtual)((uintptr_t)start, (uintptr_t)end, + start, end - start, + NULL, (void*) xmlout, + NULL, (void*) out, + options(), 0/*nice new line*/) + : + (address) + (*Disassembler::_decode_instructions)(start, end, + NULL, (void*) xmlout, + NULL, (void*) out, + options()); + } + + return use_new_version ? + (address) + (*Disassembler::_decode_instructions_virtual)((uintptr_t)start, (uintptr_t)end, + start, end - start, + &event_to_env, (void*) this, + &printf_to_env, (void*) this, + options(), 0/*nice new line*/) + : + (address) + (*Disassembler::_decode_instructions)(start, end, + &event_to_env, (void*) this, + &printf_to_env, (void*) this, + options()); +} + + +void Disassembler::decode(CodeBlob* cb, outputStream* st) { + if (!load_library()) return; + decode_env env(cb, st); + env.output()->print_cr("----------------------------------------------------------------------"); + env.output()->print_cr("%s at [" PTR_FORMAT ", " PTR_FORMAT "] %d bytes", cb->name(), cb->code_begin(), cb->code_end(), ((jlong)(cb->code_end() - cb->code_begin())) * sizeof(unsigned char*)); + env.decode_instructions(cb->code_begin(), cb->code_end()); +} + +void Disassembler::decode(address start, address end, outputStream* st, CodeStrings c) { + if (!load_library()) return; + decode_env env(CodeCache::find_blob_unsafe(start), st, c); + env.decode_instructions(start, end); +} + +void Disassembler::decode(nmethod* nm, outputStream* st) { + if (!load_library()) return; + decode_env env(nm, st); + env.output()->print_cr("----------------------------------------------------------------------"); + +#ifdef SHARK + SharkEntry* entry = (SharkEntry *) nm->code_begin(); + unsigned char* p = entry->code_start(); + unsigned char* end = entry->code_limit(); +#else + unsigned char* p = nm->code_begin(); + unsigned char* end = nm->code_end(); +#endif // SHARK + + nm->method()->method_holder()->name()->print_symbol_on(env.output()); + env.output()->print("."); + nm->method()->name()->print_symbol_on(env.output()); + env.output()->print_cr(" [" PTR_FORMAT ", " PTR_FORMAT "] %d bytes", p, end, ((jlong)(end - p)) * sizeof(unsigned char*)); + + // If there has been profiling, print the buckets. + if (FlatProfiler::bucket_start_for(p) != NULL) { + unsigned char* p1 = p; + int total_bucket_count = 0; + while (p1 < end) { + unsigned char* p0 = p1; + p1 += pd_instruction_alignment(); + address bucket_pc = FlatProfiler::bucket_start_for(p1); + if (bucket_pc != NULL && bucket_pc > p0 && bucket_pc <= p1) + total_bucket_count += FlatProfiler::bucket_count_for(p0); + } + env.set_total_ticks(total_bucket_count); + } + + // Print constant table. + if (nm->consts_size() > 0) { + nm->print_nmethod_labels(env.output(), nm->consts_begin()); + int offset = 0; + for (address p = nm->consts_begin(); p < nm->consts_end(); p += 4, offset += 4) { + if ((offset % 8) == 0) { + env.output()->print_cr(" " PTR_FORMAT " (offset: %4d): " PTR32_FORMAT " " PTR64_FORMAT, p, offset, *((int32_t*) p), *((int64_t*) p)); + } else { + env.output()->print_cr(" " PTR_FORMAT " (offset: %4d): " PTR32_FORMAT, p, offset, *((int32_t*) p)); + } + } + } + + env.decode_instructions(p, end); +} diff -r 97a0878202c2 -r fbae9be45c95 src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Wed Mar 26 17:02:45 2014 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Wed Mar 26 20:44:11 2014 +0100 @@ -513,6 +513,8 @@ address dest = _constants->start() + CompilationResult_Site::pcOffset(patch); assert(!OopData::compressed(data), err_msg("unexpected compressed oop in data section")); _constants->relocate(dest, oop_Relocation::spec(oop_index)); + } else { + ShouldNotReachHere(); } } diff -r 97a0878202c2 -r fbae9be45c95 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Wed Mar 26 17:02:45 2014 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Wed Mar 26 20:44:11 2014 +0100 @@ -329,13 +329,9 @@ return (jlong) (address) klass->implementor(); C2V_END -C2V_VMENTRY(void, initializeMethod,(JNIEnv *, jobject, jlong metaspace_method, jobject hotspot_method)) +C2V_VMENTRY(jboolean, methodIsIgnoredBySecurityStackWalk,(JNIEnv *, jobject, jlong metaspace_method)) methodHandle method = asMethod(metaspace_method); - InstanceKlass::cast(HotSpotResolvedJavaMethod::klass())->initialize(CHECK); - HotSpotResolvedJavaMethod::set_callerSensitive(hotspot_method, method->caller_sensitive()); - HotSpotResolvedJavaMethod::set_forceInline(hotspot_method, method->force_inline()); - HotSpotResolvedJavaMethod::set_dontInline(hotspot_method, method->dont_inline()); - HotSpotResolvedJavaMethod::set_ignoredBySecurityStackWalk(hotspot_method, method->is_ignored_by_security_stack_walk()); + return method->is_ignored_by_security_stack_walk(); C2V_END C2V_VMENTRY(jboolean, canInlineMethod,(JNIEnv *, jobject, jlong metaspace_method)) @@ -805,7 +801,7 @@ {CC"findUniqueConcreteMethod", CC"("METASPACE_METHOD")"METASPACE_METHOD, FN_PTR(findUniqueConcreteMethod)}, {CC"getKlassImplementor", CC"("METASPACE_KLASS")"METASPACE_KLASS, FN_PTR(getKlassImplementor)}, {CC"getStackTraceElement", CC"("METASPACE_METHOD"I)"STACK_TRACE_ELEMENT, FN_PTR(getStackTraceElement)}, - {CC"initializeMethod", CC"("METASPACE_METHOD HS_RESOLVED_METHOD")V", FN_PTR(initializeMethod)}, + {CC"methodIsIgnoredBySecurityStackWalk", CC"("METASPACE_METHOD")Z", FN_PTR(methodIsIgnoredBySecurityStackWalk)}, {CC"doNotInlineOrCompile", CC"("METASPACE_METHOD")V", FN_PTR(doNotInlineOrCompile)}, {CC"canInlineMethod", CC"("METASPACE_METHOD")Z", FN_PTR(canInlineMethod)}, {CC"shouldInlineMethod", CC"("METASPACE_METHOD")Z", FN_PTR(shouldInlineMethod)}, diff -r 97a0878202c2 -r fbae9be45c95 src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Wed Mar 26 17:02:45 2014 +0100 +++ b/src/share/vm/graal/graalJavaAccess.hpp Wed Mar 26 20:44:11 2014 +0100 @@ -55,10 +55,6 @@ oop_field(HotSpotResolvedJavaMethod, name, "Ljava/lang/String;") \ oop_field(HotSpotResolvedJavaMethod, holder, "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedObjectType;") \ long_field(HotSpotResolvedJavaMethod, metaspaceMethod) \ - boolean_field(HotSpotResolvedJavaMethod, callerSensitive) \ - boolean_field(HotSpotResolvedJavaMethod, forceInline) \ - boolean_field(HotSpotResolvedJavaMethod, dontInline) \ - boolean_field(HotSpotResolvedJavaMethod, ignoredBySecurityStackWalk) \ end_class \ start_class(HotSpotJavaType) \ oop_field(HotSpotJavaType, name, "Ljava/lang/String;") \ diff -r 97a0878202c2 -r fbae9be45c95 src/share/vm/graal/graalRuntime.cpp --- a/src/share/vm/graal/graalRuntime.cpp Wed Mar 26 17:02:45 2014 +0100 +++ b/src/share/vm/graal/graalRuntime.cpp Wed Mar 26 20:44:11 2014 +0100 @@ -438,13 +438,12 @@ return (jint)ret; JRT_END -JRT_ENTRY(void, GraalRuntime::vm_error(JavaThread* thread, oopDesc* where, oopDesc* format, jlong value)) +JRT_ENTRY(void, GraalRuntime::vm_error(JavaThread* thread, jlong where, jlong format, jlong value)) ResourceMark rm; - assert(where == NULL || java_lang_String::is_instance(where), "must be"); - const char *error_msg = where == NULL ? "" : java_lang_String::as_utf8_string(where); + const char *error_msg = where == 0L ? "" : (char*) (address) where; char *detail_msg = NULL; - if (format != NULL) { - const char* buf = java_lang_String::as_utf8_string(format); + if (format != 0L) { + const char* buf = (char*) (address) format; size_t detail_msg_length = strlen(buf) * 2; detail_msg = (char *) NEW_RESOURCE_ARRAY(u_char, detail_msg_length); jio_snprintf(detail_msg, detail_msg_length, buf, value); diff -r 97a0878202c2 -r fbae9be45c95 src/share/vm/graal/graalRuntime.hpp --- a/src/share/vm/graal/graalRuntime.hpp Wed Mar 26 17:02:45 2014 +0100 +++ b/src/share/vm/graal/graalRuntime.hpp Wed Mar 26 20:44:11 2014 +0100 @@ -43,7 +43,7 @@ static void monitorexit (JavaThread* thread, oopDesc* obj, BasicLock* lock); static void create_null_exception(JavaThread* thread); static void create_out_of_bounds_exception(JavaThread* thread, jint index); - static void vm_error(JavaThread* thread, oopDesc* where, oopDesc* format, jlong value); + static void vm_error(JavaThread* thread, jlong where, jlong format, jlong value); static oopDesc* load_and_clear_exception(JavaThread* thread); static void log_printf(JavaThread* thread, oopDesc* format, jlong v1, jlong v2, jlong v3); static void log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline); diff -r 97a0878202c2 -r fbae9be45c95 src/share/vm/oops/method.hpp --- a/src/share/vm/oops/method.hpp Wed Mar 26 17:02:45 2014 +0100 +++ b/src/share/vm/oops/method.hpp Wed Mar 26 20:44:11 2014 +0100 @@ -108,12 +108,15 @@ #endif u2 _method_size; // size of this object u1 _intrinsic_id; // vmSymbols::intrinsic_id (0 == _none) - u1 _jfr_towrite : 1, // Flags - _caller_sensitive : 1, - _force_inline : 1, - _hidden : 1, - _dont_inline : 1, - : 3; + // Flags + enum Flags { + _jfr_towrite = 1 << 0, + _caller_sensitive = 1 << 1, + _force_inline = 1 << 2, + _dont_inline = 1 << 3, + _hidden = 1 << 4 + }; + u1 _flags; #ifndef PRODUCT int _compiled_invocation_count; // Number of nmethod invocations so far (for perf. debugging) @@ -759,16 +762,41 @@ void init_intrinsic_id(); // updates from _none if a match static vmSymbols::SID klass_id_for_intrinsics(Klass* holder); - bool jfr_towrite() { return _jfr_towrite; } - void set_jfr_towrite(bool x) { _jfr_towrite = x; } - bool caller_sensitive() { return _caller_sensitive; } - void set_caller_sensitive(bool x) { _caller_sensitive = x; } - bool force_inline() { return _force_inline; } - void set_force_inline(bool x) { _force_inline = x; } - bool dont_inline() { return _dont_inline; } - void set_dont_inline(bool x) { _dont_inline = x; } - bool is_hidden() { return _hidden; } - void set_hidden(bool x) { _hidden = x; } + bool jfr_towrite() { + return (_flags & _jfr_towrite) != 0; + } + void set_jfr_towrite(bool x) { + _flags = x ? (_flags | _jfr_towrite) : (_flags & ~_jfr_towrite); + } + + bool caller_sensitive() { + return (_flags & _caller_sensitive) != 0; + } + void set_caller_sensitive(bool x) { + _flags = x ? (_flags | _caller_sensitive) : (_flags & ~_caller_sensitive); + } + + bool force_inline() { + return (_flags & _force_inline) != 0; + } + void set_force_inline(bool x) { + _flags = x ? (_flags | _force_inline) : (_flags & ~_force_inline); + } + + bool dont_inline() { + return (_flags & _dont_inline) != 0; + } + void set_dont_inline(bool x) { + _flags = x ? (_flags | _dont_inline) : (_flags & ~_dont_inline); + } + + bool is_hidden() { + return (_flags & _hidden) != 0; + } + void set_hidden(bool x) { + _flags = x ? (_flags | _hidden) : (_flags & ~_hidden); + } + ConstMethod::MethodType method_type() const { return _constMethod->method_type(); } diff -r 97a0878202c2 -r fbae9be45c95 src/share/vm/opto/node.cpp --- a/src/share/vm/opto/node.cpp Wed Mar 26 17:02:45 2014 +0100 +++ b/src/share/vm/opto/node.cpp Wed Mar 26 20:44:11 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -476,6 +476,7 @@ #pragma clang diagnostic pop #endif + //------------------------------clone------------------------------------------ // Clone a Node. Node *Node::clone() const { diff -r 97a0878202c2 -r fbae9be45c95 src/share/vm/opto/runtime.cpp --- a/src/share/vm/opto/runtime.cpp Wed Mar 26 17:02:45 2014 +0100 +++ b/src/share/vm/opto/runtime.cpp Wed Mar 26 20:44:11 2014 +0100 @@ -1,6 +1,5 @@ /* * Copyright (c) 1998, 2013, 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 diff -r 97a0878202c2 -r fbae9be45c95 src/share/vm/runtime/sharedRuntime.cpp --- a/src/share/vm/runtime/sharedRuntime.cpp Wed Mar 26 17:02:45 2014 +0100 +++ b/src/share/vm/runtime/sharedRuntime.cpp Wed Mar 26 20:44:11 2014 +0100 @@ -886,7 +886,10 @@ _implicit_null_throws++; #endif #ifdef GRAAL - if (nm->is_compiled_by_graal()) { + if (nm->is_compiled_by_graal() && nm->pc_desc_at(pc) != NULL) { + // If there's no PcDesc then we'll die way down inside of + // deopt instead of just getting normal error reporting, + // so only go there if it will succeed. target_pc = deoptimize_for_implicit_exception(thread, pc, nm, Deoptimization::Reason_null_check); } else { #endif diff -r 97a0878202c2 -r fbae9be45c95 src/share/vm/runtime/vmStructs.cpp --- a/src/share/vm/runtime/vmStructs.cpp Wed Mar 26 17:02:45 2014 +0100 +++ b/src/share/vm/runtime/vmStructs.cpp Wed Mar 26 20:44:11 2014 +0100 @@ -374,6 +374,7 @@ nonstatic_field(Method, _vtable_index, int) \ nonstatic_field(Method, _method_size, u2) \ nonstatic_field(Method, _intrinsic_id, u1) \ + nonstatic_field(Method, _flags, u1) \ nonproduct_nonstatic_field(Method, _compiled_invocation_count, int) \ volatile_nonstatic_field(Method, _code, nmethod*) \ nonstatic_field(Method, _i2i_entry, address) \ @@ -2410,6 +2411,12 @@ /* ConstMethod anon-enum */ \ /********************************/ \ \ + declare_constant(Method::_jfr_towrite) \ + declare_constant(Method::_caller_sensitive) \ + declare_constant(Method::_force_inline) \ + declare_constant(Method::_dont_inline) \ + declare_constant(Method::_hidden) \ + \ declare_constant(ConstMethod::_has_linenumber_table) \ declare_constant(ConstMethod::_has_checked_exceptions) \ declare_constant(ConstMethod::_has_localvariable_table) \ @@ -2439,6 +2446,7 @@ declare_constant(DataLayout::call_type_data_tag) \ declare_constant(DataLayout::virtual_call_type_data_tag) \ declare_constant(DataLayout::parameters_type_data_tag) \ + declare_constant(DataLayout::speculative_trap_data_tag) \ \ /*************************************/ \ /* InstanceKlass enum */ \