Home | History | Annotate | Download | only in platform
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 // BEGIN android-note
     19 // address length was changed from long to int for performance reasons.
     20 // END android-note
     21 
     22 package org.apache.harmony.luni.platform;
     23 
     24 import java.nio.ByteOrder;
     25 
     26 /**
     27  * The platform address class is an unsafe virtualization of an OS memory block.
     28  */
     29 public class PlatformAddress implements Comparable {
     30     public static final int SIZEOF_JBYTE = 1;
     31     public static final int SIZEOF_JSHORT = 2;
     32     public static final int SIZEOF_JINT = 4;
     33     public static final int SIZEOF_JSIZE = 4;
     34     public static final int SIZEOF_JFLOAT = 4;
     35     public static final int SIZEOF_JLONG = 8;
     36     public static final int SIZEOF_JDOUBLE = 8;
     37 
     38     /**
     39      * This final field defines the sentinel for an unknown address value.
     40      */
     41     static final int UNKNOWN = -1;
     42 
     43     /**
     44      * NULL is the canonical address with address value zero.
     45      */
     46     public static final PlatformAddress NULL = new PlatformAddress(0, 0);
     47 
     48     /**
     49      * INVALID is the canonical address with an invalid value
     50      * (i.e. a non-address).
     51      */
     52     public static final PlatformAddress INVALID = new PlatformAddress(UNKNOWN, UNKNOWN);
     53 
     54     public static final RuntimeMemorySpy memorySpy = new RuntimeMemorySpy();
     55 
     56     final int osaddr;
     57 
     58     final long size;
     59 
     60     PlatformAddress(int address, long size) {
     61         super();
     62         osaddr = address;
     63         this.size = size;
     64     }
     65 
     66     /**
     67      * Sending auto free to an address means that, when this subsystem has
     68      * allocated the memory, it will automatically be freed when this object is
     69      * collected by the garbage collector if the memory has not already been
     70      * freed explicitly.
     71      *
     72      */
     73     public final void autoFree() {
     74         memorySpy.autoFree(this);
     75     }
     76 
     77     public PlatformAddress duplicate() {
     78         return PlatformAddressFactory.on(osaddr, size);
     79     }
     80 
     81     public PlatformAddress offsetBytes(int offset) {
     82         return PlatformAddressFactory.on(osaddr + offset, size - offset);
     83     }
     84 
     85     public final void moveTo(PlatformAddress dst, long numBytes) {
     86         OSMemory.memmove(dst.osaddr, osaddr, numBytes);
     87     }
     88 
     89     public final boolean equals(Object other) {
     90         return (other instanceof PlatformAddress)
     91                 && (((PlatformAddress) other).osaddr == osaddr);
     92     }
     93 
     94     public final int hashCode() {
     95         return (int) osaddr;
     96     }
     97 
     98     public final boolean isNULL() {
     99         return this == NULL;
    100     }
    101 
    102     public void free() {
    103         // Memory spys can veto the basic free if they determine the memory was
    104         // not allocated.
    105         if (memorySpy.free(this)) {
    106             OSMemory.free(osaddr);
    107         }
    108     }
    109 
    110     public final void setAddress(int offset, PlatformAddress address) {
    111         OSMemory.setAddress(osaddr + offset, address.osaddr);
    112     }
    113 
    114     public final PlatformAddress getAddress(int offset) {
    115         int addr = getInt(offset);
    116         return PlatformAddressFactory.on(addr);
    117     }
    118 
    119     public final void setByte(int offset, byte value) {
    120         memorySpy.rangeCheck(this, offset, SIZEOF_JBYTE);
    121         OSMemory.setByte(osaddr + offset, value);
    122     }
    123 
    124     public final void setByteArray(int offset, byte[] bytes, int bytesOffset,
    125             int length) {
    126         memorySpy.rangeCheck(this, offset, length * SIZEOF_JBYTE);
    127         OSMemory.setByteArray(osaddr + offset, bytes, bytesOffset, length);
    128     }
    129 
    130     // BEGIN android-added
    131     public final void setShortArray(int offset, short[] shorts,
    132             int shortsOffset, int length, boolean swap) {
    133         memorySpy.rangeCheck(this, offset, length * SIZEOF_JSHORT);
    134         OSMemory.setShortArray(osaddr + offset, shorts, shortsOffset, length,
    135             swap);
    136     }
    137 
    138     public final void setIntArray(int offset, int[] ints,
    139             int intsOffset, int length, boolean swap) {
    140         memorySpy.rangeCheck(this, offset, length * SIZEOF_JINT);
    141         OSMemory.setIntArray(osaddr + offset, ints, intsOffset, length, swap);
    142     }
    143 
    144     public final void setFloatArray(int offset, float[] floats,
    145             int floatsOffset, int length, boolean swap) {
    146         memorySpy.rangeCheck(this, offset, length * SIZEOF_JFLOAT);
    147         OSMemory.setFloatArray(
    148                 osaddr + offset, floats, floatsOffset, length, swap);
    149     }
    150     // END android-added
    151 
    152     public final byte getByte(int offset) {
    153         memorySpy.rangeCheck(this, offset, SIZEOF_JBYTE);
    154         return OSMemory.getByte(osaddr + offset);
    155     }
    156 
    157     public final void getByteArray(int offset, byte[] bytes, int bytesOffset,
    158             int length) {
    159         memorySpy.rangeCheck(this, offset, length * SIZEOF_JBYTE);
    160         OSMemory.getByteArray(osaddr + offset, bytes, bytesOffset, length);
    161     }
    162 
    163     public final void setShort(int offset, short value, ByteOrder order) {
    164         memorySpy.rangeCheck(this, offset, SIZEOF_JSHORT);
    165         OSMemory.setShort(osaddr + offset, value, order);
    166     }
    167 
    168     public final void setShort(int offset, short value) {
    169         memorySpy.rangeCheck(this, offset, SIZEOF_JSHORT);
    170         OSMemory.setShort(osaddr + offset, value);
    171     }
    172 
    173     public final short getShort(int offset, ByteOrder order) {
    174         memorySpy.rangeCheck(this, offset, SIZEOF_JSHORT);
    175         return OSMemory.getShort(osaddr + offset, order);
    176     }
    177 
    178     public final short getShort(int offset) {
    179         memorySpy.rangeCheck(this, offset, SIZEOF_JSHORT);
    180         return OSMemory.getShort(osaddr + offset);
    181     }
    182 
    183     public final void setInt(int offset, int value, ByteOrder order) {
    184         memorySpy.rangeCheck(this, offset, SIZEOF_JINT);
    185         OSMemory.setInt(osaddr + offset, value, order);
    186     }
    187 
    188     public final void setInt(int offset, int value) {
    189         memorySpy.rangeCheck(this, offset, SIZEOF_JINT);
    190         OSMemory.setInt(osaddr + offset, value);
    191     }
    192 
    193     public final int getInt(int offset, ByteOrder order) {
    194         memorySpy.rangeCheck(this, offset, SIZEOF_JINT);
    195         return OSMemory.getInt(osaddr + offset, order);
    196     }
    197 
    198     public final int getInt(int offset) {
    199         memorySpy.rangeCheck(this, offset, SIZEOF_JINT);
    200         return OSMemory.getInt(osaddr + offset);
    201     }
    202 
    203     public final void setLong(int offset, long value, ByteOrder order) {
    204         memorySpy.rangeCheck(this, offset, SIZEOF_JLONG);
    205         OSMemory.setLong(osaddr + offset, value, order);
    206     }
    207 
    208     public final void setLong(int offset, long value) {
    209         memorySpy.rangeCheck(this, offset, SIZEOF_JLONG);
    210         OSMemory.setLong(osaddr + offset, value);
    211     }
    212 
    213     public final long getLong(int offset, ByteOrder order) {
    214         memorySpy.rangeCheck(this, offset, SIZEOF_JLONG);
    215         return OSMemory.getLong(osaddr + offset, order);
    216     }
    217 
    218     public final long getLong(int offset) {
    219         memorySpy.rangeCheck(this, offset, SIZEOF_JLONG);
    220         return OSMemory.getLong(osaddr + offset);
    221     }
    222 
    223     public final void setFloat(int offset, float value, ByteOrder order) {
    224         memorySpy.rangeCheck(this, offset, SIZEOF_JFLOAT);
    225         OSMemory.setFloat(osaddr + offset, value, order);
    226     }
    227 
    228     public final void setFloat(int offset, float value) {
    229         memorySpy.rangeCheck(this, offset, SIZEOF_JFLOAT);
    230         OSMemory.setFloat(osaddr + offset, value);
    231     }
    232 
    233     public final float getFloat(int offset, ByteOrder order) {
    234         memorySpy.rangeCheck(this, offset, SIZEOF_JFLOAT);
    235         return OSMemory.getFloat(osaddr + offset, order);
    236     }
    237 
    238     public final float getFloat(int offset) {
    239         memorySpy.rangeCheck(this, offset, SIZEOF_JFLOAT);
    240         return OSMemory.getFloat(osaddr + offset);
    241     }
    242 
    243     public final void setDouble(int offset, double value, ByteOrder order) {
    244         memorySpy.rangeCheck(this, offset, SIZEOF_JDOUBLE);
    245         OSMemory.setDouble(osaddr + offset, value, order);
    246     }
    247 
    248     public final void setDouble(int offset, double value) {
    249         memorySpy.rangeCheck(this, offset, SIZEOF_JDOUBLE);
    250         OSMemory.setDouble(osaddr + offset, value);
    251     }
    252 
    253     public final double getDouble(int offset, ByteOrder order) {
    254         memorySpy.rangeCheck(this, offset, SIZEOF_JDOUBLE);
    255         return OSMemory.getDouble(osaddr + offset, order);
    256     }
    257 
    258     public final double getDouble(int offset) {
    259         memorySpy.rangeCheck(this, offset, SIZEOF_JDOUBLE);
    260         return OSMemory.getDouble(osaddr + offset);
    261     }
    262 
    263     // BEGIN android-added
    264     public final int toInt() {
    265         return osaddr;
    266     }
    267     // END android-added
    268 
    269     public final long toLong() {
    270         return osaddr;
    271     }
    272 
    273     public final String toString() {
    274         return "PlatformAddress[" + osaddr + "]";
    275     }
    276 
    277     public final long getSize() {
    278         return size;
    279     }
    280 
    281     public final int compareTo(Object other) {
    282         if (other == null) {
    283             throw new NullPointerException(); // per spec.
    284         }
    285         if (other instanceof PlatformAddress) {
    286             int otherPA = ((PlatformAddress) other).osaddr;
    287             if (osaddr == otherPA) {
    288                 return 0;
    289             }
    290             return osaddr < otherPA ? -1 : 1;
    291         }
    292 
    293         throw new ClassCastException(); // per spec.
    294     }
    295 }
    296