changeset 22396:65eab5908106

Split Word.fromObject into Word.objectToTrackedPointer and Word.objectToUntrackedPointer.
author Roland Schatz <roland.schatz@oracle.com>
date Fri, 31 Jul 2015 15:07:27 +0200
parents 30de5362b0ca
children ee4ceec1a0db
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/DerivedOopTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java
diffstat 13 files changed, 133 insertions(+), 92 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java	Fri Jul 31 14:26:26 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java	Fri Jul 31 15:07:27 2015 +0200
@@ -78,7 +78,7 @@
         checkArgs(in, inOffset, out, outOffset);
         Object realReceiver = PiNode.piCastNonNull(rcvr, AESCryptClass);
         Object kObject = UnsafeLoadNode.load(realReceiver, kOffset, Kind.Object, LocationIdentity.any());
-        Pointer kAddr = Word.fromObject(kObject).add(arrayBaseOffset(Kind.Byte));
+        Pointer kAddr = Word.objectToTrackedPointer(kObject).add(arrayBaseOffset(Kind.Byte));
         Word inAddr = Word.unsigned(ComputeObjectAddressNode.get(in, arrayBaseOffset(Kind.Byte) + inOffset));
         Word outAddr = Word.unsigned(ComputeObjectAddressNode.get(out, arrayBaseOffset(Kind.Byte) + outOffset));
         if (encrypt) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java	Fri Jul 31 14:26:26 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java	Fri Jul 31 15:07:27 2015 +0200
@@ -98,8 +98,8 @@
         Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass);
         Object kObject = UnsafeLoadNode.load(embeddedCipher, AESCryptSubstitutions.kOffset, Kind.Object, LocationIdentity.any());
         Object rObject = UnsafeLoadNode.load(realReceiver, rOffset, Kind.Object, LocationIdentity.any());
-        Pointer kAddr = Word.fromObject(kObject).add(arrayBaseOffset(Kind.Byte));
-        Pointer rAddr = Word.fromObject(rObject).add(arrayBaseOffset(Kind.Byte));
+        Pointer kAddr = Word.objectToTrackedPointer(kObject).add(arrayBaseOffset(Kind.Byte));
+        Pointer rAddr = Word.objectToTrackedPointer(rObject).add(arrayBaseOffset(Kind.Byte));
         Word inAddr = Word.unsigned(ComputeObjectAddressNode.get(in, arrayBaseOffset(Kind.Byte) + inOffset));
         Word outAddr = Word.unsigned(ComputeObjectAddressNode.get(out, arrayBaseOffset(Kind.Byte) + outOffset));
         if (encrypt) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Fri Jul 31 14:26:26 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Fri Jul 31 15:07:27 2015 +0200
@@ -110,7 +110,7 @@
 
         final Word lock = beginLockScope(lockDepth);
 
-        trace(trace, "           object: 0x%016lx\n", Word.fromObject(object));
+        trace(trace, "           object: 0x%016lx\n", Word.objectToTrackedPointer(object));
         trace(trace, "             lock: 0x%016lx\n", lock);
         trace(trace, "             mark: 0x%016lx\n", mark);
 
