# HG changeset patch # User Lukas Stadler # Date 1362049679 -3600 # Node ID c8f2002d219454b8c3b11fdc5e86392eb99a23c2 # Parent f19c4d447e733a0e9b2af7f6b86d7b685fd1e37f reintroduce default Word read/write operations, more tests diff -r f19c4d447e73 -r c8f2002d2194 graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/PointerTest.java --- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/PointerTest.java Thu Feb 28 11:50:06 2013 +0100 +++ b/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/PointerTest.java Thu Feb 28 12:07:59 2013 +0100 @@ -26,8 +26,6 @@ import org.junit.*; -import sun.security.action.*; - import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; @@ -76,6 +74,13 @@ } @Test + public void test_read3() { + for (Kind kind : KINDS) { + assertRead(parse("read" + kind.name() + "3"), kind, false, LocationNode.UNKNOWN_LOCATION); + } + } + + @Test public void test_write1() { for (Kind kind : KINDS) { assertWrite(parse("write" + kind.name() + "1"), kind, false, ID); @@ -89,6 +94,13 @@ } } + @Test + public void test_write3() { + for (Kind kind : KINDS) { + assertWrite(parse("write" + kind.name() + "3"), kind, false, LocationNode.ANY_LOCATION); + } + } + private void assertRead(StructuredGraph graph, Kind kind, boolean indexConvert, Object locationIdentity) { ReadNode read = (ReadNode) graph.start().next(); Assert.assertEquals(kind.getStackKind(), read.kind()); @@ -155,6 +167,11 @@ } @Snippet + public static byte readByte3(Object o, int offset) { + return Word.fromObject(o).readByte(offset); + } + + @Snippet public static void writeByte1(Object o, int offset, byte value) { Word.fromObject(o).writeByte(offset, value, ID); } @@ -165,6 +182,11 @@ } @Snippet + public static void writeByte3(Object o, int offset, byte value) { + Word.fromObject(o).writeByte(offset, value); + } + + @Snippet public static char readChar1(Object o, int offset) { return Word.fromObject(o).readChar(offset, ID); } @@ -175,6 +197,11 @@ } @Snippet + public static char readChar3(Object o, int offset) { + return Word.fromObject(o).readChar(offset); + } + + @Snippet public static void writeChar1(Object o, int offset, char value) { Word.fromObject(o).writeChar(offset, value, ID); } @@ -185,6 +212,11 @@ } @Snippet + public static void writeChar3(Object o, int offset, char value) { + Word.fromObject(o).writeChar(offset, value); + } + + @Snippet public static short readShort1(Object o, int offset) { return Word.fromObject(o).readShort(offset, ID); } @@ -195,6 +227,11 @@ } @Snippet + public static short readShort3(Object o, int offset) { + return Word.fromObject(o).readShort(offset); + } + + @Snippet public static void writeShort1(Object o, int offset, short value) { Word.fromObject(o).writeShort(offset, value, ID); } @@ -205,6 +242,11 @@ } @Snippet + public static void writeShort3(Object o, int offset, short value) { + Word.fromObject(o).writeShort(offset, value); + } + + @Snippet public static int readInt1(Object o, int offset) { return Word.fromObject(o).readInt(offset, ID); } @@ -215,6 +257,11 @@ } @Snippet + public static int readInt3(Object o, int offset) { + return Word.fromObject(o).readInt(offset); + } + + @Snippet public static void writeInt1(Object o, int offset, int value) { Word.fromObject(o).writeInt(offset, value, ID); } @@ -225,6 +272,11 @@ } @Snippet + public static void writeInt3(Object o, int offset, int value) { + Word.fromObject(o).writeInt(offset, value); + } + + @Snippet public static long readLong1(Object o, int offset) { return Word.fromObject(o).readLong(offset, ID); } @@ -235,6 +287,11 @@ } @Snippet + public static long readLong3(Object o, int offset) { + return Word.fromObject(o).readLong(offset); + } + + @Snippet public static void writeLong1(Object o, int offset, long value) { Word.fromObject(o).writeLong(offset, value, ID); } @@ -245,6 +302,11 @@ } @Snippet + public static void writeLong3(Object o, int offset, long value) { + Word.fromObject(o).writeLong(offset, value); + } + + @Snippet public static float readFloat1(Object o, int offset) { return Word.fromObject(o).readFloat(offset, ID); } @@ -255,6 +317,11 @@ } @Snippet + public static float readFloat3(Object o, int offset) { + return Word.fromObject(o).readFloat(offset); + } + + @Snippet public static void writeFloat1(Object o, int offset, float value) { Word.fromObject(o).writeFloat(offset, value, ID); } @@ -265,6 +332,11 @@ } @Snippet + public static void writeFloat3(Object o, int offset, float value) { + Word.fromObject(o).writeFloat(offset, value); + } + + @Snippet public static double readDouble1(Object o, int offset) { return Word.fromObject(o).readDouble(offset, ID); } @@ -275,6 +347,11 @@ } @Snippet + public static double readDouble3(Object o, int offset) { + return Word.fromObject(o).readDouble(offset); + } + + @Snippet public static void writeDouble1(Object o, int offset, double value) { Word.fromObject(o).writeDouble(offset, value, ID); } @@ -285,6 +362,11 @@ } @Snippet + public static void writeDouble3(Object o, int offset, double value) { + Word.fromObject(o).writeDouble(offset, value); + } + + @Snippet public static Object readObject1(Object o, int offset) { return Word.fromObject(o).readObject(offset, ID); } @@ -295,6 +377,11 @@ } @Snippet + public static Object readObject3(Object o, int offset) { + return Word.fromObject(o).readObject(offset); + } + + @Snippet public static void writeObject1(Object o, int offset, Object value) { Word.fromObject(o).writeObject(offset, value, ID); } @@ -304,4 +391,9 @@ Word.fromObject(o).writeObject(Word.signed(offset), value, ID); } + @Snippet + public static void writeObject3(Object o, int offset, Object value) { + Word.fromObject(o).writeObject(offset, value); + } + } diff -r f19c4d447e73 -r c8f2002d2194 graal/com.oracle.graal.word/src/com/oracle/graal/word/Pointer.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Pointer.java Thu Feb 28 11:50:06 2013 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Pointer.java Thu Feb 28 12:07:59 2013 +0100 @@ -467,6 +467,402 @@ */ void writeObject(int offset, Object val, Object locationIdentity); + /** + * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in + * bytes. + *

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + void writeObject(WordBase offset, Object val); + + /** + * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in + * bytes. + * + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + void writeByte(int offset, byte val); + + /** + * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in + * bytes. + * + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + void writeChar(int offset, char val); + + /** + * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in + * bytes. + * + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + void writeShort(int offset, short val); + + /** + * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in + * bytes. + * + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + void writeInt(int offset, int val); + + /** + * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in + * bytes. + * + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + void writeLong(int offset, long val); + + /** + * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in + * bytes. + * + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + void writeFloat(int offset, float val); + + /** + * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in + * bytes. + * + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + void writeDouble(int offset, double val); + + /** + * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in + * bytes. + * + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + void writeWord(int offset, WordBase val); + + /** + * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in + * bytes. + * + * @param offset the signed offset for the memory access + * @param val the value to be written to memory + */ + void writeObject(int offset, Object val); + // Math functions that are defined in Unsigned, but known to preserve the // pointer-characteristics. // It is therefore safe that they return a static type of Pointer instead of Unsigned. diff -r f19c4d447e73 -r c8f2002d2194 graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java Thu Feb 28 11:50:06 2013 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java Thu Feb 28 12:07:59 2013 +0100 @@ -808,6 +808,218 @@ } @Override + @Operation(opcode = Opcode.READ) + public byte readByte(WordBase offset) { + return unsafe.getByte(add((Word) offset).unbox()); + } + + @Override + @Operation(opcode = Opcode.READ) + public char readChar(WordBase offset) { + return unsafe.getChar(add((Word) offset).unbox()); + } + + @Override + @Operation(opcode = Opcode.READ) + public short readShort(WordBase offset) { + return unsafe.getShort(add((Word) offset).unbox()); + } + + @Override + @Operation(opcode = Opcode.READ) + public int readInt(WordBase offset) { + return unsafe.getInt(add((Word) offset).unbox()); + } + + @Override + @Operation(opcode = Opcode.READ) + public long readLong(WordBase offset) { + return unsafe.getLong(add((Word) offset).unbox()); + } + + @Override + @Operation(opcode = Opcode.READ) + public float readFloat(WordBase offset) { + return unsafe.getFloat(add((Word) offset).unbox()); + } + + @Override + @Operation(opcode = Opcode.READ) + public double readDouble(WordBase offset) { + return unsafe.getDouble(add((Word) offset).unbox()); + } + + @Override + @Operation(opcode = Opcode.READ) + public Word readWord(WordBase offset) { + return box(unsafe.getAddress(add((Word) offset).unbox())); + } + + @Override + @Operation(opcode = Opcode.READ) + public native Object readObject(WordBase offset); + + @Override + @Operation(opcode = Opcode.READ) + public byte readByte(int offset) { + return readByte(signed(offset)); + } + + @Override + @Operation(opcode = Opcode.READ) + public char readChar(int offset) { + return readChar(signed(offset)); + } + + @Override + @Operation(opcode = Opcode.READ) + public short readShort(int offset) { + return readShort(signed(offset)); + } + + @Override + @Operation(opcode = Opcode.READ) + public int readInt(int offset) { + return readInt(signed(offset)); + } + + @Override + @Operation(opcode = Opcode.READ) + public long readLong(int offset) { + return readLong(signed(offset)); + } + + @Override + @Operation(opcode = Opcode.READ) + public float readFloat(int offset) { + return readFloat(signed(offset)); + } + + @Override + @Operation(opcode = Opcode.READ) + public double readDouble(int offset) { + return readDouble(signed(offset)); + } + + @Override + @Operation(opcode = Opcode.READ) + public Word readWord(int offset) { + return readWord(signed(offset)); + } + + @Override + @Operation(opcode = Opcode.READ) + public Object readObject(int offset) { + return readObject(signed(offset)); + } + + @Override + @Operation(opcode = Opcode.WRITE) + public void writeByte(WordBase offset, byte val) { + unsafe.putByte(add((Word) offset).unbox(), val); + } + + @Override + @Operation(opcode = Opcode.WRITE) + public void writeChar(WordBase offset, char val) { + unsafe.putChar(add((Word) offset).unbox(), val); + } + + @Override + @Operation(opcode = Opcode.WRITE) + public void writeShort(WordBase offset, short val) { + unsafe.putShort(add((Word) offset).unbox(), val); + } + + @Override + @Operation(opcode = Opcode.WRITE) + public void writeInt(WordBase offset, int val) { + unsafe.putInt(add((Word) offset).unbox(), val); + } + + @Override + @Operation(opcode = Opcode.WRITE) + public void writeLong(WordBase offset, long val) { + unsafe.putLong(add((Word) offset).unbox(), val); + } + + @Override + @Operation(opcode = Opcode.WRITE) + public void writeFloat(WordBase offset, float val) { + unsafe.putFloat(add((Word) offset).unbox(), val); + } + + @Override + @Operation(opcode = Opcode.WRITE) + public void writeDouble(WordBase offset, double val) { + unsafe.putDouble(add((Word) offset).unbox(), val); + } + + @Override + @Operation(opcode = Opcode.WRITE) + public void writeWord(WordBase offset, WordBase val) { + unsafe.putAddress(add((Word) offset).unbox(), ((Word) val).unbox()); + } + + @Override + @Operation(opcode = Opcode.WRITE) + public native void writeObject(WordBase offset, Object val); + + @Override + @Operation(opcode = Opcode.WRITE) + public void writeByte(int offset, byte val) { + writeByte(signed(offset), val); + } + + @Override + @Operation(opcode = Opcode.WRITE) + public void writeChar(int offset, char val) { + writeChar(signed(offset), val); + } + + @Override + @Operation(opcode = Opcode.WRITE) + public void writeShort(int offset, short val) { + writeShort(signed(offset), val); + } + + @Override + @Operation(opcode = Opcode.WRITE) + public void writeInt(int offset, int val) { + writeInt(signed(offset), val); + } + + @Override + @Operation(opcode = Opcode.WRITE) + public void writeLong(int offset, long val) { + writeLong(signed(offset), val); + } + + @Override + @Operation(opcode = Opcode.WRITE) + public void writeFloat(int offset, float val) { + writeFloat(signed(offset), val); + } + + @Override + @Operation(opcode = Opcode.WRITE) + public void writeDouble(int offset, double val) { + writeDouble(signed(offset), val); + } + + @Override + @Operation(opcode = Opcode.WRITE) + public void writeWord(int offset, WordBase val) { + writeWord(signed(offset), val); + } + + @Override + @Operation(opcode = Opcode.WRITE) + public void writeObject(int offset, Object val) { + writeObject(signed(offset), val); + } + + @Override public final boolean equals(Object obj) { throw GraalInternalError.shouldNotReachHere("equals must not be called on words"); } diff -r f19c4d447e73 -r c8f2002d2194 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 Feb 28 11:50:06 2013 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Thu Feb 28 12:07:59 2013 +0100 @@ -138,15 +138,17 @@ break; case READ: - assert arguments.size() == 3; + assert arguments.size() == 2 || arguments.size() == 3; Kind readKind = asKind(callTargetNode.returnType()); - replace(invoke, readOp(graph, arguments.get(0), arguments.get(1), invoke, readKind, arguments.get(2).asConstant().asObject())); + Object readLocation = arguments.size() == 2 ? LocationNode.UNKNOWN_LOCATION : arguments.get(2).asConstant().asObject(); + replace(invoke, readOp(graph, arguments.get(0), arguments.get(1), invoke, readKind, readLocation)); break; case WRITE: - assert arguments.size() == 4; + assert arguments.size() == 3 || arguments.size() == 4; Kind writeKind = asKind(targetMethod.getSignature().getParameterType(1, targetMethod.getDeclaringClass())); - replace(invoke, writeOp(graph, arguments.get(0), arguments.get(1), arguments.get(2), invoke, writeKind, arguments.get(3).asConstant().asObject())); + Object writeLocation = arguments.size() == 3 ? LocationNode.ANY_LOCATION : arguments.get(3).asConstant().asObject(); + replace(invoke, writeOp(graph, arguments.get(0), arguments.get(1), arguments.get(2), invoke, writeKind, writeLocation)); break; case ZERO: