/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.vmmagic.unboxed; import org.vmmagic.pragma.*; import org.jikesrvm.VM; /** * The offset type is used by the runtime system and collector to denote * the directed distance between two machine addresses. * We use a separate type instead of the Java int type for coding clarity. * machine-portability (it can map to 32 bit and 64 bit integral types), * and access to unsigned operations (Java does not have unsigned int types). * <p> * For efficiency and to avoid meta-circularity, the Offset class is intercepted like * magic and converted into the base type so no Offset object is created run-time. * * @see Address Word */ @Uninterruptible public final class Offset extends ArchitecturalWord { Offset(int value) { super(value, false); } Offset(int value, boolean zeroExtend) { super(value, zeroExtend); } Offset(long value) { super(value); } /* Compensate for some java compilers helpfully defining this synthetically */ @Interruptible public String toString() { return super.toString(); } public boolean equals(Object o) { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); return (o instanceof Offset) && ((Offset) o).value == value; } @UninterruptibleNoWarn public static Offset fromIntSignExtend(int address) { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); return new Offset(address); } @UninterruptibleNoWarn public static Offset fromIntZeroExtend(int address) { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); return new Offset(address, true); } @UninterruptibleNoWarn public static Offset fromLong(long offset) { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); return new Offset(offset); } @UninterruptibleNoWarn public static Offset zero() { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); return new Offset(0); } @UninterruptibleNoWarn public static Offset max() { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); return fromIntSignExtend(-1); } public int toInt() { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); return (int) value; } public long toLong() { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); if (VM.BuildFor64Addr) { return value; } else { return 0x00000000ffffffffL & ((long) value); } } @UninterruptibleNoWarn public Word toWord() { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); return new Word(value); } @UninterruptibleNoWarn public Offset plus(int byteSize) { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); return new Offset(value + byteSize); } @UninterruptibleNoWarn public Offset plus(Offset off2) { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); return new Offset(value + off2.value); } @UninterruptibleNoWarn public Offset minus(int byteSize) { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); return new Offset(value - byteSize); } @UninterruptibleNoWarn public Offset minus(Offset off2) { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); return new Offset(value - off2.value); } public boolean EQ(Offset off2) { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); return value == off2.value; } public boolean NE(Offset off2) { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); return value != off2.value; } public boolean sLT(Offset off2) { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); return value < off2.value; } public boolean sLE(Offset off2) { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); return value <= off2.value; } public boolean sGT(Offset off2) { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); return value > off2.value; } public boolean sGE(Offset off2) { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); return value >= off2.value; } public boolean isZero() { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); return EQ(zero()); } public boolean isMax() { if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED); return EQ(max()); } }