/* * Copyright (c) 2007, 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.sun.max.vm.reference.hosted; import com.sun.max.*; import com.sun.max.annotate.*; import com.sun.max.program.*; import com.sun.max.unsafe.*; import com.sun.max.vm.*; import com.sun.max.vm.actor.holder.*; import com.sun.max.vm.actor.member.*; import com.sun.max.vm.hosted.*; import com.sun.max.vm.layout.*; import com.sun.max.vm.reference.*; import com.sun.max.vm.runtime.*; import com.sun.max.vm.type.*; import com.sun.max.vm.value.*; /** * A reference scheme for use when executing in {@linkplain MaxineVM#isHosted() hosted} mode. */ public final class HostedReferenceScheme extends AbstractVMScheme implements ReferenceScheme { public boolean isConstant() { return false; } public Reference fromJava(Object object) { return new HostedReference(object); } public Object toJava(Reference ref) { final HostedReference prototypeReference = (HostedReference) ref; return prototypeReference.getObject(); } public Reference fromReference(Reference reference) { return fromJava(reference.toJava()); } public Reference fromOrigin(Pointer origin) { throw FatalError.unimplemented(); } public Reference updateReference(Reference ref, Pointer origin) { throw FatalError.unimplemented(); } @INLINE public Reference zero() { return null; } public boolean isZero(Reference ref) { return toJava(ref) == null; } @INLINE public boolean isAllOnes(Reference ref) { throw FatalError.unimplemented(); } public boolean equals(Reference ref1, Reference ref2) { return ref1.equals(ref2); } public boolean isMarked(Reference ref) { throw FatalError.unimplemented(); } public boolean isTagged(Reference ref) { throw FatalError.unimplemented(); } public Reference marked(Reference ref) { throw FatalError.unimplemented(); } public Reference unmarked(Reference ref) { throw FatalError.unimplemented(); } public Pointer toOrigin(Reference ref) { throw FatalError.unimplemented(); } private void setValue(Reference ref, int displacement, int index, Object wordOrBoxedJavaValue) { final Object object = toJava(ref); final HostedObjectMirror mirror = new HostedObjectMirror(object); final SpecificLayout specificLayout = mirror.classActor().dynamicHub().specificLayout; ProgramError.check(displacement == ((ArrayLayout) specificLayout).getElementOffsetFromOrigin(0).toInt(), "invalid array displacement"); final Value value = wordOrBoxedJavaValue instanceof Word ? WordValue.from((Word) wordOrBoxedJavaValue) : Value.fromBoxedJavaValue(wordOrBoxedJavaValue); mirror.writeElement(value.kind(), index, value); } private <T> T getValue(Reference ref, Class<T> type, int displacement, int index) { final Object object = toJava(ref); final HostedObjectMirror mirror = new HostedObjectMirror(object); final SpecificLayout specificLayout = mirror.classActor().dynamicHub().specificLayout; ProgramError.check(displacement == ((ArrayLayout) specificLayout).getElementOffsetFromOrigin(0).toInt(), "invalid array displacement"); final Kind kind = Kind.fromJava(type); final Class<T> castType = null; return Utils.cast(castType, mirror.readElement(kind, index).asBoxedJavaValue()); } private void writeValue(Reference ref, int offset, Object wordOrBoxedJavaValue) { final Object object = toJava(ref); if (object instanceof StaticTuple) { final StaticTuple staticTuple = (StaticTuple) object; final FieldActor fieldActor = staticTuple.findStaticFieldActor(offset); final Class javaClass = staticTuple.classActor().toJava(); try { WithoutAccessCheck.setStaticField(javaClass, fieldActor.name.toString(), wordOrBoxedJavaValue); } catch (Throwable throwable) { throw ProgramError.unexpected("could not write field: " + fieldActor, throwable); } } else { final HostedObjectMirror mirror = new HostedObjectMirror(object); final SpecificLayout specificLayout = mirror.classActor().dynamicHub().specificLayout; final Value value = wordOrBoxedJavaValue instanceof Word ? WordValue.from((Word) wordOrBoxedJavaValue) : Value.fromBoxedJavaValue(wordOrBoxedJavaValue); specificLayout.writeValue(value.kind(), mirror, offset, value); return; } } private <T> T readValue(Reference ref, Class<T> type, int offset) { final Class<T> castType = null; final Object object = toJava(ref); if (object instanceof StaticTuple) { final StaticTuple staticTuple = (StaticTuple) object; final FieldActor fieldActor = staticTuple.findStaticFieldActor(offset); try { return Utils.cast(castType, WithoutAccessCheck.getStaticField(staticTuple.classActor().toJava(), fieldActor.name.toString())); } catch (Throwable throwable) { throw ProgramError.unexpected("could not read field: " + fieldActor, throwable); } } final HostedObjectMirror mirror = new HostedObjectMirror(object); final ClassActor classActor = mirror.classActor(); final SpecificLayout specificLayout = classActor.dynamicHub().specificLayout; final Kind kind = Kind.fromJava(type); final Value value = specificLayout.readValue(kind, mirror, offset); return Utils.cast(castType, value.asBoxedJavaValue()); } public byte readByte(Reference ref, Offset offset) { return readByte(ref, offset.toInt()); } public byte readByte(Reference ref, int offset) { return readValue(ref, byte.class, offset).byteValue(); } public byte getByte(Reference ref, int displacement, int index) { return getValue(ref, byte.class, displacement, index); } public boolean readBoolean(Reference ref, Offset offset) { return readBoolean(ref, offset.toInt()); } public boolean readBoolean(Reference ref, int offset) { return readValue(ref, boolean.class, offset).booleanValue(); } public boolean getBoolean(Reference ref, int displacement, int index) { return getValue(ref, boolean.class, displacement, index); } public short readShort(Reference ref, Offset offset) { return readShort(ref, offset.toInt()); } public short readShort(Reference ref, int offset) { return readValue(ref, short.class, offset).shortValue(); } public short getShort(Reference ref, int displacement, int index) { return getValue(ref, short.class, displacement, index); } public char readChar(Reference ref, Offset offset) { return readChar(ref, offset.toInt()); } public char readChar(Reference ref, int offset) { return readValue(ref, char.class, offset).charValue(); } public char getChar(Reference ref, int displacement, int index) { return getValue(ref, char.class, displacement, index); } public int readInt(Reference ref, Offset offset) { return readInt(ref, offset.toInt()); } public int readInt(Reference ref, int offset) { return readValue(ref, int.class, offset).intValue(); } public int getInt(Reference ref, int displacement, int index) { return getValue(ref, int.class, displacement, index); } public float readFloat(Reference ref, Offset offset) { return readFloat(ref, offset.toInt()); } public float readFloat(Reference ref, int offset) { return readValue(ref, float.class, offset).floatValue(); } public float getFloat(Reference ref, int displacement, int index) { return getValue(ref, float.class, displacement, index); } public long readLong(Reference ref, Offset offset) { return readLong(ref, offset.toInt()); } public long readLong(Reference ref, int offset) { return readValue(ref, long.class, offset).longValue(); } public long getLong(Reference ref, int displacement, int index) { return getValue(ref, long.class, displacement, index); } public double readDouble(Reference ref, Offset offset) { return readDouble(ref, offset.toInt()); } public double readDouble(Reference ref, int offset) { return readValue(ref, double.class, offset).doubleValue(); } public double getDouble(Reference ref, int displacement, int index) { return getValue(ref, double.class, displacement, index); } public Word readWord(Reference ref, Offset offset) { return readWord(ref, offset.toInt()); } public Word readWord(Reference ref, int offset) { return readValue(ref, Word.class, offset); } public Word getWord(Reference ref, int displacement, int index) { return getValue(ref, Word.class, displacement, index); } public Reference readReference(Reference ref, Offset offset) { return readReference(ref, offset.toInt()); } public Reference readReference(Reference ref, int offset) { return fromJava(readValue(ref, Object.class, offset)); } public Reference getReference(Reference ref, int displacement, int index) { return fromJava(getValue(ref, Object.class, displacement, index)); } public void writeByte(Reference ref, Offset offset, byte value) { writeByte(ref, offset.toInt(), value); } public void writeByte(Reference ref, int offset, byte value) { writeValue(ref, offset, Byte.valueOf(value)); } public void setByte(Reference ref, int displacement, int index, byte value) { setValue(ref, displacement, index, Byte.valueOf(value)); } public void writeBoolean(Reference ref, Offset offset, boolean value) { writeBoolean(ref, offset.toInt(), value); } public void writeBoolean(Reference ref, int offset, boolean value) { writeValue(ref, offset, Boolean.valueOf(value)); } public void setBoolean(Reference ref, int displacement, int index, boolean value) { setValue(ref, displacement, index, Boolean.valueOf(value)); } public void writeShort(Reference ref, Offset offset, short value) { writeShort(ref, offset.toInt(), value); } public void writeShort(Reference ref, int offset, short value) { writeValue(ref, offset, Short.valueOf(value)); } public void setShort(Reference ref, int displacement, int index, short value) { setValue(ref, displacement, index, Short.valueOf(value)); } public void writeChar(Reference ref, Offset offset, char value) { writeChar(ref, offset.toInt(), value); } public void writeChar(Reference ref, int offset, char value) { writeValue(ref, offset, Character.valueOf(value)); } public void setChar(Reference ref, int displacement, int index, char value) { setValue(ref, displacement, index, Character.valueOf(value)); } public void writeInt(Reference ref, Offset offset, int value) { writeInt(ref, offset.toInt(), value); } public void writeInt(Reference ref, int offset, int value) { writeValue(ref, offset, Integer.valueOf(value)); } public void setInt(Reference ref, int displacement, int index, int value) { setValue(ref, displacement, index, Integer.valueOf(value)); } public void writeFloat(Reference ref, Offset offset, float value) { writeFloat(ref, offset.toInt(), value); } public void writeFloat(Reference ref, int offset, float value) { writeValue(ref, offset, Float.valueOf(value)); } public void setFloat(Reference ref, int displacement, int index, float value) { setValue(ref, displacement, index, Float.valueOf(value)); } public void writeLong(Reference ref, Offset offset, long value) { writeLong(ref, offset.toInt(), value); } public void writeLong(Reference ref, int offset, long value) { writeValue(ref, offset, Long.valueOf(value)); } public void setLong(Reference ref, int displacement, int index, long value) { setValue(ref, displacement, index, Long.valueOf(value)); } public void writeDouble(Reference ref, Offset offset, double value) { writeDouble(ref, offset.toInt(), value); } public void writeDouble(Reference ref, int offset, double value) { writeValue(ref, offset, Double.valueOf(value)); } public void setDouble(Reference ref, int displacement, int index, double value) { setValue(ref, displacement, index, Double.valueOf(value)); } public void writeWord(Reference ref, Offset offset, Word value) { writeWord(ref, offset.toInt(), value); } public void writeWord(Reference ref, int offset, Word value) { writeValue(ref, offset, value); } public void setWord(Reference ref, int displacement, int index, Word value) { setValue(ref, displacement, index, value); } public void writeReference(Reference ref, Offset offset, Reference value) { writeReference(ref, offset.toInt(), value); } public void writeReference(Reference ref, int offset, Reference value) { writeValue(ref, offset, value.toJava()); } public void setReference(Reference ref, int displacement, int index, Reference value) { setValue(ref, displacement, index, value.toJava()); } public int compareAndSwapInt(Reference ref, Offset offset, int expectedValue, int newValue) { return toOrigin(ref).compareAndSwapInt(offset, expectedValue, newValue); } public int compareAndSwapInt(Reference ref, int offset, int expectedValue, int newValue) { return toOrigin(ref).compareAndSwapInt(offset, expectedValue, newValue); } public Word compareAndSwapWord(Reference ref, Offset offset, Word expectedValue, Word newValue) { throw FatalError.unimplemented(); } public Word compareAndSwapWord(Reference ref, int offset, Word expectedValue, Word newValue) { throw FatalError.unimplemented(); } public Reference compareAndSwapReference(Reference ref, Offset offset, Reference expectedValue, Reference newValue) { throw FatalError.unimplemented(); } public Reference compareAndSwapReference(Reference ref, int offset, Reference expectedValue, Reference newValue) { throw FatalError.unimplemented(); } public void copyElements(int displacement, Reference src, int srcIndex, Object dst, int dstIndex, int length) { throw FatalError.unimplemented(); } @Override public byte[] asBytes(Pointer origin) { throw FatalError.unimplemented(); } @Override public byte[] nullAsBytes() { throw FatalError.unimplemented(); } }