@@ -296,7 +296,7 @@
 
     @Snippet
     public static void monitorexit(Object object, @ConstantParameter int lockDepth, @ConstantParameter boolean trace) {
-        trace(trace, "           object: 0x%016lx\n", Word.fromObject(object));
+        trace(trace, "           object: 0x%016lx\n", Word.objectToTrackedPointer(object));
         if (useBiasedLocking()) {
             // Check for biased locking unlock case, which is a no-op
             // Note: we do not have to check the thread ID for two reasons.
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java	Fri Jul 31 14:26:26 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java	Fri Jul 31 15:07:27 2015 +0200
@@ -42,9 +42,9 @@
     public static Object lowerUnsafeLoad(Object object, long offset) {
         Object fixedObject = FixedValueAnchorNode.getObject(object);
         if (object instanceof java.lang.ref.Reference && referentOffset() == offset) {
-            return Word.fromObject(fixedObject).readObject((int) offset, BarrierType.PRECISE);
+            return Word.objectToTrackedPointer(fixedObject).readObject((int) offset, BarrierType.PRECISE);
         } else {
-            return Word.fromObject(fixedObject).readObject((int) offset, BarrierType.NONE);
+            return Word.objectToTrackedPointer(fixedObject).readObject((int) offset, BarrierType.NONE);
         }
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Fri Jul 31 14:26:26 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Fri Jul 31 15:07:27 2015 +0200
@@ -87,7 +87,7 @@
 
     @Snippet
     public static void serialImpreciseWriteBarrier(Object object) {
-        serialWriteBarrier(Word.fromObject(object));
+        serialWriteBarrier(Word.objectToTrackedPointer(object));
     }
 
     @Snippet
@@ -124,7 +124,7 @@
         verifyOop(object);
         Object fixedExpectedObject = FixedValueAnchorNode.getObject(expectedObject);
         Pointer field = Word.fromAddress(address);
-        Pointer previousOop = Word.fromObject(fixedExpectedObject);
+        Pointer previousOop = Word.objectToTrackedPointer(fixedExpectedObject);
         byte markingValue = thread.readByte(g1SATBQueueMarkingOffset());
         Word bufferAddress = thread.readWord(g1SATBQueueBufferOffset());
         Word indexAddress = thread.add(g1SATBQueueIndexOffset());
@@ -132,8 +132,8 @@
         int gcCycle = 0;
         if (trace) {
             gcCycle = (int) Word.unsigned(HotSpotReplacementsUtil.gcTotalCollectionsAddress()).readLong(0);
-            log(trace, "[%d] G1-Pre Thread %p Object %p\n", gcCycle, thread.rawValue(), Word.fromObject(object).rawValue());
-            log(trace, "[%d] G1-Pre Thread %p Expected Object %p\n", gcCycle, thread.rawValue(), Word.fromObject(fixedExpectedObject).rawValue());
+            log(trace, "[%d] G1-Pre Thread %p Object %p\n", gcCycle, thread.rawValue(), Word.objectToTrackedPointer(object).rawValue());
+            log(trace, "[%d] G1-Pre Thread %p Expected Object %p\n", gcCycle, thread.rawValue(), Word.objectToTrackedPointer(fixedExpectedObject).rawValue());
             log(trace, "[%d] G1-Pre Thread %p Field %p\n", gcCycle, thread.rawValue(), field.rawValue());
             log(trace, "[%d] G1-Pre Thread %p Marking %d\n", gcCycle, thread.rawValue(), markingValue);
             log(trace, "[%d] G1-Pre Thread %p DoLoad %d\n", gcCycle, thread.rawValue(), doLoad ? 1L : 0L);
@@ -144,7 +144,7 @@
             // If the previous value has to be loaded (before the write), the load is issued.
             // The load is always issued except the cases of CAS and referent field.
             if (probability(LIKELY_PROBABILITY, doLoad)) {
-                previousOop = Word.fromObject(field.readObject(0, BarrierType.NONE));
+                previousOop = Word.objectToTrackedPointer(field.readObject(0, BarrierType.NONE));
                 if (trace) {
                     log(trace, "[%d] G1-Pre Thread %p Previous Object %p\n ", gcCycle, thread.rawValue(), previousOop.rawValue());
                     verifyOop(previousOop.toObject());
@@ -181,15 +181,15 @@
         if (usePrecise) {
             oop = Word.fromAddress(address);
         } else {
-            oop = Word.fromObject(object);
+            oop = Word.objectToTrackedPointer(object);
         }
         int gcCycle = 0;
         if (trace) {
             gcCycle = (int) Word.unsigned(HotSpotReplacementsUtil.gcTotalCollectionsAddress()).readLong(0);
-            log(trace, "[%d] G1-Post Thread: %p Object: %p\n", gcCycle, thread.rawValue(), Word.fromObject(object).rawValue());
+            log(trace, "[%d] G1-Post Thread: %p Object: %p\n", gcCycle, thread.rawValue(), Word.objectToTrackedPointer(object).rawValue());
             log(trace, "[%d] G1-Post Thread: %p Field: %p\n", gcCycle, thread.rawValue(), oop.rawValue());
         }
-        Pointer writtenValue = Word.fromObject(fixedValue);
+        Pointer writtenValue = Word.objectToTrackedPointer(fixedValue);
         Word bufferAddress = thread.readWord(g1CardQueueBufferOffset());
         Word indexAddress = thread.add(g1CardQueueIndexOffset());
         Word indexValue = thread.readWord(g1CardQueueIndexOffset());
@@ -263,7 +263,7 @@
 
         for (int i = startIndex; i < length; i++) {
             long address = dstAddr + header + (i * scale);
-            Pointer oop = Word.fromObject(Word.unsigned(address).readObject(0, BarrierType.NONE));
+            Pointer oop = Word.objectToTrackedPointer(Word.unsigned(address).readObject(0, BarrierType.NONE));
             verifyOop(oop.toObject());
             if (oop.notEqual(0)) {
                 if (indexValue != 0) {
@@ -503,7 +503,7 @@
      */
     public static void validateObject(Object parent, Object child) {
         if (verifyOops() && child != null && !validateOop(VALIDATE_OBJECT, parent, child)) {
-            log(true, "Verification ERROR, Parent: %p Child: %p\n", Word.fromObject(parent).rawValue(), Word.fromObject(child).rawValue());
+            log(true, "Verification ERROR, Parent: %p Child: %p\n", Word.objectToTrackedPointer(parent).rawValue(), Word.objectToTrackedPointer(child).rawValue());
             DirectObjectStoreNode.storeObject(null, 0, 0, null, LocationIdentity.any(), Kind.Object);
         }
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java	Fri Jul 31 14:26:26 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java	Fri Jul 31 15:07:27 2015 +0200
@@ -78,8 +78,8 @@
         writeExceptionOop(thread, exception);
         writeExceptionPc(thread, exceptionPc);
         if (logging()) {
-            printf("handling exception %p (", Word.fromObject(exception).rawValue());
-            decipher(Word.fromObject(exception).rawValue());
+            printf("handling exception %p (", Word.objectToTrackedPointer(exception).rawValue());
+            decipher(Word.objectToTrackedPointer(exception).rawValue());
             printf(") at %p (", exceptionPc.rawValue());
             decipher(exceptionPc.rawValue());
             printf(")\n");
@@ -91,7 +91,7 @@
         Word handlerPc = exceptionHandlerForPc(EXCEPTION_HANDLER_FOR_PC, thread);
 
         if (logging()) {
-            printf("handler for exception %p at %p is at %p (", Word.fromObject(exception).rawValue(), exceptionPc.rawValue(), handlerPc.rawValue());
+            printf("handler for exception %p at %p is at %p (", Word.objectToTrackedPointer(exception).rawValue(), exceptionPc.rawValue(), handlerPc.rawValue());
             decipher(handlerPc.rawValue());
             printf(")\n");
         }
@@ -104,7 +104,7 @@
         if (enabled) {
             Object currentException = readExceptionOop(thread);
             if (currentException != null) {
-                fatal("exception object in thread must be null, not %p", Word.fromObject(currentException).rawValue());
+                fatal("exception object in thread must be null, not %p", Word.objectToTrackedPointer(currentException).rawValue());
             }
             if (cAssertionsEnabled()) {
                 // This thread-local is only cleared in DEBUG builds of the VM
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java	Fri Jul 31 14:26:26 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java	Fri Jul 31 15:07:27 2015 +0200
@@ -224,7 +224,7 @@
             Word verifyOopCounter = Word.unsigned(verifyOopCounterAddress());
             verifyOopCounter.writeInt(0, verifyOopCounter.readInt(0) + 1);
 
-            Pointer oop = Word.fromObject(object);
+            Pointer oop = Word.objectToTrackedPointer(object);
             if (object != null) {
                 GuardingNode anchorNode = SnippetAnchorNode.anchor();
                 // make sure object is 'reasonable'
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java	Fri Jul 31 14:26:26 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java	Fri Jul 31 15:07:27 2015 +0200
@@ -67,7 +67,7 @@
 
     @Snippet
     private static void unwindExceptionToCaller(Object exception, Word returnAddress, @ConstantParameter Register threadRegister) {
-        Pointer exceptionOop = Word.fromObject(exception);
+        Pointer exceptionOop = Word.objectToTrackedPointer(exception);
         if (logging()) {
             printf("unwinding exception %p (", exceptionOop.rawValue());
             decipher(exceptionOop.rawValue());
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/DerivedOopTest.java	Fri Jul 31 14:26:26 2015 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/DerivedOopTest.java	Fri Jul 31 15:07:27 2015 +0200
@@ -112,7 +112,7 @@
     }
 
     static long getRawPointerIntrinsic(Object obj) {
-        return Word.fromObject(obj).rawValue();
+        return Word.objectToTrackedPointer(obj).rawValue();
     }
 
     public static Result fieldOffsetSnippet(Result obj, long offset) {
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Fri Jul 31 14:26:26 2015 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Fri Jul 31 15:07:27 2015 +0200
@@ -157,242 +157,242 @@
 
     @Snippet
     public static byte readByte1(Object o, int offset) {
-        return Word.fromObject(o).readByte(offset, ID);
+        return Word.objectToTrackedPointer(o).readByte(offset, ID);
     }
 
     @Snippet
     public static byte readByte2(Object o, int offset) {
-        return Word.fromObject(o).readByte(Word.signed(offset), ID);
+        return Word.objectToTrackedPointer(o).readByte(Word.signed(offset), ID);
     }
 
     @Snippet
     public static byte readByte3(Object o, int offset) {
-        return Word.fromObject(o).readByte(offset);
+        return Word.objectToTrackedPointer(o).readByte(offset);
     }
 
     @Snippet
     public static void writeByte1(Object o, int offset, byte value) {
-        Word.fromObject(o).writeByte(offset, value, ID);
+        Word.objectToTrackedPointer(o).writeByte(offset, value, ID);
     }
 
     @Snippet
     public static void writeByte2(Object o, int offset, byte value) {
-        Word.fromObject(o).writeByte(Word.signed(offset), value, ID);
+        Word.objectToTrackedPointer(o).writeByte(Word.signed(offset), value, ID);
     }
 
     @Snippet
     public static void writeByte3(Object o, int offset, byte value) {
-        Word.fromObject(o).writeByte(offset, value);
+        Word.objectToTrackedPointer(o).writeByte(offset, value);
     }
 
     @Snippet
     public static char readChar1(Object o, int offset) {
-        return Word.fromObject(o).readChar(offset, ID);
+        return Word.objectToTrackedPointer(o).readChar(offset, ID);
     }
 
     @Snippet
     public static char readChar2(Object o, int offset) {
-        return Word.fromObject(o).readChar(Word.signed(offset), ID);
+        return Word.objectToTrackedPointer(o).readChar(Word.signed(offset), ID);
     }
 
     @Snippet
     public static char readChar3(Object o, int offset) {
-        return Word.fromObject(o).readChar(offset);
+        return Word.objectToTrackedPointer(o).readChar(offset);
     }
 
     @Snippet
     public static void writeChar1(Object o, int offset, char value) {
-        Word.fromObject(o).writeChar(offset, value, ID);
+        Word.objectToTrackedPointer(o).writeChar(offset, value, ID);
     }
 
     @Snippet
     public static void writeChar2(Object o, int offset, char value) {
-        Word.fromObject(o).writeChar(Word.signed(offset), value, ID);
+        Word.objectToTrackedPointer(o).writeChar(Word.signed(offset), value, ID);
     }
 
     @Snippet
     public static void writeChar3(Object o, int offset, char value) {
-        Word.fromObject(o).writeChar(offset, value);
+        Word.objectToTrackedPointer(o).writeChar(offset, value);
     }
 
     @Snippet
     public static short readShort1(Object o, int offset) {
-        return Word.fromObject(o).readShort(offset, ID);
+        return Word.objectToTrackedPointer(o).readShort(offset, ID);
     }
 
     @Snippet
     public static short readShort2(Object o, int offset) {
-        return Word.fromObject(o).readShort(Word.signed(offset), ID);
+        return Word.objectToTrackedPointer(o).readShort(Word.signed(offset), ID);
     }
 
     @Snippet
     public static short readShort3(Object o, int offset) {
-        return Word.fromObject(o).readShort(offset);
+        return Word.objectToTrackedPointer(o).readShort(offset);
     }
 
     @Snippet
     public static void writeShort1(Object o, int offset, short value) {
-        Word.fromObject(o).writeShort(offset, value, ID);
+        Word.objectToTrackedPointer(o).writeShort(offset, value, ID);
     }
 
     @Snippet
     public static void writeShort2(Object o, int offset, short value) {
-        Word.fromObject(o).writeShort(Word.signed(offset), value, ID);
+        Word.objectToTrackedPointer(o).writeShort(Word.signed(offset), value, ID);
     }
 
     @Snippet
     public static void writeShort3(Object o, int offset, short value) {
-        Word.fromObject(o).writeShort(offset, value);
+        Word.objectToTrackedPointer(o).writeShort(offset, value);
     }
 
     @Snippet
     public static int readInt1(Object o, int offset) {
-        return Word.fromObject(o).readInt(offset, ID);
+        return Word.objectToTrackedPointer(o).readInt(offset, ID);
     }
 
     @Snippet
     public static int readInt2(Object o, int offset) {
-        return Word.fromObject(o).readInt(Word.signed(offset), ID);
+        return Word.objectToTrackedPointer(o).readInt(Word.signed(offset), ID);
     }
 
     @Snippet
     public static int readInt3(Object o, int offset) {
-        return Word.fromObject(o).readInt(offset);
+        return Word.objectToTrackedPointer(o).readInt(offset);
     }
 
     @Snippet
     public static void writeInt1(Object o, int offset, int value) {
-        Word.fromObject(o).writeInt(offset, value, ID);
+        Word.objectToTrackedPointer(o).writeInt(offset, value, ID);
     }
 
     @Snippet
     public static void writeInt2(Object o, int offset, int value) {
-        Word.fromObject(o).writeInt(Word.signed(offset), value, ID);
+        Word.objectToTrackedPointer(o).writeInt(Word.signed(offset), value, ID);
     }
 
     @Snippet
     public static void writeInt3(Object o, int offset, int value) {
-        Word.fromObject(o).writeInt(offset, value);
+        Word.objectToTrackedPointer(o).writeInt(offset, value);
     }
 
     @Snippet
     public static long readLong1(Object o, int offset) {
-        return Word.fromObject(o).readLong(offset, ID);
+        return Word.objectToTrackedPointer(o).readLong(offset, ID);
     }
 
     @Snippet
     public static long readLong2(Object o, int offset) {
-        return Word.fromObject(o).readLong(Word.signed(offset), ID);
+        return Word.objectToTrackedPointer(o).readLong(Word.signed(offset), ID);
     }
 
     @Snippet
     public static long readLong3(Object o, int offset) {
-        return Word.fromObject(o).readLong(offset);
+        return Word.objectToTrackedPointer(o).readLong(offset);
     }
 
     @Snippet
     public static void writeLong1(Object o, int offset, long value) {
-        Word.fromObject(o).writeLong(offset, value, ID);
+        Word.objectToTrackedPointer(o).writeLong(offset, value, ID);
     }
 
     @Snippet
     public static void writeLong2(Object o, int offset, long value) {
-        Word.fromObject(o).writeLong(Word.signed(offset), value, ID);
+        Word.objectToTrackedPointer(o).writeLong(Word.signed(offset), value, ID);
     }
 
     @Snippet
     public static void writeLong3(Object o, int offset, long value) {
-        Word.fromObject(o).writeLong(offset, value);
+        Word.objectToTrackedPointer(o).writeLong(offset, value);
     }
 
     @Snippet
     public static float readFloat1(Object o, int offset) {
-        return Word.fromObject(o).readFloat(offset, ID);
+        return Word.objectToTrackedPointer(o).readFloat(offset, ID);
     }
 
     @Snippet
     public static float readFloat2(Object o, int offset) {
-        return Word.fromObject(o).readFloat(Word.signed(offset), ID);
+        return Word.objectToTrackedPointer(o).readFloat(Word.signed(offset), ID);
     }
 
     @Snippet
     public static float readFloat3(Object o, int offset) {
-        return Word.fromObject(o).readFloat(offset);
+        return Word.objectToTrackedPointer(o).readFloat(offset);
     }
 
     @Snippet
     public static void writeFloat1(Object o, int offset, float value) {
-        Word.fromObject(o).writeFloat(offset, value, ID);
+        Word.objectToTrackedPointer(o).writeFloat(offset, value, ID);
     }
 
     @Snippet
     public static void writeFloat2(Object o, int offset, float value) {
-        Word.fromObject(o).writeFloat(Word.signed(offset), value, ID);
+        Word.objectToTrackedPointer(o).writeFloat(Word.signed(offset), value, ID);
     }
 
     @Snippet
     public static void writeFloat3(Object o, int offset, float value) {
-        Word.fromObject(o).writeFloat(offset, value);
+        Word.objectToTrackedPointer(o).writeFloat(offset, value);
     }
 
     @Snippet
     public static double readDouble1(Object o, int offset) {
-        return Word.fromObject(o).readDouble(offset, ID);
+        return Word.objectToTrackedPointer(o).readDouble(offset, ID);
     }
 
     @Snippet
     public static double readDouble2(Object o, int offset) {
-        return Word.fromObject(o).readDouble(Word.signed(offset), ID);
+        return Word.objectToTrackedPointer(o).readDouble(Word.signed(offset), ID);
     }
 
     @Snippet
     public static double readDouble3(Object o, int offset) {
-        return Word.fromObject(o).readDouble(offset);
+        return Word.objectToTrackedPointer(o).readDouble(offset);
     }
 
     @Snippet
     public static void writeDouble1(Object o, int offset, double value) {
-        Word.fromObject(o).writeDouble(offset, value, ID);
+        Word.objectToTrackedPointer(o).writeDouble(offset, value, ID);
     }
 
     @Snippet
     public static void writeDouble2(Object o, int offset, double value) {
-        Word.fromObject(o).writeDouble(Word.signed(offset), value, ID);
+        Word.objectToTrackedPointer(o).writeDouble(Word.signed(offset), value, ID);
     }
 
     @Snippet
     public static void writeDouble3(Object o, int offset, double value) {
-        Word.fromObject(o).writeDouble(offset, value);
+        Word.objectToTrackedPointer(o).writeDouble(offset, value);
     }
 
     @Snippet
     public static Object readObject1(Object o, int offset) {
-        return Word.fromObject(o).readObject(offset, ID);
+        return Word.objectToTrackedPointer(o).readObject(offset, ID);
     }
 
     @Snippet
     public static Object readObject2(Object o, int offset) {
-        return Word.fromObject(o).readObject(Word.signed(offset), ID);
+        return Word.objectToTrackedPointer(o).readObject(Word.signed(offset), ID);
     }
 
     @Snippet
     public static Object readObject3(Object o, int offset) {
-        return Word.fromObject(o).readObject(offset);
+        return Word.objectToTrackedPointer(o).readObject(offset);
     }
 
     @Snippet
     public static void writeObject1(Object o, int offset, Object value) {
-        Word.fromObject(o).writeObject(offset, value, ID);
+        Word.objectToTrackedPointer(o).writeObject(offset, value, ID);
     }
 
     @Snippet
     public static void writeObject2(Object o, int offset, Object value) {
-        Word.fromObject(o).writeObject(Word.signed(offset), value, ID);
+        Word.objectToTrackedPointer(o).writeObject(Word.signed(offset), value, ID);
     }
 
     @Snippet
     public static void writeObject3(Object o, int offset, Object value) {
-        Word.fromObject(o).writeObject(offset, value);
+        Word.objectToTrackedPointer(o).writeObject(offset, value);
     }
 
     private void assertNumWordCasts(String snippetName, int expectedWordCasts) {
@@ -410,7 +410,7 @@
 
     @Snippet
     public static void unusedFromObject(Object o) {
-        Word.fromObject(o);
+        Word.objectToTrackedPointer(o);
     }
 
     @Test
@@ -420,7 +420,7 @@
 
     @Snippet
     public static void unusedRawValue(Object o) {
-        Word.fromObject(o).rawValue();
+        Word.objectToTrackedPointer(o).rawValue();
     }
 
     @Test
@@ -430,7 +430,7 @@
 
     @Snippet
     public static long usedRawValue(Object o) {
-        return Word.fromObject(o).rawValue();
+        return Word.objectToTrackedPointer(o).rawValue();
     }
 
     @Test
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java	Fri Jul 31 14:26:26 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java	Fri Jul 31 15:07:27 2015 +0200
@@ -263,10 +263,16 @@
                 b.push(returnKind, toUnsigned(b, args[0], Kind.Long));
                 break;
 
-            case FROM_OBJECT:
+            case OBJECT_TO_TRACKED:
                 assert args.length == 1;
-                WordCastNode objectToWord = b.add(WordCastNode.objectToWord(args[0], wordKind));
-                b.push(returnKind, objectToWord);
+                WordCastNode objectToTracked = b.add(WordCastNode.objectToTrackedPointer(args[0], wordKind));
+                b.push(returnKind, objectToTracked);
+                break;
+
+            case OBJECT_TO_UNTRACKED:
+                assert args.length == 1;
+                WordCastNode objectToUntracked = b.add(WordCastNode.objectToUntrackedPointer(args[0], wordKind));
+                b.push(returnKind, objectToUntracked);
                 break;
 
             case FROM_ADDRESS:
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java	Fri Jul 31 14:26:26 2015 +0200
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java	Fri Jul 31 15:07:27 2015 +0200
@@ -73,8 +73,9 @@
          ZERO,
          FROM_UNSIGNED,
          FROM_SIGNED,
-         FROM_OBJECT,
          FROM_ADDRESS,
+         OBJECT_TO_TRACKED,
+         OBJECT_TO_UNTRACKED,
          TO_OBJECT,
          TO_RAW_VALUE,
     }
@@ -172,8 +173,29 @@
         return unbox();
     }
 
-    @Operation(opcode = Opcode.FROM_OBJECT)
-    public static native Pointer fromObject(Object val);
+    /**
+     * Convert an {@link Object} to a {@link Pointer}, keeping the reference information. If the
+     * returned pointer or any value derived from it is alive across a safepoint, it will be
+     * tracked. Depending on the arithmetic on the pointer and the capabilities of the backend to
+     * deal with derived references, this may work correctly, or result in a compiler error.
+     */
+    @Operation(opcode = Opcode.OBJECT_TO_TRACKED)
+    public static native Pointer objectToTrackedPointer(Object val);
+
+    /**
+     * Convert an {@link Object} to a {@link Pointer}, dropping the reference information. If the
+     * returned pointer or any value derived from it is alive across a safepoint, it will be treated
+     * as a simple integer and not tracked by the garbage collector.
+     * <p>
+     * This is a dangerous operation, the GC could move the object without updating the pointer! Use
+     * only in combination with some mechanism to prevent the GC from moving or freeing the object
+     * as long as the pointer is in use.
+     * <p>
+     * If the result value should not be alive across a safepoint, it's better to use
+     * {@link #objectToTrackedPointer(Object)} instead.
+     */
+    @Operation(opcode = Opcode.OBJECT_TO_UNTRACKED)
+    public static native Pointer objectToUntrackedPointer(Object val);
 
     @Operation(opcode = Opcode.FROM_ADDRESS)
     public static native Pointer fromAddress(Address address);
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java	Fri Jul 31 14:26:26 2015 +0200
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java	Fri Jul 31 15:07:27 2015 +0200
@@ -33,34 +33,47 @@
 import com.oracle.graal.word.Word.Opcode;
 
 /**
- * Casts between Word and Object exposed by the {@link Opcode#FROM_OBJECT} and
- * {@link Opcode#TO_OBJECT} operations. It has an impact on the pointer maps for the GC, so it must
- * not be scheduled or optimized away.
+ * Casts between Word and Object exposed by the {@link Opcode#FROM_ADDRESS},
+ * {@link Opcode#OBJECT_TO_TRACKED}, {@link Opcode#OBJECT_TO_UNTRACKED} and {@link Opcode#TO_OBJECT}
+ * operations. It has an impact on the pointer maps for the GC, so it must not be scheduled or
+ * optimized away.
  */
 @NodeInfo
 public final class WordCastNode extends FixedWithNextNode implements LIRLowerable, Canonicalizable {
 
     public static final NodeClass<WordCastNode> TYPE = NodeClass.create(WordCastNode.class);
+
     @Input ValueNode input;
+    public final boolean trackedPointer;
 
     public static WordCastNode wordToObject(ValueNode input, Kind wordKind) {
         assert input.getKind() == wordKind;
         return new WordCastNode(StampFactory.object(), input);
     }
 
-    public static WordCastNode objectToWord(ValueNode input, Kind wordKind) {
-        assert input.stamp() instanceof ObjectStamp;
-        return new WordCastNode(StampFactory.forKind(wordKind), input);
-    }
-
     public static WordCastNode addressToWord(ValueNode input, Kind wordKind) {
         assert input.stamp() instanceof AbstractPointerStamp;
         return new WordCastNode(StampFactory.forKind(wordKind), input);
     }
 
-    public WordCastNode(Stamp stamp, ValueNode input) {
+    public static WordCastNode objectToTrackedPointer(ValueNode input, Kind wordKind) {
+        assert input.stamp() instanceof ObjectStamp;
+        return new WordCastNode(StampFactory.forKind(wordKind), input, true);
+    }
+
+    public static WordCastNode objectToUntrackedPointer(ValueNode input, Kind wordKind) {
+        assert input.stamp() instanceof ObjectStamp;
+        return new WordCastNode(StampFactory.forKind(wordKind), input, false);
+    }
+
+    protected WordCastNode(Stamp stamp, ValueNode input) {
+        this(stamp, input, true);
+    }
+
+    protected WordCastNode(Stamp stamp, ValueNode input, boolean trackedPointer) {
         super(TYPE, stamp);
         this.input = input;
+        this.trackedPointer = trackedPointer;
     }
 
     public ValueNode getInput() {
@@ -93,8 +106,8 @@
         LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp());
         assert generator.getLIRGeneratorTool().target().getSizeInBytes(kind.getPlatformKind()) == generator.getLIRGeneratorTool().target().getSizeInBytes(value.getPlatformKind());
 
-        if (kind.isValue() && !value.getLIRKind().isValue()) {
-            // only add reference information, but never drop it
+        if (trackedPointer && kind.isValue() && !value.getLIRKind().isValue()) {
+            // just change the PlatformKind, but don't drop reference information
             kind = value.getLIRKind().changeType(kind.getPlatformKind());
         }