Mercurial > hg > graal-compiler
comparison graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java @ 7530:5e3d1a68664e
applied mx eclipseformat to all Java files
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 23 Jan 2013 16:34:57 +0100 |
parents | 4cc0efe5cffe |
children | 223f645acb9b |
comparison
equal
deleted
inserted
replaced
7529:4a11124a3563 | 7530:5e3d1a68664e |
---|---|
72 | 72 |
73 /** | 73 /** |
74 * HotSpot implementation of {@link GraalCodeCacheProvider}. | 74 * HotSpot implementation of {@link GraalCodeCacheProvider}. |
75 */ | 75 */ |
76 public abstract class HotSpotRuntime implements GraalCodeCacheProvider, SnippetProvider { | 76 public abstract class HotSpotRuntime implements GraalCodeCacheProvider, SnippetProvider { |
77 | |
77 public final HotSpotVMConfig config; | 78 public final HotSpotVMConfig config; |
78 | 79 |
79 protected final RegisterConfig regConfig; | 80 protected final RegisterConfig regConfig; |
80 protected final RegisterConfig globalStubRegConfig; | 81 protected final RegisterConfig globalStubRegConfig; |
81 protected final HotSpotGraalRuntime graalRuntime; | 82 protected final HotSpotGraalRuntime graalRuntime; |
90 | 91 |
91 private final Map<Descriptor, HotSpotRuntimeCallTarget> runtimeCalls = new HashMap<>(); | 92 private final Map<Descriptor, HotSpotRuntimeCallTarget> runtimeCalls = new HashMap<>(); |
92 private final Map<ResolvedJavaMethod, Stub> stubs = new HashMap<>(); | 93 private final Map<ResolvedJavaMethod, Stub> stubs = new HashMap<>(); |
93 | 94 |
94 /** | 95 /** |
95 * Holds onto objects that will be embedded in compiled code. HotSpot treats oops | 96 * Holds onto objects that will be embedded in compiled code. HotSpot treats oops embedded in |
96 * embedded in code as weak references so without an external strong root, such | 97 * code as weak references so without an external strong root, such an embedded oop will quickly |
97 * an embedded oop will quickly die. This in turn will cause the nmethod to | 98 * die. This in turn will cause the nmethod to be unloaded. |
98 * be unloaded. | |
99 */ | 99 */ |
100 private final Map<Object, Object> gcRoots = new HashMap<>(); | 100 private final Map<Object, Object> gcRoots = new HashMap<>(); |
101 | 101 |
102 /** | 102 /** |
103 * The offset from the origin of an array to the first element. | 103 * The offset from the origin of an array to the first element. |
104 * | 104 * |
105 * @return the offset in bytes | 105 * @return the offset in bytes |
106 */ | 106 */ |
107 public static int getArrayBaseOffset(Kind kind) { | 107 public static int getArrayBaseOffset(Kind kind) { |
108 switch (kind) { | 108 switch (kind) { |
109 case Boolean: | 109 case Boolean: |
129 } | 129 } |
130 } | 130 } |
131 | 131 |
132 /** | 132 /** |
133 * The scale used for the index when accessing elements of an array of this kind. | 133 * The scale used for the index when accessing elements of an array of this kind. |
134 * | 134 * |
135 * @return the scale in order to convert the index into a byte offset | 135 * @return the scale in order to convert the index into a byte offset |
136 */ | 136 */ |
137 public static int getArrayIndexScale(Kind kind) { | 137 public static int getArrayIndexScale(Kind kind) { |
138 switch (kind) { | 138 switch (kind) { |
139 case Boolean: | 139 case Boolean: |
274 /* arg1: flags */ Kind.Int)); | 274 /* arg1: flags */ Kind.Int)); |
275 | 275 |
276 // @formatter:on | 276 // @formatter:on |
277 } | 277 } |
278 | 278 |
279 | |
280 /** | 279 /** |
281 * Registers the details for linking a runtime call. | 280 * Registers the details for linking a runtime call. |
282 * | 281 * |
283 * @param descriptor name and signature of the call | 282 * @param descriptor name and signature of the call |
284 * @param address target address of the call | 283 * @param address target address of the call |
285 * @param tempRegs temporary registers used (and killed) by the call (null if none) | 284 * @param tempRegs temporary registers used (and killed) by the call (null if none) |
286 * @param ret where the call returns its result | 285 * @param ret where the call returns its result |
287 * @param args where arguments are passed to the call | 286 * @param args where arguments are passed to the call |
312 return kind == Kind.fromJavaClass(spec); | 311 return kind == Kind.fromJavaClass(spec); |
313 } | 312 } |
314 | 313 |
315 /** | 314 /** |
316 * Binds a snippet-base {@link Stub} to a runtime call descriptor. | 315 * Binds a snippet-base {@link Stub} to a runtime call descriptor. |
317 * | 316 * |
318 * @return the linkage information for a call to the stub | 317 * @return the linkage information for a call to the stub |
319 */ | 318 */ |
320 public HotSpotRuntimeCallTarget registerStub(Descriptor descriptor, Stub stub) { | 319 public HotSpotRuntimeCallTarget registerStub(Descriptor descriptor, Stub stub) { |
321 HotSpotRuntimeCallTarget linkage = runtimeCalls.get(descriptor); | 320 HotSpotRuntimeCallTarget linkage = runtimeCalls.get(descriptor); |
322 assert linkage != null; | 321 assert linkage != null; |
460 private static void addExceptionHandlersComment(CompilationResult tm, HexCodeFile hcf) { | 459 private static void addExceptionHandlersComment(CompilationResult tm, HexCodeFile hcf) { |
461 if (!tm.getExceptionHandlers().isEmpty()) { | 460 if (!tm.getExceptionHandlers().isEmpty()) { |
462 String nl = HexCodeFile.NEW_LINE; | 461 String nl = HexCodeFile.NEW_LINE; |
463 StringBuilder buf = new StringBuilder("------ Exception Handlers ------").append(nl); | 462 StringBuilder buf = new StringBuilder("------ Exception Handlers ------").append(nl); |
464 for (CompilationResult.ExceptionHandler e : tm.getExceptionHandlers()) { | 463 for (CompilationResult.ExceptionHandler e : tm.getExceptionHandlers()) { |
465 buf.append(" "). | 464 buf.append(" ").append(e.pcOffset).append(" -> ").append(e.handlerPos).append(nl); |
466 append(e.pcOffset).append(" -> "). | |
467 append(e.handlerPos). | |
468 append(nl); | |
469 hcf.addComment(e.pcOffset, "[exception -> " + e.handlerPos + "]"); | 465 hcf.addComment(e.pcOffset, "[exception -> " + e.handlerPos + "]"); |
470 hcf.addComment(e.handlerPos, "[exception handler for " + e.pcOffset + "]"); | 466 hcf.addComment(e.handlerPos, "[exception handler for " + e.pcOffset + "]"); |
471 } | 467 } |
472 hcf.addComment(0, buf.toString()); | 468 hcf.addComment(0, buf.toString()); |
473 } | 469 } |
506 public RegisterConfig lookupRegisterConfig(ResolvedJavaMethod method) { | 502 public RegisterConfig lookupRegisterConfig(ResolvedJavaMethod method) { |
507 return regConfig; | 503 return regConfig; |
508 } | 504 } |
509 | 505 |
510 /** | 506 /** |
511 * HotSpots needs an area suitable for storing a program counter for temporary use during the deoptimization process. | 507 * HotSpots needs an area suitable for storing a program counter for temporary use during the |
508 * deoptimization process. | |
512 */ | 509 */ |
513 @Override | 510 @Override |
514 public int getCustomStackAreaSize() { | 511 public int getCustomStackAreaSize() { |
515 return graalRuntime.getTarget().wordSize; | 512 return graalRuntime.getTarget().wordSize; |
516 } | 513 } |
546 invoke.node().dependencies().add(tool.createNullCheckGuard(receiver, invoke.leafGraphId())); | 543 invoke.node().dependencies().add(tool.createNullCheckGuard(receiver, invoke.leafGraphId())); |
547 } | 544 } |
548 JavaType[] signature = MetaUtil.signatureToTypes(callTarget.targetMethod().getSignature(), callTarget.isStatic() ? null : callTarget.targetMethod().getDeclaringClass()); | 545 JavaType[] signature = MetaUtil.signatureToTypes(callTarget.targetMethod().getSignature(), callTarget.isStatic() ? null : callTarget.targetMethod().getDeclaringClass()); |
549 | 546 |
550 AbstractCallTargetNode loweredCallTarget = null; | 547 AbstractCallTargetNode loweredCallTarget = null; |
551 if (callTarget.invokeKind() == InvokeKind.Virtual && | 548 if (callTarget.invokeKind() == InvokeKind.Virtual && GraalOptions.InlineVTableStubs && (GraalOptions.AlwaysInlineVTableStubs || invoke.isPolymorphic())) { |
552 GraalOptions.InlineVTableStubs && | |
553 (GraalOptions.AlwaysInlineVTableStubs || invoke.isPolymorphic())) { | |
554 | 549 |
555 HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod(); | 550 HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod(); |
556 if (!hsMethod.getDeclaringClass().isInterface()) { | 551 if (!hsMethod.getDeclaringClass().isInterface()) { |
557 int vtableEntryOffset = hsMethod.vtableEntryOffset(); | 552 int vtableEntryOffset = hsMethod.vtableEntryOffset(); |
558 if (vtableEntryOffset > 0) { | 553 if (vtableEntryOffset > 0) { |
559 // We use LocationNode.ANY_LOCATION for the reads that access the vtable entry and the compiled code entry | 554 // We use LocationNode.ANY_LOCATION for the reads that access the vtable |
555 // entry and the compiled code entry | |
560 // as HotSpot does not guarantee they are final values. | 556 // as HotSpot does not guarantee they are final values. |
561 assert vtableEntryOffset > 0; | 557 assert vtableEntryOffset > 0; |
562 LoadHubNode hub = graph.add(new LoadHubNode(receiver, wordKind)); | 558 LoadHubNode hub = graph.add(new LoadHubNode(receiver, wordKind)); |
563 ReadNode metaspaceMethod = graph.add(new ReadNode(hub, LocationNode.create(LocationNode.ANY_LOCATION, wordKind, vtableEntryOffset, graph), StampFactory.forKind(wordKind()))); | 559 ReadNode metaspaceMethod = graph.add(new ReadNode(hub, LocationNode.create(LocationNode.ANY_LOCATION, wordKind, vtableEntryOffset, graph), StampFactory.forKind(wordKind()))); |
564 ReadNode compiledEntry = graph.add(new ReadNode(metaspaceMethod, LocationNode.create(LocationNode.ANY_LOCATION, wordKind, config.methodCompiledEntryOffset, graph), StampFactory.forKind(wordKind()))); | 560 ReadNode compiledEntry = graph.add(new ReadNode(metaspaceMethod, LocationNode.create(LocationNode.ANY_LOCATION, wordKind, config.methodCompiledEntryOffset, graph), |
565 | 561 StampFactory.forKind(wordKind()))); |
566 loweredCallTarget = graph.add(new HotSpotIndirectCallTargetNode(metaspaceMethod, compiledEntry, parameters, invoke.node().stamp(), signature, callTarget.targetMethod(), CallingConvention.Type.JavaCall)); | 562 |
563 loweredCallTarget = graph.add(new HotSpotIndirectCallTargetNode(metaspaceMethod, compiledEntry, parameters, invoke.node().stamp(), signature, callTarget.targetMethod(), | |
564 CallingConvention.Type.JavaCall)); | |
567 | 565 |
568 graph.addBeforeFixed(invoke.node(), hub); | 566 graph.addBeforeFixed(invoke.node(), hub); |
569 graph.addAfterFixed(hub, metaspaceMethod); | 567 graph.addAfterFixed(hub, metaspaceMethod); |
570 graph.addAfterFixed(metaspaceMethod, compiledEntry); | 568 graph.addAfterFixed(metaspaceMethod, compiledEntry); |
571 } | 569 } |
572 } | 570 } |
573 } | 571 } |
574 | 572 |
575 if (loweredCallTarget == null) { | 573 if (loweredCallTarget == null) { |
576 loweredCallTarget = graph.add(new HotSpotDirectCallTargetNode(parameters, invoke.node().stamp(), signature, callTarget.targetMethod(), CallingConvention.Type.JavaCall, callTarget.invokeKind())); | 574 loweredCallTarget = graph.add(new HotSpotDirectCallTargetNode(parameters, invoke.node().stamp(), signature, callTarget.targetMethod(), CallingConvention.Type.JavaCall, |
575 callTarget.invokeKind())); | |
577 } | 576 } |
578 callTarget.replaceAndDelete(loweredCallTarget); | 577 callTarget.replaceAndDelete(loweredCallTarget); |
579 } | 578 } |
580 } else if (n instanceof LoadFieldNode) { | 579 } else if (n instanceof LoadFieldNode) { |
581 LoadFieldNode loadField = (LoadFieldNode) n; | 580 LoadFieldNode loadField = (LoadFieldNode) n; |
675 } else if (n instanceof UnsafeLoadNode) { | 674 } else if (n instanceof UnsafeLoadNode) { |
676 UnsafeLoadNode load = (UnsafeLoadNode) n; | 675 UnsafeLoadNode load = (UnsafeLoadNode) n; |
677 assert load.kind() != Kind.Illegal; | 676 assert load.kind() != Kind.Illegal; |
678 IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, load.accessKind(), load.displacement(), load.offset(), graph, false); | 677 IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, load.accessKind(), load.displacement(), load.offset(), graph, false); |
679 ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp())); | 678 ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp())); |
680 // An unsafe read must not floating outside its block as may float above an explicit null check on its object. | 679 // An unsafe read must not floating outside its block as may float above an explicit |
680 // null check on its object. | |
681 memoryRead.dependencies().add(BeginNode.prevBegin(load)); | 681 memoryRead.dependencies().add(BeginNode.prevBegin(load)); |
682 graph.replaceFixedWithFixed(load, memoryRead); | 682 graph.replaceFixedWithFixed(load, memoryRead); |
683 } else if (n instanceof UnsafeStoreNode) { | 683 } else if (n instanceof UnsafeStoreNode) { |
684 UnsafeStoreNode store = (UnsafeStoreNode) n; | 684 UnsafeStoreNode store = (UnsafeStoreNode) n; |
685 IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, store.accessKind(), store.displacement(), store.offset(), graph, false); | 685 IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, store.accessKind(), store.displacement(), store.offset(), graph, false); |
736 } else if (n instanceof InitializeArrayNode) { | 736 } else if (n instanceof InitializeArrayNode) { |
737 newObjectSnippets.lower((InitializeArrayNode) n, tool); | 737 newObjectSnippets.lower((InitializeArrayNode) n, tool); |
738 } else if (n instanceof NewMultiArrayNode) { | 738 } else if (n instanceof NewMultiArrayNode) { |
739 newObjectSnippets.lower((NewMultiArrayNode) n, tool); | 739 newObjectSnippets.lower((NewMultiArrayNode) n, tool); |
740 } else if (n instanceof IntegerDivNode || n instanceof IntegerRemNode || n instanceof UnsignedDivNode || n instanceof UnsignedRemNode) { | 740 } else if (n instanceof IntegerDivNode || n instanceof IntegerRemNode || n instanceof UnsignedDivNode || n instanceof UnsignedRemNode) { |
741 // Nothing to do for division nodes. The HotSpot signal handler catches divisions by zero and the MIN_VALUE / -1 cases. | 741 // Nothing to do for division nodes. The HotSpot signal handler catches divisions by |
742 // zero and the MIN_VALUE / -1 cases. | |
742 } else { | 743 } else { |
743 assert false : "Node implementing Lowerable not handled: " + n; | 744 assert false : "Node implementing Lowerable not handled: " + n; |
744 throw GraalInternalError.shouldNotReachHere(); | 745 throw GraalInternalError.shouldNotReachHere(); |
745 } | 746 } |
746 } | 747 } |
777 return callTarget; | 778 return callTarget; |
778 } | 779 } |
779 | 780 |
780 /** | 781 /** |
781 * Gets the stub corresponding to a given method. | 782 * Gets the stub corresponding to a given method. |
782 * | 783 * |
783 * @return the stub {@linkplain Stub#getMethod() implemented} by {@code method} or null if {@code method} does not | 784 * @return the stub {@linkplain Stub#getMethod() implemented} by {@code method} or null if |
784 * implement a stub | 785 * {@code method} does not implement a stub |
785 */ | 786 */ |
786 public Stub asStub(ResolvedJavaMethod method) { | 787 public Stub asStub(ResolvedJavaMethod method) { |
787 return stubs.get(method); | 788 return stubs.get(method); |
788 } | 789 } |
789 | 790 |
847 int reasonValue = convertDeoptReason(reason); | 848 int reasonValue = convertDeoptReason(reason); |
848 return (~(((reasonValue) << reasonShift) + ((actionValue) << actionShift))); | 849 return (~(((reasonValue) << reasonShift) + ((actionValue) << actionShift))); |
849 } | 850 } |
850 | 851 |
851 public int convertDeoptAction(DeoptimizationAction action) { | 852 public int convertDeoptAction(DeoptimizationAction action) { |
852 switch(action) { | 853 switch (action) { |
853 case None: return config.deoptActionNone; | 854 case None: |
854 case RecompileIfTooManyDeopts: return config.deoptActionMaybeRecompile; | 855 return config.deoptActionNone; |
855 case InvalidateReprofile: return config.deoptActionReinterpret; | 856 case RecompileIfTooManyDeopts: |
856 case InvalidateRecompile: return config.deoptActionMakeNotEntrant; | 857 return config.deoptActionMaybeRecompile; |
857 case InvalidateStopCompiling: return config.deoptActionMakeNotCompilable; | 858 case InvalidateReprofile: |
858 default: throw GraalInternalError.shouldNotReachHere(); | 859 return config.deoptActionReinterpret; |
860 case InvalidateRecompile: | |
861 return config.deoptActionMakeNotEntrant; | |
862 case InvalidateStopCompiling: | |
863 return config.deoptActionMakeNotCompilable; | |
864 default: | |
865 throw GraalInternalError.shouldNotReachHere(); | |
859 } | 866 } |
860 } | 867 } |
861 | 868 |
862 public int convertDeoptReason(DeoptimizationReason reason) { | 869 public int convertDeoptReason(DeoptimizationReason reason) { |
863 switch(reason) { | 870 switch (reason) { |
864 case None: return config.deoptReasonNone; | 871 case None: |
865 case NullCheckException: return config.deoptReasonNullCheck; | 872 return config.deoptReasonNone; |
866 case BoundsCheckException: return config.deoptReasonRangeCheck; | 873 case NullCheckException: |
867 case ClassCastException: return config.deoptReasonClassCheck; | 874 return config.deoptReasonNullCheck; |
868 case ArrayStoreException: return config.deoptReasonArrayCheck; | 875 case BoundsCheckException: |
869 case UnreachedCode: return config.deoptReasonUnreached0; | 876 return config.deoptReasonRangeCheck; |
870 case TypeCheckedInliningViolated: return config.deoptReasonTypeCheckInlining; | 877 case ClassCastException: |
871 case OptimizedTypeCheckViolated: return config.deoptReasonOptimizedTypeCheck; | 878 return config.deoptReasonClassCheck; |
872 case NotCompiledExceptionHandler: return config.deoptReasonNotCompiledExceptionHandler; | 879 case ArrayStoreException: |
873 case Unresolved: return config.deoptReasonUnresolved; | 880 return config.deoptReasonArrayCheck; |
874 case JavaSubroutineMismatch: return config.deoptReasonJsrMismatch; | 881 case UnreachedCode: |
875 case ArithmeticException: return config.deoptReasonDiv0Check; | 882 return config.deoptReasonUnreached0; |
876 case RuntimeConstraint: return config.deoptReasonConstraint; | 883 case TypeCheckedInliningViolated: |
877 default: throw GraalInternalError.shouldNotReachHere(); | 884 return config.deoptReasonTypeCheckInlining; |
885 case OptimizedTypeCheckViolated: | |
886 return config.deoptReasonOptimizedTypeCheck; | |
887 case NotCompiledExceptionHandler: | |
888 return config.deoptReasonNotCompiledExceptionHandler; | |
889 case Unresolved: | |
890 return config.deoptReasonUnresolved; | |
891 case JavaSubroutineMismatch: | |
892 return config.deoptReasonJsrMismatch; | |
893 case ArithmeticException: | |
894 return config.deoptReasonDiv0Check; | |
895 case RuntimeConstraint: | |
896 return config.deoptReasonConstraint; | |
897 default: | |
898 throw GraalInternalError.shouldNotReachHere(); | |
878 } | 899 } |
879 } | 900 } |
880 | 901 |
881 public boolean needsDataPatch(Constant constant) { | 902 public boolean needsDataPatch(Constant constant) { |
882 return constant.getPrimitiveAnnotation() instanceof HotSpotResolvedObjectType; | 903 return constant.getPrimitiveAnnotation() instanceof HotSpotResolvedObjectType; |
883 } | 904 } |
884 | 905 |
885 /** | 906 /** |
886 * Registers an object created by the compiler and referenced by some generated code. | 907 * Registers an object created by the compiler and referenced by some generated code. HotSpot |
887 * HotSpot treats oops embedded in code as weak references so without an external strong root, such | 908 * treats oops embedded in code as weak references so without an external strong root, such an |
888 * an embedded oop will quickly die. This in turn will cause the nmethod to be unloaded. | 909 * embedded oop will quickly die. This in turn will cause the nmethod to be unloaded. |
889 */ | 910 */ |
890 public synchronized Object registerGCRoot(Object object) { | 911 public synchronized Object registerGCRoot(Object object) { |
891 Object existing = gcRoots.get(object); | 912 Object existing = gcRoots.get(object); |
892 if (existing != null) { | 913 if (existing != null) { |
893 return existing; | 914 return existing; |