1 /*
   2  * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 package sun.jvm.hotspot.debugger.dummy;
  26 
  27 import sun.jvm.hotspot.debugger.*;
  28 
  29 /** For testing purposes */
  30 
  31 class DummyAddress implements Address {
  32   protected DummyDebugger debugger;
  33   protected long addr;
  34   private static final long badLong = 0xBAADBABEL;
  35   private static final double badDouble = 1.23456;
  36 
  37   DummyAddress(DummyDebugger debugger, long addr) {
  38     this.debugger = debugger;
  39     this.addr = addr;
  40   }
  41 
  42   //
  43   // Basic Java routines
  44   //
  45 
  46   public boolean equals(Object arg) {
  47     if (arg == null) {
  48       return false;
  49     }
  50 
  51     if (!(arg instanceof DummyAddress)) {
  52       return false;
  53     }
  54 
  55     return (addr == ((DummyAddress) arg).addr);
  56   }
  57 
  58   public int hashCode() {
  59     // FIXME: suggestions on a better hash code?
  60     return (int) addr;
  61   }
  62 
  63   public String toString() {
  64     return debugger.addressToString(this);
  65   }
  66 
  67   //
  68   // C/C++-related routines
  69   //
  70 
  71   public long getCIntegerAt(long offset, long numBytes, boolean isUnsigned) throws UnalignedAddressException, UnmappedAddressException {
  72     return badLong;
  73   }
  74 
  75   public Address getAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
  76     return new DummyAddress(debugger, badLong);
  77   }
  78 
  79   public Address getCompOopAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
  80     return new DummyAddress(debugger, badLong);
  81   }
  82 
  83   public Address getCompKlassAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
  84     return new DummyAddress(debugger, badLong);
  85   }
  86 
  87   //
  88   // Java-related routines
  89   //
  90 
  91   public boolean getJBooleanAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
  92     return false;
  93   }
  94 
  95   public byte getJByteAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
  96     return (byte) badLong;
  97   }
  98 
  99   public char getJCharAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
 100     return (char) badLong;
 101   }
 102 
 103   public double getJDoubleAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
 104     return badDouble;
 105   }
 106 
 107   public float getJFloatAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
 108     return (float) badDouble;
 109   }
 110 
 111   public int getJIntAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
 112     return (int) badLong;
 113   }
 114 
 115   public long getJLongAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
 116     return badLong;
 117   }
 118 
 119   public short getJShortAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
 120     return (short) badLong;
 121   }
 122 
 123   public OopHandle getOopHandleAt(long offset)
 124     throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
 125     return new DummyOopHandle(debugger, badLong);
 126   }
 127   public OopHandle getCompOopHandleAt(long offset)
 128     throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
 129     return new DummyOopHandle(debugger, badLong);
 130   }
 131 
 132   // Mutators -- not implemented
 133   public void setCIntegerAt(long offset, long numBytes, long value) {
 134     throw new DebuggerException("Unimplemented");
 135   }
 136   public void setAddressAt(long offset, Address value) {
 137     throw new DebuggerException("Unimplemented");
 138   }
 139   public void       setJBooleanAt      (long offset, boolean value)
 140     throws UnmappedAddressException, UnalignedAddressException {
 141     throw new DebuggerException("Unimplemented");
 142   }
 143   public void       setJByteAt         (long offset, byte value)
 144     throws UnmappedAddressException, UnalignedAddressException {
 145     throw new DebuggerException("Unimplemented");
 146   }
 147   public void       setJCharAt         (long offset, char value)
 148     throws UnmappedAddressException, UnalignedAddressException {
 149     throw new DebuggerException("Unimplemented");
 150   }
 151   public void       setJDoubleAt       (long offset, double value)
 152     throws UnmappedAddressException, UnalignedAddressException {
 153     throw new DebuggerException("Unimplemented");
 154   }
 155   public void       setJFloatAt        (long offset, float value)
 156     throws UnmappedAddressException, UnalignedAddressException {
 157     throw new DebuggerException("Unimplemented");
 158   }
 159   public void       setJIntAt          (long offset, int value)
 160     throws UnmappedAddressException, UnalignedAddressException {
 161     throw new DebuggerException("Unimplemented");
 162   }
 163   public void       setJLongAt         (long offset, long value)
 164     throws UnmappedAddressException, UnalignedAddressException {
 165     throw new DebuggerException("Unimplemented");
 166   }
 167   public void       setJShortAt        (long offset, short value)
 168     throws UnmappedAddressException, UnalignedAddressException {
 169     throw new DebuggerException("Unimplemented");
 170   }
 171   public void       setOopHandleAt     (long offset, OopHandle value)
 172     throws UnmappedAddressException, UnalignedAddressException {
 173     throw new DebuggerException("Unimplemented");
 174   }
 175 
 176   //
 177   // Arithmetic operations -- necessary evil.
 178   //
 179 
 180   public Address    addOffsetTo       (long offset) throws UnsupportedOperationException {
 181     long value = addr + offset;
 182     if (value == 0) {
 183       return null;
 184     }
 185     return new DummyAddress(debugger, value);
 186   }
 187 
 188   public OopHandle  addOffsetToAsOopHandle(long offset) throws UnsupportedOperationException {
 189     long value = addr + offset;
 190     if (value == 0) {
 191       return null;
 192     }
 193     return new DummyOopHandle(debugger, value);
 194   }
 195 
 196   /** (FIXME: any signed/unsigned issues? Should this work for
 197       OopHandles?) */
 198   public long       minus(Address arg) {
 199     if (arg == null) {
 200       return addr;
 201     }
 202     return addr - ((DummyAddress) arg).addr;
 203   }
 204 
 205   // Two's complement representation.
 206   // All negative numbers are larger than positive numbers.
 207   // Numbers with the same sign can be compared normally.
 208   // Test harness is below in main().
 209 
 210   public boolean    lessThan          (Address arg) {
 211     DummyAddress DummyArg = (DummyAddress) arg;
 212     if ((addr >= 0) && (DummyArg.addr < 0)) {
 213       return true;
 214     }
 215     if ((addr < 0) && (DummyArg.addr >= 0)) {
 216       return false;
 217     }
 218     return (addr < DummyArg.addr);
 219   }
 220 
 221   public boolean    lessThanOrEqual   (Address arg) {
 222     DummyAddress DummyArg = (DummyAddress) arg;
 223     if ((addr >= 0) && (DummyArg.addr < 0)) {
 224       return true;
 225     }
 226     if ((addr < 0) && (DummyArg.addr >= 0)) {
 227       return false;
 228     }
 229     return (addr <= DummyArg.addr);
 230   }
 231 
 232   public boolean    greaterThan       (Address arg) {
 233     DummyAddress DummyArg = (DummyAddress) arg;
 234     if ((addr >= 0) && (DummyArg.addr < 0)) {
 235       return false;
 236     }
 237     if ((addr < 0) && (DummyArg.addr >= 0)) {
 238       return true;
 239     }
 240     return (addr > DummyArg.addr);
 241   }
 242 
 243   public boolean    greaterThanOrEqual(Address arg) {
 244     DummyAddress DummyArg = (DummyAddress) arg;
 245     if ((addr >= 0) && (DummyArg.addr < 0)) {
 246       return false;
 247     }
 248     if ((addr < 0) && (DummyArg.addr >= 0)) {
 249       return true;
 250     }
 251     return (addr >= DummyArg.addr);
 252   }
 253 
 254   public Address    andWithMask(long mask) throws UnsupportedOperationException {
 255     long value = addr & mask;
 256     if (value == 0) {
 257       return null;
 258     }
 259     return new DummyAddress(debugger, value);
 260   }
 261 
 262   public Address    orWithMask(long mask) throws UnsupportedOperationException {
 263     long value = addr | mask;
 264     if (value == 0) {
 265       return null;
 266     }
 267     return new DummyAddress(debugger, value);
 268   }
 269 
 270   public Address    xorWithMask(long mask) throws UnsupportedOperationException {
 271     long value = addr ^ mask;
 272     if (value == 0) {
 273       return null;
 274     }
 275     return new DummyAddress(debugger, value);
 276   }
 277 
 278   //--------------------------------------------------------------------------------
 279   // Internals only below this point
 280   //
 281 
 282   long getValue() {
 283     return addr;
 284   }
 285 
 286   private static void check(boolean arg, String failMessage) {
 287     if (!arg) {
 288       System.err.println(failMessage + ": FAILED");
 289       System.exit(1);
 290     }
 291   }
 292 
 293   // Test harness
 294   public static void main(String[] args) {
 295     // p/n indicates whether the interior address is really positive
 296     // or negative. In unsigned terms, p1 < p2 < n1 < n2.
 297 
 298     DummyAddress p1 = new DummyAddress(null, 0x7FFFFFFFFFFFFFF0L);
 299     DummyAddress p2 = (DummyAddress) p1.addOffsetTo(10);
 300     DummyAddress n1 = (DummyAddress) p2.addOffsetTo(10);
 301     DummyAddress n2 = (DummyAddress) n1.addOffsetTo(10);
 302 
 303     // lessThan positive tests
 304     check(p1.lessThan(p2), "lessThan 1");
 305     check(p1.lessThan(n1), "lessThan 2");
 306     check(p1.lessThan(n2), "lessThan 3");
 307     check(p2.lessThan(n1), "lessThan 4");
 308     check(p2.lessThan(n2), "lessThan 5");
 309     check(n1.lessThan(n2), "lessThan 6");
 310 
 311     // lessThan negative tests
 312     check(!p1.lessThan(p1), "lessThan 7");
 313     check(!p2.lessThan(p2), "lessThan 8");
 314     check(!n1.lessThan(n1), "lessThan 9");
 315     check(!n2.lessThan(n2), "lessThan 10");
 316 
 317     check(!p2.lessThan(p1), "lessThan 11");
 318     check(!n1.lessThan(p1), "lessThan 12");
 319     check(!n2.lessThan(p1), "lessThan 13");
 320     check(!n1.lessThan(p2), "lessThan 14");
 321     check(!n2.lessThan(p2), "lessThan 15");
 322     check(!n2.lessThan(n1), "lessThan 16");
 323 
 324     // lessThanOrEqual positive tests
 325     check(p1.lessThanOrEqual(p1), "lessThanOrEqual 1");
 326     check(p2.lessThanOrEqual(p2), "lessThanOrEqual 2");
 327     check(n1.lessThanOrEqual(n1), "lessThanOrEqual 3");
 328     check(n2.lessThanOrEqual(n2), "lessThanOrEqual 4");
 329 
 330     check(p1.lessThanOrEqual(p2), "lessThanOrEqual 5");
 331     check(p1.lessThanOrEqual(n1), "lessThanOrEqual 6");
 332     check(p1.lessThanOrEqual(n2), "lessThanOrEqual 7");
 333     check(p2.lessThanOrEqual(n1), "lessThanOrEqual 8");
 334     check(p2.lessThanOrEqual(n2), "lessThanOrEqual 9");
 335     check(n1.lessThanOrEqual(n2), "lessThanOrEqual 10");
 336 
 337     // lessThanOrEqual negative tests
 338     check(!p2.lessThanOrEqual(p1), "lessThanOrEqual 11");
 339     check(!n1.lessThanOrEqual(p1), "lessThanOrEqual 12");
 340     check(!n2.lessThanOrEqual(p1), "lessThanOrEqual 13");
 341     check(!n1.lessThanOrEqual(p2), "lessThanOrEqual 14");
 342     check(!n2.lessThanOrEqual(p2), "lessThanOrEqual 15");
 343     check(!n2.lessThanOrEqual(n1), "lessThanOrEqual 16");
 344 
 345     // greaterThan positive tests
 346     check(n2.greaterThan(p1), "greaterThan 1");
 347     check(n2.greaterThan(p2), "greaterThan 2");
 348     check(n2.greaterThan(n1), "greaterThan 3");
 349     check(n1.greaterThan(p1), "greaterThan 4");
 350     check(n1.greaterThan(p2), "greaterThan 5");
 351     check(p2.greaterThan(p1), "greaterThan 6");
 352 
 353     // greaterThan negative tests
 354     check(!p1.greaterThan(p1), "greaterThan 7");
 355     check(!p2.greaterThan(p2), "greaterThan 8");
 356     check(!n1.greaterThan(n1), "greaterThan 9");
 357     check(!n2.greaterThan(n2), "greaterThan 10");
 358 
 359     check(!p1.greaterThan(n2), "greaterThan 11");
 360     check(!p2.greaterThan(n2), "greaterThan 12");
 361     check(!n1.greaterThan(n2), "greaterThan 13");
 362     check(!p1.greaterThan(n1), "greaterThan 14");
 363     check(!p2.greaterThan(n1), "greaterThan 15");
 364     check(!p1.greaterThan(p2), "greaterThan 16");
 365 
 366     // greaterThanOrEqual positive tests
 367     check(p1.greaterThanOrEqual(p1), "greaterThanOrEqual 1");
 368     check(p2.greaterThanOrEqual(p2), "greaterThanOrEqual 2");
 369     check(n1.greaterThanOrEqual(n1), "greaterThanOrEqual 3");
 370     check(n2.greaterThanOrEqual(n2), "greaterThanOrEqual 4");
 371 
 372     check(n2.greaterThanOrEqual(p1), "greaterThanOrEqual 5");
 373     check(n2.greaterThanOrEqual(p2), "greaterThanOrEqual 6");
 374     check(n2.greaterThanOrEqual(n1), "greaterThanOrEqual 7");
 375     check(n1.greaterThanOrEqual(p1), "greaterThanOrEqual 8");
 376     check(n1.greaterThanOrEqual(p2), "greaterThanOrEqual 9");
 377     check(p2.greaterThanOrEqual(p1), "greaterThanOrEqual 10");
 378 
 379     // greaterThanOrEqual negative tests
 380     check(!p1.greaterThanOrEqual(n2), "greaterThanOrEqual 11");
 381     check(!p2.greaterThanOrEqual(n2), "greaterThanOrEqual 12");
 382     check(!n1.greaterThanOrEqual(n2), "greaterThanOrEqual 13");
 383     check(!p1.greaterThanOrEqual(n1), "greaterThanOrEqual 14");
 384     check(!p2.greaterThanOrEqual(n1), "greaterThanOrEqual 15");
 385     check(!p1.greaterThanOrEqual(p2), "greaterThanOrEqual 16");
 386 
 387     System.err.println("DummyAddress: all tests passed successfully.");
 388   }
 389 }