# HG changeset patch # User Christian Wimmer # Date 1380236001 25200 # Node ID 8db5e8c4f542972c6d0c513c6ea019d7d84d02d9 # Parent 43bc62c78f776bb4dd7e1123a53c66eea4ca7c5d Provide object read/write methods similar to Pointer.readXxxx/writeXxx that do not require casts to Word first, and use them in relevant places diff -r 43bc62c78f77 -r 8db5e8c4f542 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java Thu Sep 26 22:45:25 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java Thu Sep 26 15:53:21 2013 -0700 @@ -56,9 +56,12 @@ Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION); Object result = NewObjectSnippets.allocateInstance(instanceSize, hub, prototypeMarkWord, false); - Pointer memory = Word.fromObject(result); for (int offset = instanceHeaderSize(); offset < instanceSize; offset += wordSize()) { - memory.writeWord(offset, Word.fromObject(src).readWord(offset, ANY_LOCATION), ANY_LOCATION); + /* + * TODO atomicity problem on 32-bit architectures: The JVM spec requires double values + * to be copied atomically, but here they are copied as two 4-byte word values. + */ + ObjectAccess.writeWord(result, offset, ObjectAccess.readWord(src, offset, ANY_LOCATION), ANY_LOCATION); } return result; @@ -73,9 +76,12 @@ Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION); Object result = NewObjectSnippets.allocateArray(hub, arrayLength, prototypeMarkWord, headerSize, log2ElementSize, false); - Pointer memory = Word.fromObject(result); for (int offset = headerSize; offset < sizeInBytes; offset += wordSize()) { - memory.writeWord(offset, Word.fromObject(src).readWord(offset, ANY_LOCATION), ANY_LOCATION); + /* + * TODO atomicity problem on 32-bit architectures: The JVM spec requires double values + * to be copied atomically, but here they are copied as two 4-byte word values. + */ + ObjectAccess.writeWord(result, offset, ObjectAccess.readWord(src, offset, ANY_LOCATION), ANY_LOCATION); } return result; } diff -r 43bc62c78f77 -r 8db5e8c4f542 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java Thu Sep 26 22:45:25 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java Thu Sep 26 15:53:21 2013 -0700 @@ -192,6 +192,11 @@ } } else { for (long i = 0; i < byteLength; i += VECTOR_SIZE) { + /* + * TODO atomicity problem on 32-bit architectures: The JVM spec requires double + * values to be copied atomically, but not long values. For example, on Intel 32-bit + * this code is not atomic as long as the vector kind remains Kind.Long. + */ Long a = UnsafeLoadNode.load(src, arrayBaseOffset, i + srcOffset, VECTOR_KIND); UnsafeStoreNode.store(dest, arrayBaseOffset, i + destOffset, a.longValue(), VECTOR_KIND); } @@ -225,22 +230,22 @@ int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask(); int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask(); - Word srcOffset = (Word) Word.fromObject(src).add(headerSize).add(srcPos << log2ElementSize); - Word destOffset = (Word) Word.fromObject(dest).add(headerSize).add(destPos << log2ElementSize); - Word destStart = destOffset; - long sizeInBytes = ((long) length) << log2ElementSize; - Word destEnd = destOffset.add(Word.unsigned(length).shiftLeft(log2ElementSize)); + Unsigned srcOffset = Word.unsigned(srcPos).shiftLeft(log2ElementSize).add(headerSize); + Unsigned destOffset = Word.unsigned(destPos).shiftLeft(log2ElementSize).add(headerSize); + Unsigned destStart = destOffset; + Unsigned sizeInBytes = Word.unsigned(length).shiftLeft(log2ElementSize); + Unsigned destEnd = destOffset.add(Word.unsigned(length).shiftLeft(log2ElementSize)); - int nonVectorBytes = (int) (sizeInBytes % VECTOR_SIZE); - Word destNonVectorEnd = destStart.add(nonVectorBytes); + Unsigned nonVectorBytes = sizeInBytes.unsignedRemainder(Word.unsigned(VECTOR_SIZE)); + Unsigned destNonVectorEnd = destStart.add(nonVectorBytes); while (destOffset.belowThan(destNonVectorEnd)) { - destOffset.writeByte(0, srcOffset.readByte(0, ANY_LOCATION), ANY_LOCATION); + ObjectAccess.writeByte(dest, destOffset, ObjectAccess.readByte(src, srcOffset, ANY_LOCATION), ANY_LOCATION); destOffset = destOffset.add(1); srcOffset = srcOffset.add(1); } while (destOffset.belowThan(destEnd)) { - destOffset.writeWord(0, srcOffset.readWord(0, ANY_LOCATION), ANY_LOCATION); + ObjectAccess.writeWord(dest, destOffset, ObjectAccess.readWord(src, srcOffset, ANY_LOCATION), ANY_LOCATION); destOffset = destOffset.add(wordSize()); srcOffset = srcOffset.add(wordSize()); } diff -r 43bc62c78f77 -r 8db5e8c4f542 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ArrayCopyGeneric.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ArrayCopyGeneric.java Thu Sep 26 15:53:21 2013 -0700 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011, 2012, 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.jtt.optimize; + +import com.oracle.graal.jtt.*; + +import org.junit.*; + +/* + * Tests calls to the array copy method. + */ +public class ArrayCopyGeneric extends JTTTest { + + public Object[] arraysFrom; + public Object[] arraysTo; + + public void init() { + arraysFrom = new Object[]{new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, new short[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + new long[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, new float[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}; + arraysTo = new Object[]{new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, new short[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + new long[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, new float[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}; + } + + public Object test() { + init(); + + for (int i = 0; i < arraysFrom.length; i++) { + Object from = arraysFrom[i]; + Object to = arraysTo[i]; + System.arraycopy(from, 1, to, 2, 2); + System.arraycopy(from, 8, to, 7, 2); + } + return arraysTo; + } + + @Test + public void run0() throws Throwable { + runTest("test"); + } +} diff -r 43bc62c78f77 -r 8db5e8c4f542 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java Thu Sep 26 15:53:21 2013 -0700 @@ -0,0 +1,390 @@ +/* + * Copyright (c) 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.replacements.test; + +import java.lang.reflect.*; + +import org.junit.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.runtime.*; +import com.oracle.graal.compiler.test.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.replacements.*; +import com.oracle.graal.replacements.Snippet.SnippetInliningPolicy; +import com.oracle.graal.word.*; + +/** + * Tests for the {@link Pointer} read and write operations. + */ +public class ObjectAccessTest extends GraalCompilerTest implements Snippets { + + private static final LocationIdentity ID = new NamedLocationIdentity("ID"); + private static final Kind[] KINDS = new Kind[]{Kind.Byte, Kind.Char, Kind.Short, Kind.Int, Kind.Long, Kind.Float, Kind.Double, Kind.Object}; + private final TargetDescription target; + private final ReplacementsImpl installer; + + public ObjectAccessTest() { + target = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget(); + installer = new ReplacementsImpl(runtime, new Assumptions(false), target); + } + + private static final ThreadLocal inliningPolicy = new ThreadLocal<>(); + + @Override + protected StructuredGraph parse(Method m) { + ResolvedJavaMethod resolvedMethod = runtime.lookupJavaMethod(m); + return installer.makeGraph(resolvedMethod, null, inliningPolicy.get()); + } + + @Test + public void testRead1() { + for (Kind kind : KINDS) { + assertRead(parse("read" + kind.name() + "1"), kind, false, ID); + } + } + + @Test + public void testRead2() { + for (Kind kind : KINDS) { + assertRead(parse("read" + kind.name() + "2"), kind, true, ID); + } + } + + @Test + public void testRead3() { + for (Kind kind : KINDS) { + assertRead(parse("read" + kind.name() + "3"), kind, false, LocationIdentity.ANY_LOCATION); + } + } + + @Test + public void testWrite1() { + for (Kind kind : KINDS) { + assertWrite(parse("write" + kind.name() + "1"), kind, false, ID); + } + } + + @Test + public void testWrite2() { + for (Kind kind : KINDS) { + assertWrite(parse("write" + kind.name() + "2"), kind, true, ID); + } + } + + @Test + public void testWrite3() { + for (Kind kind : KINDS) { + assertWrite(parse("write" + kind.name() + "3"), kind, false, LocationIdentity.ANY_LOCATION); + } + } + + private static void assertRead(StructuredGraph graph, Kind kind, boolean indexConvert, LocationIdentity locationIdentity) { + ReadNode read = (ReadNode) graph.start().next(); + Assert.assertEquals(kind.getStackKind(), read.kind()); + Assert.assertEquals(graph.getLocal(0), read.object()); + + IndexedLocationNode location = (IndexedLocationNode) read.location(); + Assert.assertEquals(kind, location.getValueKind()); + Assert.assertEquals(locationIdentity, location.getLocationIdentity()); + Assert.assertEquals(1, location.getIndexScaling()); + + if (indexConvert) { + ConvertNode convert = (ConvertNode) location.getIndex(); + Assert.assertEquals(ConvertNode.Op.I2L, convert.opcode); + Assert.assertEquals(graph.getLocal(1), convert.value()); + } else { + Assert.assertEquals(graph.getLocal(1), location.getIndex()); + } + + ReturnNode ret = (ReturnNode) read.next(); + Assert.assertEquals(read, ret.result()); + } + + private static void assertWrite(StructuredGraph graph, Kind kind, boolean indexConvert, LocationIdentity locationIdentity) { + WriteNode write = (WriteNode) graph.start().next(); + Assert.assertEquals(graph.getLocal(2), write.value()); + Assert.assertEquals(graph.getLocal(0), write.object()); + Assert.assertEquals(Kind.Void, write.kind()); + Assert.assertEquals(FrameState.AFTER_BCI, write.stateAfter().bci); + + IndexedLocationNode location = (IndexedLocationNode) write.location(); + Assert.assertEquals(kind, location.getValueKind()); + Assert.assertEquals(locationIdentity, location.getLocationIdentity()); + Assert.assertEquals(1, location.getIndexScaling()); + + if (indexConvert) { + ConvertNode convert = (ConvertNode) location.getIndex(); + Assert.assertEquals(ConvertNode.Op.I2L, convert.opcode); + Assert.assertEquals(graph.getLocal(1), convert.value()); + } else { + Assert.assertEquals(graph.getLocal(1), location.getIndex()); + } + + ReturnNode ret = (ReturnNode) write.next(); + Assert.assertEquals(null, ret.result()); + } + + @Snippet + public static byte readByte1(Object o, int offset) { + return ObjectAccess.readByte(o, offset, ID); + } + + @Snippet + public static byte readByte2(Object o, int offset) { + return ObjectAccess.readByte(o, Word.signed(offset), ID); + } + + @Snippet + public static byte readByte3(Object o, int offset) { + return ObjectAccess.readByte(o, offset); + } + + @Snippet + public static void writeByte1(Object o, int offset, byte value) { + ObjectAccess.writeByte(o, offset, value, ID); + } + + @Snippet + public static void writeByte2(Object o, int offset, byte value) { + ObjectAccess.writeByte(o, Word.signed(offset), value, ID); + } + + @Snippet + public static void writeByte3(Object o, int offset, byte value) { + ObjectAccess.writeByte(o, offset, value); + } + + @Snippet + public static char readChar1(Object o, int offset) { + return ObjectAccess.readChar(o, offset, ID); + } + + @Snippet + public static char readChar2(Object o, int offset) { + return ObjectAccess.readChar(o, Word.signed(offset), ID); + } + + @Snippet + public static char readChar3(Object o, int offset) { + return ObjectAccess.readChar(o, offset); + } + + @Snippet + public static void writeChar1(Object o, int offset, char value) { + ObjectAccess.writeChar(o, offset, value, ID); + } + + @Snippet + public static void writeChar2(Object o, int offset, char value) { + ObjectAccess.writeChar(o, Word.signed(offset), value, ID); + } + + @Snippet + public static void writeChar3(Object o, int offset, char value) { + ObjectAccess.writeChar(o, offset, value); + } + + @Snippet + public static short readShort1(Object o, int offset) { + return ObjectAccess.readShort(o, offset, ID); + } + + @Snippet + public static short readShort2(Object o, int offset) { + return ObjectAccess.readShort(o, Word.signed(offset), ID); + } + + @Snippet + public static short readShort3(Object o, int offset) { + return ObjectAccess.readShort(o, offset); + } + + @Snippet + public static void writeShort1(Object o, int offset, short value) { + ObjectAccess.writeShort(o, offset, value, ID); + } + + @Snippet + public static void writeShort2(Object o, int offset, short value) { + ObjectAccess.writeShort(o, Word.signed(offset), value, ID); + } + + @Snippet + public static void writeShort3(Object o, int offset, short value) { + ObjectAccess.writeShort(o, offset, value); + } + + @Snippet + public static int readInt1(Object o, int offset) { + return ObjectAccess.readInt(o, offset, ID); + } + + @Snippet + public static int readInt2(Object o, int offset) { + return ObjectAccess.readInt(o, Word.signed(offset), ID); + } + + @Snippet + public static int readInt3(Object o, int offset) { + return ObjectAccess.readInt(o, offset); + } + + @Snippet + public static void writeInt1(Object o, int offset, int value) { + ObjectAccess.writeInt(o, offset, value, ID); + } + + @Snippet + public static void writeInt2(Object o, int offset, int value) { + ObjectAccess.writeInt(o, Word.signed(offset), value, ID); + } + + @Snippet + public static void writeInt3(Object o, int offset, int value) { + ObjectAccess.writeInt(o, offset, value); + } + + @Snippet + public static long readLong1(Object o, int offset) { + return ObjectAccess.readLong(o, offset, ID); + } + + @Snippet + public static long readLong2(Object o, int offset) { + return ObjectAccess.readLong(o, Word.signed(offset), ID); + } + + @Snippet + public static long readLong3(Object o, int offset) { + return ObjectAccess.readLong(o, offset); + } + + @Snippet + public static void writeLong1(Object o, int offset, long value) { + ObjectAccess.writeLong(o, offset, value, ID); + } + + @Snippet + public static void writeLong2(Object o, int offset, long value) { + ObjectAccess.writeLong(o, Word.signed(offset), value, ID); + } + + @Snippet + public static void writeLong3(Object o, int offset, long value) { + ObjectAccess.writeLong(o, offset, value); + } + + @Snippet + public static float readFloat1(Object o, int offset) { + return ObjectAccess.readFloat(o, offset, ID); + } + + @Snippet + public static float readFloat2(Object o, int offset) { + return ObjectAccess.readFloat(o, Word.signed(offset), ID); + } + + @Snippet + public static float readFloat3(Object o, int offset) { + return ObjectAccess.readFloat(o, offset); + } + + @Snippet + public static void writeFloat1(Object o, int offset, float value) { + ObjectAccess.writeFloat(o, offset, value, ID); + } + + @Snippet + public static void writeFloat2(Object o, int offset, float value) { + ObjectAccess.writeFloat(o, Word.signed(offset), value, ID); + } + + @Snippet + public static void writeFloat3(Object o, int offset, float value) { + ObjectAccess.writeFloat(o, offset, value); + } + + @Snippet + public static double readDouble1(Object o, int offset) { + return ObjectAccess.readDouble(o, offset, ID); + } + + @Snippet + public static double readDouble2(Object o, int offset) { + return ObjectAccess.readDouble(o, Word.signed(offset), ID); + } + + @Snippet + public static double readDouble3(Object o, int offset) { + return ObjectAccess.readDouble(o, offset); + } + + @Snippet + public static void writeDouble1(Object o, int offset, double value) { + ObjectAccess.writeDouble(o, offset, value, ID); + } + + @Snippet + public static void writeDouble2(Object o, int offset, double value) { + ObjectAccess.writeDouble(o, Word.signed(offset), value, ID); + } + + @Snippet + public static void writeDouble3(Object o, int offset, double value) { + ObjectAccess.writeDouble(o, offset, value); + } + + @Snippet + public static Object readObject1(Object o, int offset) { + return ObjectAccess.readObject(o, offset, ID); + } + + @Snippet + public static Object readObject2(Object o, int offset) { + return ObjectAccess.readObject(o, Word.signed(offset), ID); + } + + @Snippet + public static Object readObject3(Object o, int offset) { + return ObjectAccess.readObject(o, offset); + } + + @Snippet + public static void writeObject1(Object o, int offset, Object value) { + ObjectAccess.writeObject(o, offset, value, ID); + } + + @Snippet + public static void writeObject2(Object o, int offset, Object value) { + ObjectAccess.writeObject(o, Word.signed(offset), value, ID); + } + + @Snippet + public static void writeObject3(Object o, int offset, Object value) { + ObjectAccess.writeObject(o, offset, value); + } +} diff -r 43bc62c78f77 -r 8db5e8c4f542 graal/com.oracle.graal.word/src/com/oracle/graal/word/ObjectAccess.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/ObjectAccess.java Thu Sep 26 15:53:21 2013 -0700 @@ -0,0 +1,936 @@ +/* + * 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.word; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.word.Word.Opcode; +import com.oracle.graal.word.Word.Operation; + +/** + * Low-level memory access for Objects. Similarly to the readXxx and writeXxx methods defined for + * {@link Pointer}, these methods access the raw memory without any null checks, read- or write + * barriers. + */ +public final class ObjectAccess { + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native byte readByte(Object object, WordBase offset, LocationIdentity locationIdentity); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native char readChar(Object object, WordBase offset, LocationIdentity locationIdentity); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native short readShort(Object object, WordBase offset, LocationIdentity locationIdentity); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native int readInt(Object object, WordBase offset, LocationIdentity locationIdentity); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native long readLong(Object object, WordBase offset, LocationIdentity locationIdentity); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native float readFloat(Object object, WordBase offset, LocationIdentity locationIdentity); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native double readDouble(Object object, WordBase offset, LocationIdentity locationIdentity); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native Word readWord(Object object, WordBase offset, LocationIdentity locationIdentity); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native Object readObject(Object object, WordBase offset, LocationIdentity locationIdentity); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native byte readByte(Object object, int offset, LocationIdentity locationIdentity); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native char readChar(Object object, int offset, LocationIdentity locationIdentity); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native short readShort(Object object, int offset, LocationIdentity locationIdentity); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native int readInt(Object object, int offset, LocationIdentity locationIdentity); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native long readLong(Object object, int offset, LocationIdentity locationIdentity); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native float readFloat(Object object, int offset, LocationIdentity locationIdentity); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native double readDouble(Object object, int offset, LocationIdentity locationIdentity); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native Word readWord(Object object, int offset, LocationIdentity locationIdentity); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native Object readObject(Object object, int offset, LocationIdentity locationIdentity); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeByte(Object object, WordBase offset, byte val, LocationIdentity locationIdentity); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeChar(Object object, WordBase offset, char val, LocationIdentity locationIdentity); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeShort(Object object, WordBase offset, short val, LocationIdentity locationIdentity); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeInt(Object object, WordBase offset, int val, LocationIdentity locationIdentity); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeLong(Object object, WordBase offset, long val, LocationIdentity locationIdentity); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeFloat(Object object, WordBase offset, float val, LocationIdentity locationIdentity); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeDouble(Object object, WordBase offset, double val, LocationIdentity locationIdentity); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeWord(Object object, WordBase offset, WordBase val, LocationIdentity locationIdentity); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeObject(Object object, WordBase offset, Object val, LocationIdentity locationIdentity); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeByte(Object object, int offset, byte val, LocationIdentity locationIdentity); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeChar(Object object, int offset, char val, LocationIdentity locationIdentity); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeShort(Object object, int offset, short val, LocationIdentity locationIdentity); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeInt(Object object, int offset, int val, LocationIdentity locationIdentity); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeLong(Object object, int offset, long val, LocationIdentity locationIdentity); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeFloat(Object object, int offset, float val, LocationIdentity locationIdentity); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeDouble(Object object, int offset, double val, LocationIdentity locationIdentity); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeWord(Object object, int offset, WordBase val, LocationIdentity locationIdentity); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeObject(Object object, int offset, Object val, LocationIdentity locationIdentity); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native byte readByte(Object object, WordBase offset); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native char readChar(Object object, WordBase offset); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native short readShort(Object object, WordBase offset); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native int readInt(Object object, WordBase offset); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native long readLong(Object object, WordBase offset); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native float readFloat(Object object, WordBase offset); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native double readDouble(Object object, WordBase offset); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native Word readWord(Object object, WordBase offset); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native Object readObject(Object object, WordBase offset); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native byte readByte(Object object, int offset); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native char readChar(Object object, int offset); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native short readShort(Object object, int offset); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native int readInt(Object object, int offset); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native long readLong(Object object, int offset); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native float readFloat(Object object, int offset); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native double readDouble(Object object, int offset); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native Word readWord(Object object, int offset); + + /** + * Reads the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @return the result of the memory access + */ + @Operation(opcode = Opcode.READ) + public static native Object readObject(Object object, int offset); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeByte(Object object, WordBase offset, byte val); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeChar(Object object, WordBase offset, char val); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeShort(Object object, WordBase offset, short val); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeInt(Object object, WordBase offset, int val); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeLong(Object object, WordBase offset, long val); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeFloat(Object object, WordBase offset, float val); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeDouble(Object object, WordBase offset, double val); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeWord(Object object, WordBase offset, WordBase val); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeObject(Object object, WordBase offset, Object val); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeByte(Object object, int offset, byte val); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeChar(Object object, int offset, char val); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeShort(Object object, int offset, short val); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeInt(Object object, int offset, int val); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeLong(Object object, int offset, long val); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeFloat(Object object, int offset, float val); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeDouble(Object object, int offset, double val); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeWord(Object object, int offset, WordBase val); + + /** + * Writes the memory at address {@code (object + offset)}. The offset is in bytes. + * + * @param object the base object for the memory access + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + @Operation(opcode = Opcode.WRITE) + public static native void writeObject(Object object, int offset, Object val); +} diff -r 43bc62c78f77 -r 8db5e8c4f542 graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Thu Sep 26 22:45:25 2013 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Thu Sep 26 15:53:21 2013 -0700 @@ -50,6 +50,7 @@ protected final MetaAccessProvider metaAccess; protected final ResolvedJavaType wordBaseType; protected final ResolvedJavaType wordImplType; + protected final ResolvedJavaType objectAccessType; protected final Kind wordKind; public WordTypeRewriterPhase(MetaAccessProvider metaAccess, Kind wordKind) { @@ -57,6 +58,7 @@ this.wordKind = wordKind; this.wordBaseType = metaAccess.lookupJavaType(WordBase.class); this.wordImplType = metaAccess.lookupJavaType(Word.class); + this.objectAccessType = metaAccess.lookupJavaType(ObjectAccess.class); } @Override @@ -191,8 +193,11 @@ */ protected void rewriteInvoke(StructuredGraph graph, MethodCallTargetNode callTargetNode) { ResolvedJavaMethod targetMethod = callTargetNode.targetMethod(); - if (!wordBaseType.isAssignableFrom(targetMethod.getDeclaringClass())) { - /* Not a method defined on WordBase or a subclass / subinterface, so nothing to rewrite. */ + if (!wordBaseType.isAssignableFrom(targetMethod.getDeclaringClass()) && !objectAccessType.equals(targetMethod.getDeclaringClass())) { + /* + * Not a method defined on WordBase or a subclass / subinterface, and not on + * ObjectAccess, so nothing to rewrite. + */ return; } @@ -252,7 +257,7 @@ case WRITE: case INITIALIZE: { assert arguments.size() == 3 || arguments.size() == 4; - Kind writeKind = asKind(targetMethod.getSignature().getParameterType(1, targetMethod.getDeclaringClass())); + Kind writeKind = asKind(targetMethod.getSignature().getParameterType(Modifier.isStatic(targetMethod.getModifiers()) ? 2 : 1, targetMethod.getDeclaringClass())); LocationNode location; if (arguments.size() == 3) { location = makeLocation(graph, arguments.get(1), writeKind, LocationIdentity.ANY_LOCATION);