diff graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java @ 18699:08b17b738500

Add hooks for verifying heap from generated code
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Tue, 16 Dec 2014 13:36:16 -0800
parents ecb9d0cedbab
children e23a5de08e2a
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Tue Dec 16 13:30:07 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Tue Dec 16 13:36:16 2014 -0800
@@ -24,6 +24,7 @@
 
 import static com.oracle.graal.api.code.UnsignedMath.*;
 import static com.oracle.graal.compiler.common.GraalOptions.*;
+import static com.oracle.graal.hotspot.nodes.CStringNode.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.Options.*;
 import static com.oracle.graal.nodes.PiArrayNode.*;
@@ -49,6 +50,7 @@
 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.options.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
@@ -354,6 +356,18 @@
         return memory.toObject();
     }
 
+    @Snippet
+    protected static void verifyHeap(@ConstantParameter Register threadRegister) {
+        Word thread = registerAsWord(threadRegister);
+        Word topValue = readTlabTop(thread);
+        if (!topValue.equal(Word.zero())) {
+            Word topValueContents = topValue.readWord(0, MARK_WORD_LOCATION);
+            if (topValueContents.equal(Word.zero())) {
+                AssertionSnippets.vmMessageC(AssertionSnippets.ASSERTION_VM_MESSAGE_C, true, cstring("overzeroing of TLAB detected"), 0L, 0L, 0L);
+            }
+        }
+    }
+
     /**
      * Formats some allocated memory with an object header and zeroes out the rest.
      */
@@ -378,6 +392,7 @@
         private final SnippetInfo allocateArrayDynamic = snippet(NewObjectSnippets.class, "allocateArrayDynamic");
         private final SnippetInfo allocateInstanceDynamic = snippet(NewObjectSnippets.class, "allocateInstanceDynamic");
         private final SnippetInfo newmultiarray = snippet(NewObjectSnippets.class, "newmultiarray");
+        private final SnippetInfo verifyHeap = snippet(NewObjectSnippets.class, "verifyHeap");
 
         public Templates(HotSpotProviders providers, TargetDescription target) {
             super(providers, providers.getSnippetReflection(), target);
@@ -482,6 +497,28 @@
             assert size >= 0;
             return size;
         }
+
+        static class WarnOnce {
+            static {
+                System.out.println("VerifyHeapNode requires a VM with asserts enabled.");
+            }
+
+            static void warn() {
+            }
+        }
+
+        public void lower(VerifyHeapNode verifyHeapNode, HotSpotRegistersProvider registers, HotSpotGraalRuntimeProvider runtime, LoweringTool tool) {
+            if (runtime.getConfig().cAssertions) {
+                Arguments args = new Arguments(verifyHeap, verifyHeapNode.graph().getGuardsStage(), tool.getLoweringStage());
+                args.addConst("threadRegister", registers.getThreadRegister());
+
+                SnippetTemplate template = template(args);
+                template.instantiate(providers.getMetaAccess(), verifyHeapNode, DEFAULT_REPLACER, args);
+            } else {
+                WarnOnce.warn();
+                GraphUtil.removeFixedWithUnusedInputs(verifyHeapNode);
+            }
+        }
     }
 
     private static final SnippetCounter.Group countersNew = SnippetCounters.getValue() ? new SnippetCounter.Group("NewInstance") : null;