Mercurial > hg > graal-compiler
changeset 8970:50c63b0d858e
Merge.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Tue, 09 Apr 2013 19:29:26 +0200 |
parents | 1fa6536416db (current diff) 1af9b5d75139 (diff) |
children | da39fb4f9b2e |
files | |
diffstat | 38 files changed, 434 insertions(+), 64 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java Tue Apr 09 19:29:26 2013 +0200 @@ -25,6 +25,7 @@ import static com.oracle.graal.api.meta.MetaUtil.*; import java.io.*; +import java.lang.invoke.*; import java.util.*; import com.oracle.graal.api.meta.*; @@ -182,6 +183,45 @@ } /** + * Assumption that a call site's method handle did not change. + */ + public static final class CallSiteTargetValue extends Assumption { + + private static final long serialVersionUID = 1732459941784550371L; + + public final CallSite callSite; + public final MethodHandle methodHandle; + + public CallSiteTargetValue(CallSite callSite, MethodHandle methodHandle) { + this.callSite = callSite; + this.methodHandle = methodHandle; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + callSite.hashCode(); + result = prime * result + methodHandle.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof CallSiteTargetValue) { + CallSiteTargetValue other = (CallSiteTargetValue) obj; + return other.callSite == callSite && other.methodHandle == methodHandle; + } + return false; + } + + @Override + public String toString() { + return "CallSiteTargetValue[callSite=" + callSite + ", methodHandle=" + methodHandle + "]"; + } + } + + /** * Array with the assumptions. This field is directly accessed from C++ code in the * Graal/HotSpot implementation. */
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java Tue Apr 09 19:29:26 2013 +0200 @@ -74,7 +74,7 @@ /** * Derives hint information for use when generating the code for a type check instruction. * - * @param type the target type of the type check + * @param targetType the target type of the type check * @param profile the profiling information available for the instruction (if any) * @param assumptions the object in which speculations are recorded. This is null if * speculations are not supported. @@ -83,16 +83,16 @@ * will be null * @param maxHints the maximum length of {@link #hints} */ - public TypeCheckHints(ResolvedJavaType type, JavaTypeProfile profile, Assumptions assumptions, double minHintHitProbability, int maxHints) { - if (type != null && !canHaveSubtype(type)) { - hints = new Hint[]{new Hint(type, true)}; + public TypeCheckHints(ResolvedJavaType targetType, JavaTypeProfile profile, Assumptions assumptions, double minHintHitProbability, int maxHints) { + if (targetType != null && !canHaveSubtype(targetType)) { + hints = new Hint[]{new Hint(targetType, true)}; exact = true; } else { - ResolvedJavaType uniqueSubtype = type == null ? null : type.findUniqueConcreteSubtype(); + ResolvedJavaType uniqueSubtype = targetType == null ? null : targetType.findUniqueConcreteSubtype(); if (uniqueSubtype != null) { hints = new Hint[]{new Hint(uniqueSubtype, true)}; if (assumptions.useOptimisticAssumptions()) { - assumptions.recordConcreteSubtype(type, uniqueSubtype); + assumptions.recordConcreteSubtype(targetType, uniqueSubtype); exact = true; } else { exact = false; @@ -109,8 +109,9 @@ int hintCount = 0; double totalHintProbability = 0.0d; for (ProfiledType ptype : ptypes) { - if (type != null) { - hintsBuf[hintCount++] = new Hint(type, type.isAssignableFrom(ptype.getType())); + if (targetType != null) { + ResolvedJavaType hintType = ptype.getType(); + hintsBuf[hintCount++] = new Hint(hintType, targetType.isAssignableFrom(hintType)); totalHintProbability += ptype.getProbability(); } }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantPool.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantPool.java Tue Apr 09 19:29:26 2013 +0200 @@ -93,4 +93,12 @@ * entry */ Object lookupConstant(int cpi); + + /** + * Looks up the appendix at the specified index. + * + * @param cpi the constant pool index + * @return the appendix if resolved or {@code null}. + */ + Object lookupAppendix(int cpi); }
--- a/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeStream.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeStream.java Tue Apr 09 19:29:26 2013 +0200 @@ -168,6 +168,16 @@ } /** + * Reads a constant pool index for an invokedynamic instruction. + * + * @return the constant pool index + */ + public int readCPI4() { + assert opcode == Bytecodes.INVOKEDYNAMIC; + return Bytes.beS4(code, curBCI + 1); + } + + /** * Reads a signed, 1-byte value for the current instruction (e.g. BIPUSH). * * @return the byte
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Tue Apr 09 19:29:26 2013 +0200 @@ -225,6 +225,8 @@ new LoweringPhase(target, runtime, replacements, assumptions).apply(graph); + new FrameStateAssignementPhase().apply(graph); + final SchedulePhase schedule = new SchedulePhase(); schedule.apply(graph); Debug.dump(schedule, "final schedule");
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Tue Apr 09 19:29:26 2013 +0200 @@ -338,14 +338,7 @@ if (instr instanceof StateSplit) { stateAfter = ((StateSplit) instr).stateAfter(); } - if (instr instanceof DeoptimizingNode) { - DeoptimizingNode deopt = (DeoptimizingNode) instr; - if (deopt.canDeoptimize() && deopt.getDeoptimizationState() == null) { - deopt.setDeoptimizationState(lastState); - } - } if (instr instanceof ValueNode) { - ValueNode valueNode = (ValueNode) instr; if (operand(valueNode) == null) { if (!peephole(valueNode)) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Tue Apr 09 19:29:26 2013 +0200 @@ -221,4 +221,6 @@ * @param metaspaceMethod the metaspace Method object */ void reprofile(long metaspaceMethod); + + Object lookupAppendixInPool(HotSpotResolvedObjectType pool, int cpi); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Tue Apr 09 19:29:26 2013 +0200 @@ -158,4 +158,7 @@ @Override public native void reprofile(long metaspaceMethod); + + @Override + public native Object lookupAppendixInPool(HotSpotResolvedObjectType pool, int cpi); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java Tue Apr 09 19:29:26 2013 +0200 @@ -51,6 +51,13 @@ } @Override + public Object lookupAppendix(int cpi) { + assert cpi != 0; + Object constant = HotSpotGraalRuntime.getInstance().getCompilerToVM().lookupAppendixInPool(type, cpi); + return constant; + } + + @Override public JavaMethod lookupMethod(int cpi, int opcode) { return HotSpotGraalRuntime.getInstance().getCompilerToVM().lookupMethodInPool(type, cpi, (byte) opcode); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodUnresolved.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodUnresolved.java Tue Apr 09 19:29:26 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.hotspot.meta; +import static com.oracle.graal.api.meta.MetaUtil.*; + import com.oracle.graal.api.meta.*; /** @@ -51,6 +53,6 @@ @Override public String toString() { - return "HotSpotMethod<" + holder.getName() + ". " + name + ", unresolved>"; + return format("HotSpotMethod<%H.%n(%p), unresolved>", this); } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Tue Apr 09 19:29:26 2013 +0200 @@ -23,7 +23,10 @@ package com.oracle.graal.hotspot.meta; +import static com.oracle.graal.api.meta.MetaUtil.*; + import java.lang.annotation.*; +import java.lang.invoke.*; import java.lang.reflect.*; import com.oracle.graal.api.meta.*; @@ -97,6 +100,8 @@ if (assumeNonStaticFinalFieldsAsFinal(receiver.asObject().getClass()) || !value.isDefaultForKind()) { return value; } + } else if (receiver.asObject() instanceof ConstantCallSite) { + return readValue(receiver); } } return null; @@ -150,7 +155,7 @@ @Override public String toString() { - return "HotSpotField<" + MetaUtil.format("%h.%n", this) + ":" + offset + ">"; + return format("HotSpotField<%H.%n %t:", this) + offset + ">"; } @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Tue Apr 09 19:29:26 2013 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.hotspot.meta; +import static com.oracle.graal.api.meta.MetaUtil.*; import static com.oracle.graal.graph.FieldIntrospection.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; @@ -186,7 +187,7 @@ @Override public String toString() { - return "HotSpotMethod<" + MetaUtil.format("%h.%n", this) + ">"; + return format("HotSpotMethod<%H.%n(%p)>", this); } public int getCompiledCodeSize() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedField.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedField.java Tue Apr 09 19:29:26 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.hotspot.meta; +import static com.oracle.graal.api.meta.MetaUtil.*; + import com.oracle.graal.api.meta.*; /** @@ -60,6 +62,6 @@ */ @Override public String toString() { - return MetaUtil.format("%H.%n [unresolved]", this); + return format("HotSpotField<%H.%n %t, unresolved>", this); } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java Tue Apr 09 19:29:26 2013 +0200 @@ -70,7 +70,6 @@ @Override public void generate(LIRGenerator gen) { assert lockDepth != -1; - assert stateAfter() != null; HotSpotLIRGenerator hsGen = (HotSpotLIRGenerator) gen; StackSlot slot = hsGen.getLockSlot(lockDepth); if (!eliminated) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Tue Apr 09 19:29:26 2013 +0200 @@ -24,6 +24,7 @@ import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*; import static com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.*; +import static com.oracle.graal.replacements.Snippet.Varargs.*; import static com.oracle.graal.replacements.SnippetTemplate.Arguments.*; import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; @@ -114,6 +115,7 @@ @Parameter("trueValue") Object trueValue, @Parameter("falseValue") Object falseValue, @VarargsParameter("hints") Word[] hints, + @VarargsParameter("hintIsPositive") boolean[] hintIsPositive, @ConstantParameter("checkNull") boolean checkNull) { if (checkNull && object == null) { probability(NOT_FREQUENT_PROBABILITY); @@ -125,10 +127,11 @@ ExplodeLoopNode.explodeLoop(); for (int i = 0; i < hints.length; i++) { Word hintHub = hints[i]; + boolean positive = hintIsPositive[i]; if (hintHub.equal(objectHub)) { probability(NOT_FREQUENT_PROBABILITY); hintsHit.inc(); - return trueValue; + return positive ? trueValue : falseValue; } } if (!checkSecondarySubType(hub, objectHub)) { @@ -174,7 +177,7 @@ super(runtime, replacements, target, InstanceOfSnippets.class); instanceofExact = snippet("instanceofExact", Object.class, Word.class, Object.class, Object.class, boolean.class); instanceofPrimary = snippet("instanceofPrimary", Word.class, Object.class, Object.class, Object.class, boolean.class, int.class); - instanceofSecondary = snippet("instanceofSecondary", Word.class, Object.class, Object.class, Object.class, Word[].class, boolean.class); + instanceofSecondary = snippet("instanceofSecondary", Word.class, Object.class, Object.class, Object.class, Word[].class, boolean[].class, boolean.class); instanceofDynamic = snippet("instanceofDynamic", Class.class, Object.class, Object.class, Object.class, boolean.class); } @@ -200,9 +203,13 @@ key = new Key(instanceofPrimary).add("checkNull", checkNull).add("superCheckOffset", type.superCheckOffset()); arguments = arguments("hub", hub).add("object", object).add("trueValue", trueValue).add("falseValue", falseValue); } else { - ConstantNode[] hints = createHints(hintInfo, runtime, true, hub.graph()).hubs; - key = new Key(instanceofSecondary).add("hints", Varargs.vargargs(new Word[hints.length], StampFactory.forKind(wordKind()))).add("checkNull", checkNull); - arguments = arguments("hub", hub).add("object", object).add("hints", hints).add("trueValue", trueValue).add("falseValue", falseValue); + Hints hints = createHints(hintInfo, runtime, false, hub.graph()); + ConstantNode[] hintHubs = hints.hubs; + boolean[] hintIsPositive = hints.isPositive; + Varargs hintsParam = vargargs(new Word[hintHubs.length], StampFactory.forKind(wordKind())); + Varargs hintIsPositiveParam = vargargs(new boolean[hintIsPositive.length], StampFactory.forKind(Kind.Boolean)); + key = new Key(instanceofSecondary).add("hints", hintsParam).add("hintIsPositive", hintIsPositiveParam).add("checkNull", checkNull); + arguments = arguments("hub", hub).add("object", object).add("hints", hintHubs).add("hintIsPositive", hintIsPositive).add("trueValue", trueValue).add("falseValue", falseValue); } return new KeyAndArguments(key, arguments); } else {
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java Tue Apr 09 19:29:26 2013 +0200 @@ -102,6 +102,13 @@ buf.append(String.format("#%-10s // %s", cpi + ", " + stream.readUByte(bci + 3), calleeDesc)); break; } + case INVOKEDYNAMIC: { + int cpi = stream.readCPI4(); + JavaMethod callee = cp.lookupMethod(cpi, opcode); + String calleeDesc = callee.getDeclaringClass().getName().equals(method.getDeclaringClass().getName()) ? MetaUtil.format("%n:(%P)%R", callee) : MetaUtil.format("%H.%n:(%P)%R", callee); + buf.append(String.format("#%-10d // %s", cpi, calleeDesc)); + break; + } case LDC : case LDC_W : case LDC2_W : {
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Apr 09 19:29:26 2013 +0200 @@ -766,7 +766,8 @@ } private void eagerResolvingForSnippets(int cpi, int bytecode) { - if (graphBuilderConfig.eagerResolving()) { + // (aw) cannot eager-resolve invokedynamic + if (graphBuilderConfig.eagerResolving() && bytecode != Bytecodes.INVOKEDYNAMIC) { constantPool.loadReferencedType(cpi, bytecode); } } @@ -1054,6 +1055,19 @@ } } + private void genInvokeDynamic(JavaMethod target) { + if (target instanceof ResolvedJavaMethod) { + Object appendix = constantPool.lookupAppendix(stream.readCPI4()); + if (appendix != null) { + frameState.apush(ConstantNode.forObject(appendix, runtime, currentGraph)); + } + ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(false), target.getSignature().getParameterCount(false)); + appendInvoke(InvokeKind.Static, (ResolvedJavaMethod) target, args); + } else { + handleUnresolvedInvoke(target, InvokeKind.Static); + } + } + private void genInvokeVirtual(JavaMethod target) { if (target instanceof ResolvedJavaMethod) { ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(true), target.getSignature().getParameterCount(true)); @@ -1937,6 +1951,7 @@ case INVOKESPECIAL : cpi = stream.readCPI(); genInvokeSpecial(lookupMethod(cpi, opcode)); break; case INVOKESTATIC : cpi = stream.readCPI(); genInvokeStatic(lookupMethod(cpi, opcode)); break; case INVOKEINTERFACE: cpi = stream.readCPI(); genInvokeInterface(lookupMethod(cpi, opcode)); break; + case INVOKEDYNAMIC : cpi = stream.readCPI4(); genInvokeDynamic(lookupMethod(cpi, opcode)); break; case NEW : genNewInstance(stream.readCPI()); break; case NEWARRAY : genNewPrimitiveArray(stream.readLocalIndex()); break; case ANEWARRAY : genNewObjectArray(stream.readCPI()); break;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Tue Apr 09 19:29:26 2013 +0200 @@ -70,6 +70,7 @@ @Override public void setDeoptimizationState(FrameState f) { + updateUsages(deoptState, f); deoptState = f; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingFixedWithNextNode.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingFixedWithNextNode.java Tue Apr 09 19:29:26 2013 +0200 @@ -49,6 +49,7 @@ @Override public void setDeoptimizationState(FrameState f) { + updateUsages(deoptState, f); deoptState = f; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Tue Apr 09 19:29:26 2013 +0200 @@ -38,6 +38,7 @@ public final class InvokeNode extends AbstractStateSplit implements StateSplit, Node.IterableNodeType, Invoke, LIRLowerable, MemoryCheckpoint { @Input private final CallTargetNode callTarget; + @Input private FrameState deoptState; private final int bci; private boolean polymorphic; private boolean useForInlining; @@ -188,7 +189,12 @@ @Override public FrameState getDeoptimizationState() { - return stateDuring(); + if (deoptState == null) { + FrameState stateDuring = stateDuring(); + updateUsages(deoptState, stateDuring); + deoptState = stateDuring; + } + return deoptState; } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Tue Apr 09 19:29:26 2013 +0200 @@ -37,6 +37,7 @@ @Successor private BeginNode next; @Successor private DispatchBeginNode exceptionEdge; @Input private final CallTargetNode callTarget; + @Input private FrameState deoptState; @Input private FrameState stateAfter; private final int bci; private boolean polymorphic; @@ -234,7 +235,12 @@ @Override public FrameState getDeoptimizationState() { - return stateDuring(); + if (deoptState == null) { + FrameState stateDuring = stateDuring(); + updateUsages(deoptState, stateDuring); + deoptState = stateDuring; + } + return deoptState; } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java Tue Apr 09 19:29:26 2013 +0200 @@ -97,6 +97,7 @@ @Override public void setDeoptimizationState(FrameState f) { + updateUsages(deoptState, f); deoptState = f; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/RuntimeCallNode.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/RuntimeCallNode.java Tue Apr 09 19:29:26 2013 +0200 @@ -81,7 +81,8 @@ 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.kind()); } - return stateDuring; + updateUsages(deoptState, stateDuring); + return deoptState = stateDuring; } return null; } @@ -91,6 +92,7 @@ if (deoptState != null) { throw new IllegalStateException(); } + updateUsages(deoptState, f); deoptState = f; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Tue Apr 09 19:29:26 2013 +0200 @@ -97,6 +97,7 @@ @Override public void setDeoptimizationState(FrameState f) { + updateUsages(deoptState, f); deoptState = f; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignementPhase.java Tue Apr 09 19:29:26 2013 +0200 @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013, 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.common; + +import java.util.*; + +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.cfg.*; +import com.oracle.graal.nodes.util.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.graph.*; +import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure; + +public class FrameStateAssignementPhase extends Phase { + + private static class FrameStateAssignementState { + + private FrameState framestate; + + public FrameStateAssignementState(FrameState framestate) { + this.framestate = framestate; + } + + public FrameState getFramestate() { + return framestate; + } + + public void setFramestate(FrameState framestate) { + assert framestate != null; + this.framestate = framestate; + } + + @Override + public String toString() { + return "FrameStateAssignementState: " + framestate; + } + } + + private static class FrameStateAssignementClosure extends BlockIteratorClosure<FrameStateAssignementState> { + + @Override + protected void processBlock(Block block, FrameStateAssignementState currentState) { + FixedNode node = block.getBeginNode(); + while (node != null) { + if (node instanceof DeoptimizingNode) { + DeoptimizingNode deopt = (DeoptimizingNode) node; + if (deopt.canDeoptimize() && deopt.getDeoptimizationState() == null) { + deopt.setDeoptimizationState(currentState.getFramestate()); + } + } + + if (node instanceof StateSplit) { + StateSplit stateSplit = (StateSplit) node; + if (stateSplit.stateAfter() != null) { + currentState.setFramestate(stateSplit.stateAfter()); + stateSplit.setStateAfter(null); + } + } + + if (node instanceof FixedWithNextNode) { + node = ((FixedWithNextNode) node).next(); + } else { + node = null; + } + } + } + + @Override + protected FrameStateAssignementState merge(Block mergeBlock, List<FrameStateAssignementState> states) { + MergeNode merge = (MergeNode) mergeBlock.getBeginNode(); + if (merge.stateAfter() != null) { + return new FrameStateAssignementState(merge.stateAfter()); + } + return new FrameStateAssignementState(singleFrameState(states)); + } + + @Override + protected FrameStateAssignementState cloneState(FrameStateAssignementState oldState) { + return new FrameStateAssignementState(oldState.getFramestate()); + } + + @Override + protected List<FrameStateAssignementState> processLoop(Loop loop, FrameStateAssignementState initialState) { + return ReentrantBlockIterator.processLoop(this, loop, initialState).exitStates; + } + + } + + @Override + protected void run(StructuredGraph graph) { + assert checkFixedDeopts(graph); + ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, false, false); + ReentrantBlockIterator.apply(new FrameStateAssignementClosure(), cfg.getStartBlock(), new FrameStateAssignementState(null), null); + } + + private static boolean checkFixedDeopts(StructuredGraph graph) { + NodePredicate isFloatingNode = GraphUtil.isFloatingNode(); + for (Node n : graph.getNodes().filterInterface(DeoptimizingNode.class)) { + if (((DeoptimizingNode) n).canDeoptimize() && isFloatingNode.apply(n)) { + return false; + } + } + return true; + } + + private static FrameState singleFrameState(List<FrameStateAssignementState> states) { + Iterator<FrameStateAssignementState> it = states.iterator(); + assert it.hasNext(); + FrameState first = it.next().getFramestate(); + while (it.hasNext()) { + if (first != it.next().getFramestate()) { + return null; + } + } + return first; + } +}
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Apr 09 19:29:26 2013 +0200 @@ -39,6 +39,30 @@ public final class SchedulePhase extends Phase { + /** + * Error thrown when a graph cannot be scheduled. + */ + public static class SchedulingError extends Error { + + private static final long serialVersionUID = 1621001069476473145L; + + public SchedulingError() { + super(); + } + + /** + * 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...)} + */ + public SchedulingError(String format, Object... args) { + super(String.format(format, args)); + } + + } + public static enum SchedulingStrategy { EARLIEST, LATEST, LATEST_OUT_OF_LOOPS } @@ -169,8 +193,8 @@ /** * Sets {@link ScheduledNode#scheduledNext} on all scheduled nodes in all blocks using the - * scheduling built by @link {@link #run(StructuredGraph)}. This method should thus only be - * called when run has been successfully executed. + * scheduling built by {@link #run(StructuredGraph)}. This method should thus only be called + * when run has been successfully executed. */ public void scheduleGraph() { assert blockToNodesMap != null : "cannot set scheduledNext before run has been executed"; @@ -207,7 +231,9 @@ private void assignBlockToNodes(StructuredGraph graph, SchedulingStrategy strategy) { for (Block block : cfg.getBlocks()) { List<ScheduledNode> nodes = new ArrayList<>(); - assert blockToNodesMap.get(block) == null; + if (blockToNodesMap.get(block) != null) { + throw new SchedulingError(); + } blockToNodesMap.put(block, nodes); for (FixedNode node : block.getNodes()) { nodes.add(node); @@ -234,8 +260,9 @@ } // PhiNodes and FixedNodes should already have been placed in blocks by // ControlFlowGraph.identifyBlocks - assert !(node instanceof PhiNode) : node; - assert !(node instanceof FixedNode) : node; + if (node instanceof PhiNode || node instanceof FixedNode) { + throw new SchedulingError("%s should already have been placed in a block", node); + } Block block; switch (strategy) { @@ -251,8 +278,10 @@ // schedule at the latest position possible in the outermost loop possible Block earliestBlock = earliestBlock(node); block = scheduleOutOfLoops(node, block, earliestBlock); - assert earliestBlock.dominates(block) : "Graph cannot be scheduled : inconsistent for " + node + ", " + node.usages().count() + " usages, (" + earliestBlock + - " needs to dominate " + block + ")"; + if (!earliestBlock.dominates(block)) { + throw new SchedulingError("%s: Graph cannot be scheduled : inconsistent for %s, %d usages, (%s needs to dominate %s)", node.graph(), node, node.usages().count(), + earliestBlock, block); + } } break; default: @@ -271,7 +300,9 @@ private Block latestBlock(ScheduledNode node, SchedulingStrategy strategy) { CommonDominatorBlockClosure cdbc = new CommonDominatorBlockClosure(null); for (Node succ : node.successors().nonNull()) { - assert cfg.getNodeToBlock().get(succ) != null; + if (cfg.getNodeToBlock().get(succ) == null) { + throw new SchedulingError(); + } cdbc.apply(cfg.getNodeToBlock().get(succ)); } ensureScheduledUsages(node, strategy); @@ -281,7 +312,9 @@ List<FixedNode> usages = phantomUsages.get(node); if (usages != null) { for (FixedNode usage : usages) { - assert cfg.getNodeToBlock().get(usage) != null; + if (cfg.getNodeToBlock().get(usage) == null) { + throw new SchedulingError(); + } cdbc.apply(cfg.getNodeToBlock().get(usage)); } } @@ -331,7 +364,9 @@ */ BitSet dominators = new BitSet(cfg.getBlocks().length); - assert node.predecessor() == null; + if (node.predecessor() != null) { + throw new SchedulingError(); + } for (Node input : node.inputs().nonNull()) { assert input instanceof ValueNode; Block inputEarliest; @@ -356,7 +391,9 @@ } private static Block scheduleOutOfLoops(Node n, Block latestBlock, Block earliest) { - assert latestBlock != null : "no latest : " + n; + if (latestBlock == null) { + throw new SchedulingError("no latest : %s", n); + } Block cur = latestBlock; Block result = latestBlock; while (cur.getLoop() != null && cur != earliest && cur.getDominator() != null) { @@ -378,7 +415,9 @@ * @param closure the closure that will be called for each block */ private void blocksForUsage(ScheduledNode node, Node usage, BlockClosure closure, SchedulingStrategy strategy) { - assert !(node instanceof PhiNode); + if (node instanceof PhiNode) { + throw new SchedulingError(node.toString()); + } if (usage instanceof PhiNode) { // An input to a PhiNode is used at the end of the predecessor block that corresponds to @@ -388,7 +427,9 @@ PhiNode phi = (PhiNode) usage; MergeNode merge = phi.merge(); Block mergeBlock = cfg.getNodeToBlock().get(merge); - assert mergeBlock != null : "no block for merge " + merge.toString(Verbosity.Id); + if (mergeBlock == null) { + throw new SchedulingError("no block for merge %s", merge.toString(Verbosity.Id)); + } for (int i = 0; i < phi.valueCount(); ++i) { if (phi.valueAt(i) == node) { if (mergeBlock.getPredecessorCount() <= i) { @@ -412,7 +453,9 @@ blocksForUsage(node, unscheduledUsage, closure, strategy); } else if (unscheduledUsage instanceof MergeNode) { // Only FrameStates can be connected to MergeNodes. - assert usage instanceof FrameState; + if (!(usage instanceof FrameState)) { + throw new SchedulingError(usage.toString()); + } // If a FrameState belongs to a MergeNode then it's inputs will be placed at the // common dominator of all EndNodes. for (Node pred : unscheduledUsage.cfgPredecessors()) { @@ -420,8 +463,12 @@ } } else { // For the time being, only FrameStates can be connected to StateSplits. - assert usage instanceof FrameState; - assert unscheduledUsage instanceof StateSplit; + if (!(usage instanceof FrameState)) { + throw new SchedulingError(usage.toString()); + } + if (!(unscheduledUsage instanceof StateSplit || unscheduledUsage instanceof DeoptimizingNode)) { + throw new SchedulingError(unscheduledUsage.toString()); + } // Otherwise: Put the input into the same block as the usage. assignBlockToNode((ScheduledNode) unscheduledUsage, strategy); closure.apply(cfg.getNodeToBlock().get(unscheduledUsage)); @@ -459,8 +506,12 @@ } private void sortNodesWithinBlock(Block b, NodeBitMap visited, SchedulingStrategy strategy) { - assert !visited.isMarked(b.getBeginNode()) && cfg.blockFor(b.getBeginNode()) == b; - assert !visited.isMarked(b.getEndNode()) && cfg.blockFor(b.getEndNode()) == b; + if (visited.isMarked(b.getBeginNode()) || cfg.blockFor(b.getBeginNode()) != b) { + throw new SchedulingError(); + } + if (visited.isMarked(b.getEndNode()) || cfg.blockFor(b.getEndNode()) != b) { + throw new SchedulingError(); + } List<ScheduledNode> sortedInstructions; switch (strategy) { @@ -520,7 +571,9 @@ private void addUnscheduledToLatestSorting(Block b, VirtualState state, List<ScheduledNode> sortedInstructions, NodeBitMap visited) { if (state != null) { // UnscheduledNodes should never be marked as visited. - assert !visited.isMarked(state); + if (visited.isMarked(state)) { + throw new SchedulingError(); + } for (Node input : state.inputs()) { if (input instanceof VirtualState) {
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java Tue Apr 09 19:29:12 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java Tue Apr 09 19:29:26 2013 +0200 @@ -24,17 +24,18 @@ import java.util.*; - import com.oracle.graal.api.code.CompilationResult.Call; import com.oracle.graal.api.code.CompilationResult.Mark; import com.oracle.graal.api.code.CompilationResult.Site; import com.oracle.graal.api.meta.*; -import com.oracle.graal.test.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; -import com.oracle.graal.replacements.test.CheckCastTest.*; +import com.oracle.graal.replacements.test.CheckCastTest.Depth12; +import com.oracle.graal.replacements.test.CheckCastTest.Depth13; +import com.oracle.graal.replacements.test.CheckCastTest.Depth14; +import com.oracle.graal.test.*; /** * Tests the implementation of instanceof, allowing profiling information to be manually specified. @@ -125,6 +126,7 @@ test("isMap", profile(), Object.class); test("isMap", profile(HashMap.class), Object.class); test("isMap", profile(TreeMap.class, HashMap.class), Object.class); + test("isMap", profile(String.class, HashMap.class), Object.class); } @LongTest @@ -150,6 +152,7 @@ test("isDepth12", profile(), o); test("isDepth12", profile(Depth13.class), o); test("isDepth12", profile(Depth13.class, Depth14.class), o); + test("isDepth12", profile(String.class, HashMap.class), o); } @LongTest
--- a/src/cpu/x86/vm/templateInterpreter_x86.hpp Tue Apr 09 19:29:12 2013 +0200 +++ b/src/cpu/x86/vm/templateInterpreter_x86.hpp Tue Apr 09 19:29:26 2013 +0200 @@ -34,7 +34,7 @@ // Run with +PrintInterpreter to get the VM to print out the size. // Max size with JVMTI #ifdef AMD64 - const static int InterpreterCodeSize = 224 * 1024; + const static int InterpreterCodeSize = 240 * 1024; #else const static int InterpreterCodeSize = 168 * 1024; #endif // AMD64
--- a/src/share/vm/classfile/systemDictionary.hpp Tue Apr 09 19:29:12 2013 +0200 +++ b/src/share/vm/classfile/systemDictionary.hpp Tue Apr 09 19:29:26 2013 +0200 @@ -201,6 +201,7 @@ do_klass(Assumptions_ConcreteMethod_klass, com_oracle_graal_api_code_Assumptions_ConcreteMethod, Opt) \ do_klass(Assumptions_ConcreteSubtype_klass, com_oracle_graal_api_code_Assumptions_ConcreteSubtype, Opt) \ do_klass(Assumptions_MethodContents_klass, com_oracle_graal_api_code_Assumptions_MethodContents, Opt) \ + do_klass(Assumptions_CallSiteTargetValue_klass, com_oracle_graal_api_code_Assumptions_CallSiteTargetValue, Opt) \ do_klass(BytecodePosition_klass, com_oracle_graal_api_code_BytecodePosition, Opt) \ do_klass(DebugInfo_klass, com_oracle_graal_api_code_DebugInfo, Opt) \ do_klass(BytecodeFrame_klass, com_oracle_graal_api_code_BytecodeFrame, Opt) \
--- a/src/share/vm/classfile/vmSymbols.hpp Tue Apr 09 19:29:12 2013 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Tue Apr 09 19:29:26 2013 +0200 @@ -323,6 +323,7 @@ template(com_oracle_graal_api_code_Assumptions_MethodContents, "com/oracle/graal/api/code/Assumptions$MethodContents") \ template(com_oracle_graal_api_code_Assumptions_ConcreteSubtype, "com/oracle/graal/api/code/Assumptions$ConcreteSubtype") \ template(com_oracle_graal_api_code_Assumptions_ConcreteMethod, "com/oracle/graal/api/code/Assumptions$ConcreteMethod") \ + template(com_oracle_graal_api_code_Assumptions_CallSiteTargetValue,"com/oracle/graal/api/code/Assumptions$CallSiteTargetValue") \ template(com_oracle_graal_api_code_CompilationResult, "com/oracle/graal/api/code/CompilationResult") \ template(com_oracle_graal_api_code_CompilationResult_Call, "com/oracle/graal/api/code/CompilationResult$Call") \ template(com_oracle_graal_api_code_CompilationResult_DataPatch, "com/oracle/graal/api/code/CompilationResult$DataPatch") \
--- a/src/share/vm/code/dependencies.cpp Tue Apr 09 19:29:12 2013 +0200 +++ b/src/share/vm/code/dependencies.cpp Tue Apr 09 19:29:26 2013 +0200 @@ -170,6 +170,10 @@ check_ctxk(ctxk); assert_common_2(unique_concrete_method, DepValue(_oop_recorder, ctxk), DepValue(_oop_recorder, uniqm)); } + +void Dependencies::assert_call_site_target_value(oop cs, oop mh) { + assert_common_2(call_site_target_value, DepValue(_oop_recorder, JNIHandles::make_local(cs)), DepValue(_oop_recorder, JNIHandles::make_local(mh))); +} #endif // GRAAL
--- a/src/share/vm/code/dependencies.hpp Tue Apr 09 19:29:12 2013 +0200 +++ b/src/share/vm/code/dependencies.hpp Tue Apr 09 19:29:26 2013 +0200 @@ -363,6 +363,7 @@ void assert_leaf_type(Klass* ctxk); void assert_unique_concrete_method(Klass* ctxk, Method* uniqm); void assert_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck); + void assert_call_site_target_value(oop callSite, oop methodHandle); #endif // GRAAL // Define whether a given method or type is concrete.
--- a/src/share/vm/graal/graalCodeInstaller.cpp Tue Apr 09 19:29:12 2013 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Tue Apr 09 19:29:26 2013 +0200 @@ -236,7 +236,7 @@ for (jint i = 0; i < values->length(); i++) { ScopeValue* cur_second = NULL; ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i], total_frame_size, objects, cur_second, oop_recorder); - + if (isLongArray && cur_second == NULL) { // we're trying to put ints into a long array... this isn't really valid, but it's used for some optimizations. // add an int 0 constant @@ -298,6 +298,8 @@ assumption_ConcreteSubtype(assumption); } else if (assumption->klass() == Assumptions_ConcreteMethod::klass()) { assumption_ConcreteMethod(assumption); + } else if (assumption->klass() == Assumptions_CallSiteTargetValue::klass()) { + assumption_CallSiteTargetValue(assumption); } else { assumption->print(); fatal("unexpected Assumption subclass"); @@ -350,7 +352,7 @@ // constructor used to create a stub CodeInstaller::CodeInstaller(Handle& target_method, BufferBlob*& blob, jlong& id) { No_Safepoint_Verifier no_safepoint; - + _oop_recorder = new OopRecorder(&_arena); initialize_fields(target_method(), NULL); assert(_name != NULL, "installMethod needs NON-NULL name"); @@ -398,7 +400,7 @@ _debug_recorder = new DebugInformationRecorder(_oop_recorder); _debug_recorder->set_oopmaps(new OopMapSet()); - + buffer.initialize_oop_recorder(_oop_recorder); _instructions = buffer.insts(); @@ -460,6 +462,13 @@ _dependencies->assert_unique_concrete_method(context, impl()); } +void CodeInstaller::assumption_CallSiteTargetValue(Handle assumption) { + Handle callSite = Assumptions_CallSiteTargetValue::callSite(assumption()); + Handle methodHandle = Assumptions_CallSiteTargetValue::methodHandle(assumption()); + + _dependencies->assert_call_site_target_value(callSite(), methodHandle()); +} + void CodeInstaller::process_exception_handlers() { // allocate some arrays for use by the collection code. const int num_handlers = 5;
--- a/src/share/vm/graal/graalCodeInstaller.hpp Tue Apr 09 19:29:12 2013 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Tue Apr 09 19:29:26 2013 +0200 @@ -95,6 +95,7 @@ void assumption_MethodContents(Handle assumption); void assumption_ConcreteSubtype(Handle assumption); void assumption_ConcreteMethod(Handle assumption); + void assumption_CallSiteTargetValue(Handle assumption); void site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site); void site_Call(CodeBuffer& buffer, jint pc_offset, oop site);
--- a/src/share/vm/graal/graalCompiler.hpp Tue Apr 09 19:29:12 2013 +0200 +++ b/src/share/vm/graal/graalCompiler.hpp Tue Apr 09 19:29:26 2013 +0200 @@ -68,7 +68,7 @@ // Print compilation timers and statistics virtual void print_timers(); - + static Handle get_JavaTypeFromSignature(Symbol* signature, KlassHandle accessor, TRAPS); static Handle get_JavaType(constantPoolHandle cp, int index, KlassHandle accessor, TRAPS); static Handle get_JavaType(Symbol* klass_name, TRAPS); @@ -93,6 +93,11 @@ return ((index & 0xFF) << 8) | (index >> 8); } + static int to_index_u4(int index) { + // Swap. + return ((index & 0xFF) << 24) | ((index & 0xFF00) << 8) | ((index & 0xFF0000) >> 8) | ((index & 0xFF000000) >> 24); + } + static void initialize_buffer_blob(); };
--- a/src/share/vm/graal/graalCompilerToVM.cpp Tue Apr 09 19:29:12 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Tue Apr 09 19:29:26 2013 +0200 @@ -62,7 +62,7 @@ C2V_ENTRY(jbyteArray, initializeBytecode, (JNIEnv *env, jobject, jlong metaspace_method, jbyteArray result)) methodHandle method = asMethod(metaspace_method); ResourceMark rm; - + int code_size = method->code_size(); jbyte* reconstituted_code = NULL; @@ -416,12 +416,21 @@ return JNIHandles::make_local(THREAD, result); C2V_END +C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv *env, jobject, jobject type, jint index)) + assert(GraalCompiler::to_index_u4(index) < 0, "not an invokedynamic constant pool index"); + constantPoolHandle cpool(InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants()); + oop appendix_oop = ConstantPool::appendix_at_if_loaded(cpool, GraalCompiler::to_index_u4(index)); + + return JNIHandles::make_local(THREAD, appendix_oop); +C2V_END + C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv *env, jobject, jobject type, jint index, jbyte opcode)) - index = GraalCompiler::to_cp_index_u2(index); constantPoolHandle cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants(); instanceKlassHandle pool_holder(cp->pool_holder()); Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF); + index = (bc == Bytecodes::_invokedynamic) ? GraalCompiler::to_index_u4(index) : GraalCompiler::to_cp_index_u2(index); + methodHandle method = GraalEnv::get_method_by_index(cp, index, bc, pool_holder); if (!method.is_null()) { Handle holder = GraalCompiler::get_JavaType(method->method_holder(), CHECK_NULL); @@ -430,8 +439,13 @@ // Get the method's name and signature. Handle name = java_lang_String::create_from_symbol(cp->name_ref_at(index), CHECK_NULL); Handle signature = java_lang_String::create_from_symbol(cp->signature_ref_at(index), CHECK_NULL); - int holder_index = cp->klass_ref_index_at(index); - Handle type = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL); + Handle type; + if (bc != Bytecodes::_invokedynamic) { + int holder_index = cp->klass_ref_index_at(index); + type = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL); + } else { + type = Handle(SystemDictionary::MethodHandle_klass()->java_mirror()); + } return JNIHandles::make_local(THREAD, VMToCompiler::createUnresolvedJavaMethod(name, signature, type, THREAD)); } C2V_END @@ -479,7 +493,7 @@ int holder_index = cp->klass_ref_index_at(index); Handle holder = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL); instanceKlassHandle holder_klass; - + Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF); int offset = -1; AccessFlags flags; @@ -499,7 +513,7 @@ holder = GraalCompiler::get_JavaType(holder_klass, CHECK_NULL); } } - + Handle type = GraalCompiler::get_JavaTypeFromSignature(signature, cp->pool_holder(), CHECK_NULL); Handle field_handle = GraalCompiler::get_JavaField(offset, flags.as_int(), name, holder, type, THREAD); @@ -663,7 +677,7 @@ set_int("arrayKlassLayoutHelperIdentifier", 0x80000000); assert((Klass::_lh_array_tag_obj_value & Klass::_lh_array_tag_type_value & 0x80000000) != 0, "obj_array and type_array must have first bit set"); set_int("arrayKlassComponentMirrorOffset", in_bytes(ArrayKlass::component_mirror_offset())); - + set_int("pendingDeoptimizationOffset", in_bytes(ThreadShadow::pending_deoptimization_offset())); @@ -1104,6 +1118,7 @@ {CC"getVtableEntryOffset", CC"("METASPACE_METHOD")I", FN_PTR(getVtableEntryOffset)}, {CC"lookupType", CC"("STRING HS_RESOLVED_TYPE"Z)"TYPE, FN_PTR(lookupType)}, {CC"lookupConstantInPool", CC"("HS_RESOLVED_TYPE"I)"OBJECT, FN_PTR(lookupConstantInPool)}, + {CC"lookupAppendixInPool", CC"("HS_RESOLVED_TYPE"I)"OBJECT, FN_PTR(lookupAppendixInPool)}, {CC"lookupMethodInPool", CC"("HS_RESOLVED_TYPE"IB)"METHOD, FN_PTR(lookupMethodInPool)}, {CC"lookupTypeInPool", CC"("HS_RESOLVED_TYPE"I)"TYPE, FN_PTR(lookupTypeInPool)}, {CC"lookupReferencedTypeInPool", CC"("HS_RESOLVED_TYPE"IB)V", FN_PTR(lookupReferencedTypeInPool)},
--- a/src/share/vm/graal/graalEnv.cpp Tue Apr 09 19:29:12 2013 +0200 +++ b/src/share/vm/graal/graalEnv.cpp Tue Apr 09 19:29:26 2013 +0200 @@ -319,6 +319,19 @@ methodHandle GraalEnv::get_method_by_index_impl(constantPoolHandle& cpool, int index, Bytecodes::Code bc, instanceKlassHandle& accessor) { + if (bc == Bytecodes::_invokedynamic) { + ConstantPoolCacheEntry* cpce = cpool->invokedynamic_cp_cache_entry_at(index); + bool is_resolved = !cpce->is_f1_null(); + if (is_resolved) { + // Get the invoker Method* from the constant pool. + // (The appendix argument, if any, will be noted in the method's signature.) + Method* adapter = cpce->f1_as_method(); + return methodHandle(adapter); + } + + return NULL; + } + int holder_index = cpool->klass_ref_index_at(index); bool holder_is_accessible; KlassHandle holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor); @@ -369,7 +382,6 @@ int index, Bytecodes::Code bc, instanceKlassHandle& accessor) { ResourceMark rm; - assert(bc != Bytecodes::_invokedynamic, "invokedynamic not yet supported"); return get_method_by_index_impl(cpool, index, bc, accessor); }
--- a/src/share/vm/graal/graalJavaAccess.hpp Tue Apr 09 19:29:12 2013 +0200 +++ b/src/share/vm/graal/graalJavaAccess.hpp Tue Apr 09 19:29:26 2013 +0200 @@ -119,6 +119,10 @@ oop_field(Assumptions_ConcreteMethod, context, "Lcom/oracle/graal/api/meta/ResolvedJavaType;") \ oop_field(Assumptions_ConcreteMethod, impl, "Lcom/oracle/graal/api/meta/ResolvedJavaMethod;") \ end_class \ + start_class(Assumptions_CallSiteTargetValue) \ + oop_field(Assumptions_CallSiteTargetValue, callSite, "Ljava/lang/invoke/CallSite;") \ + oop_field(Assumptions_CallSiteTargetValue, methodHandle, "Ljava/lang/invoke/MethodHandle;") \ + end_class \ start_class(CompilationResult_Site) \ int_field(CompilationResult_Site, pcOffset) \ end_class \