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;