1 /* 2 * Copyright (c) 2002, 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.remote; 26 27 import sun.jvm.hotspot.debugger.*; 28 29 class RemoteAddress implements Address { 30 protected RemoteDebuggerClient debugger; 31 protected long addr; 32 33 RemoteAddress(RemoteDebuggerClient debugger, long addr) { 34 this.debugger = debugger; 35 this.addr = addr; 36 } 37 38 // 39 // Basic Java routines 40 // 41 42 public boolean equals(Object arg) { 43 if (arg == null) { 44 return false; 45 } 46 47 if (!(arg instanceof RemoteAddress)) { 48 return false; 49 } 50 51 return (addr == ((RemoteAddress) arg).addr); 52 } 53 54 public int hashCode() { 55 // FIXME: suggestions on a better hash code? 56 return (int) addr; 57 } 58 59 public String toString() { 60 return debugger.addressValueToString(addr); 61 } 62 63 // 64 // C/C++-related routines 65 // 66 67 public long getCIntegerAt(long offset, long numBytes, boolean isUnsigned) throws UnalignedAddressException, UnmappedAddressException { 68 return debugger.readCInteger(addr + offset, numBytes, isUnsigned); 69 } 70 71 public Address getAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException { 72 return debugger.readAddress(addr + offset); 73 } 74 public Address getCompOopAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException { 75 return debugger.readCompOopAddress(addr + offset); 76 } 77 public Address getCompKlassAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException { 78 return debugger.readCompKlassAddress(addr + offset); 79 } 80 81 // 82 // Java-related routines 83 // 84 85 public boolean getJBooleanAt(long offset) throws UnalignedAddressException, UnmappedAddressException { 86 return debugger.readJBoolean(addr + offset); 87 } 88 89 public byte getJByteAt(long offset) throws UnalignedAddressException, UnmappedAddressException { 90 return debugger.readJByte(addr + offset); 91 } 92 93 public char getJCharAt(long offset) throws UnalignedAddressException, UnmappedAddressException { 94 return debugger.readJChar(addr + offset); 95 } 96 97 public double getJDoubleAt(long offset) throws UnalignedAddressException, UnmappedAddressException { 98 return debugger.readJDouble(addr + offset); 99 } 100 101 public float getJFloatAt(long offset) throws UnalignedAddressException, UnmappedAddressException { 102 return debugger.readJFloat(addr + offset); 103 } 104 105 public int getJIntAt(long offset) throws UnalignedAddressException, UnmappedAddressException { 106 return debugger.readJInt(addr + offset); 107 } 108 109 public long getJLongAt(long offset) throws UnalignedAddressException, UnmappedAddressException { 110 return debugger.readJLong(addr + offset); 111 } 112 113 public short getJShortAt(long offset) throws UnalignedAddressException, UnmappedAddressException { 114 return debugger.readJShort(addr + offset); 115 } 116 117 public OopHandle getOopHandleAt(long offset) 118 throws UnalignedAddressException, UnmappedAddressException, NotInHeapException { 119 return debugger.readOopHandle(addr + offset); 120 } 121 public OopHandle getCompOopHandleAt(long offset) 122 throws UnalignedAddressException, UnmappedAddressException, NotInHeapException { 123 return debugger.readCompOopHandle(addr + offset); 124 } 125 126 // Mutators -- not implemented for now (FIXME) 127 public void setCIntegerAt(long offset, long numBytes, long value) { 128 throw new DebuggerException("Unimplemented"); 129 } 130 public void setAddressAt(long offset, Address value) { 131 throw new DebuggerException("Unimplemented"); 132 } 133 public void setJBooleanAt (long offset, boolean value) 134 throws UnmappedAddressException, UnalignedAddressException { 135 throw new DebuggerException("Unimplemented"); 136 } 137 public void setJByteAt (long offset, byte value) 138 throws UnmappedAddressException, UnalignedAddressException { 139 throw new DebuggerException("Unimplemented"); 140 } 141 public void setJCharAt (long offset, char value) 142 throws UnmappedAddressException, UnalignedAddressException { 143 throw new DebuggerException("Unimplemented"); 144 } 145 public void setJDoubleAt (long offset, double value) 146 throws UnmappedAddressException, UnalignedAddressException { 147 throw new DebuggerException("Unimplemented"); 148 } 149 public void setJFloatAt (long offset, float value) 150 throws UnmappedAddressException, UnalignedAddressException { 151 throw new DebuggerException("Unimplemented"); 152 } 153 public void setJIntAt (long offset, int value) 154 throws UnmappedAddressException, UnalignedAddressException { 155 throw new DebuggerException("Unimplemented"); 156 } 157 public void setJLongAt (long offset, long value) 158 throws UnmappedAddressException, UnalignedAddressException { 159 throw new DebuggerException("Unimplemented"); 160 } 161 public void setJShortAt (long offset, short value) 162 throws UnmappedAddressException, UnalignedAddressException { 163 throw new DebuggerException("Unimplemented"); 164 } 165 public void setOopHandleAt (long offset, OopHandle value) 166 throws UnmappedAddressException, UnalignedAddressException { 167 throw new DebuggerException("Unimplemented"); 168 } 169 170 // 171 // Arithmetic operations -- necessary evil. 172 // 173 174 public Address addOffsetTo (long offset) throws UnsupportedOperationException { 175 long value = addr + offset; 176 if (value == 0) { 177 return null; 178 } 179 return new RemoteAddress(debugger, value); 180 } 181 182 public OopHandle addOffsetToAsOopHandle(long offset) throws UnsupportedOperationException { 183 long value = addr + offset; 184 if (value == 0) { 185 return null; 186 } 187 return new RemoteOopHandle(debugger, value); 188 } 189 190 /** (FIXME: any signed/unsigned issues? Should this work for 191 OopHandles?) */ 192 public long minus(Address arg) { 193 if (arg == null) { 194 return addr; 195 } 196 return addr - ((RemoteAddress) arg).addr; 197 } 198 199 // Two's complement representation. 200 // All negative numbers are larger than positive numbers. 201 // Numbers with the same sign can be compared normally. 202 // Test harness is below in main(). 203 204 public boolean lessThan (Address arg) { 205 if (arg == null) { 206 return false; 207 } 208 RemoteAddress remoteArg = (RemoteAddress) arg; 209 if ((addr >= 0) && (remoteArg.addr < 0)) { 210 return true; 211 } 212 if ((addr < 0) && (remoteArg.addr >= 0)) { 213 return false; 214 } 215 return (addr < remoteArg.addr); 216 } 217 218 public boolean lessThanOrEqual (Address arg) { 219 if (arg == null) { 220 return false; 221 } 222 RemoteAddress remoteArg = (RemoteAddress) arg; 223 if ((addr >= 0) && (remoteArg.addr < 0)) { 224 return true; 225 } 226 if ((addr < 0) && (remoteArg.addr >= 0)) { 227 return false; 228 } 229 return (addr <= remoteArg.addr); 230 } 231 232 public boolean greaterThan (Address arg) { 233 if (arg == null) { 234 return true; 235 } 236 RemoteAddress remoteArg = (RemoteAddress) arg; 237 if ((addr >= 0) && (remoteArg.addr < 0)) { 238 return false; 239 } 240 if ((addr < 0) && (remoteArg.addr >= 0)) { 241 return true; 242 } 243 return (addr > remoteArg.addr); 244 } 245 246 public boolean greaterThanOrEqual(Address arg) { 247 if (arg == null) { 248 return true; 249 } 250 RemoteAddress remoteArg = (RemoteAddress) arg; 251 if ((addr >= 0) && (remoteArg.addr < 0)) { 252 return false; 253 } 254 if ((addr < 0) && (remoteArg.addr >= 0)) { 255 return true; 256 } 257 return (addr >= remoteArg.addr); 258 } 259 260 public Address andWithMask(long mask) throws UnsupportedOperationException { 261 long value = addr & mask; 262 if (value == 0) { 263 return null; 264 } 265 return new RemoteAddress(debugger, value); 266 } 267 268 public Address orWithMask(long mask) throws UnsupportedOperationException { 269 long value = addr | mask; 270 if (value == 0) { 271 return null; 272 } 273 return new RemoteAddress(debugger, value); 274 } 275 276 public Address xorWithMask(long mask) throws UnsupportedOperationException { 277 long value = addr ^ mask; 278 if (value == 0) { 279 return null; 280 } 281 return new RemoteAddress(debugger, value); 282 } 283 284 public long asLongValue() { return addr; } 285 //-------------------------------------------------------------------------------- 286 // Internals only below this point 287 // 288 289 long getValue() { 290 return addr; 291 } 292 293 294 private static void check(boolean arg, String failMessage) { 295 if (!arg) { 296 System.err.println(failMessage + ": FAILED"); 297 System.exit(1); 298 } 299 } 300 301 // Test harness 302 public static void main(String[] args) { 303 // p/n indicates whether the interior address is really positive 304 // or negative. In unsigned terms, p1 < p2 < n1 < n2. 305 306 RemoteAddress p1 = new RemoteAddress(null, 0x7FFFFFFFFFFFFFF0L); 307 RemoteAddress p2 = (RemoteAddress) p1.addOffsetTo(10); 308 RemoteAddress n1 = (RemoteAddress) p2.addOffsetTo(10); 309 RemoteAddress n2 = (RemoteAddress) n1.addOffsetTo(10); 310 311 // lessThan positive tests 312 check(p1.lessThan(p2), "lessThan 1"); 313 check(p1.lessThan(n1), "lessThan 2"); 314 check(p1.lessThan(n2), "lessThan 3"); 315 check(p2.lessThan(n1), "lessThan 4"); 316 check(p2.lessThan(n2), "lessThan 5"); 317 check(n1.lessThan(n2), "lessThan 6"); 318 319 // lessThan negative tests 320 check(!p1.lessThan(p1), "lessThan 7"); 321 check(!p2.lessThan(p2), "lessThan 8"); 322 check(!n1.lessThan(n1), "lessThan 9"); 323 check(!n2.lessThan(n2), "lessThan 10"); 324 325 check(!p2.lessThan(p1), "lessThan 11"); 326 check(!n1.lessThan(p1), "lessThan 12"); 327 check(!n2.lessThan(p1), "lessThan 13"); 328 check(!n1.lessThan(p2), "lessThan 14"); 329 check(!n2.lessThan(p2), "lessThan 15"); 330 check(!n2.lessThan(n1), "lessThan 16"); 331 332 // lessThanOrEqual positive tests 333 check(p1.lessThanOrEqual(p1), "lessThanOrEqual 1"); 334 check(p2.lessThanOrEqual(p2), "lessThanOrEqual 2"); 335 check(n1.lessThanOrEqual(n1), "lessThanOrEqual 3"); 336 check(n2.lessThanOrEqual(n2), "lessThanOrEqual 4"); 337 338 check(p1.lessThanOrEqual(p2), "lessThanOrEqual 5"); 339 check(p1.lessThanOrEqual(n1), "lessThanOrEqual 6"); 340 check(p1.lessThanOrEqual(n2), "lessThanOrEqual 7"); 341 check(p2.lessThanOrEqual(n1), "lessThanOrEqual 8"); 342 check(p2.lessThanOrEqual(n2), "lessThanOrEqual 9"); 343 check(n1.lessThanOrEqual(n2), "lessThanOrEqual 10"); 344 345 // lessThanOrEqual negative tests 346 check(!p2.lessThanOrEqual(p1), "lessThanOrEqual 11"); 347 check(!n1.lessThanOrEqual(p1), "lessThanOrEqual 12"); 348 check(!n2.lessThanOrEqual(p1), "lessThanOrEqual 13"); 349 check(!n1.lessThanOrEqual(p2), "lessThanOrEqual 14"); 350 check(!n2.lessThanOrEqual(p2), "lessThanOrEqual 15"); 351 check(!n2.lessThanOrEqual(n1), "lessThanOrEqual 16"); 352 353 // greaterThan positive tests 354 check(n2.greaterThan(p1), "greaterThan 1"); 355 check(n2.greaterThan(p2), "greaterThan 2"); 356 check(n2.greaterThan(n1), "greaterThan 3"); 357 check(n1.greaterThan(p1), "greaterThan 4"); 358 check(n1.greaterThan(p2), "greaterThan 5"); 359 check(p2.greaterThan(p1), "greaterThan 6"); 360 361 // greaterThan negative tests 362 check(!p1.greaterThan(p1), "greaterThan 7"); 363 check(!p2.greaterThan(p2), "greaterThan 8"); 364 check(!n1.greaterThan(n1), "greaterThan 9"); 365 check(!n2.greaterThan(n2), "greaterThan 10"); 366 367 check(!p1.greaterThan(n2), "greaterThan 11"); 368 check(!p2.greaterThan(n2), "greaterThan 12"); 369 check(!n1.greaterThan(n2), "greaterThan 13"); 370 check(!p1.greaterThan(n1), "greaterThan 14"); 371 check(!p2.greaterThan(n1), "greaterThan 15"); 372 check(!p1.greaterThan(p2), "greaterThan 16"); 373 374 // greaterThanOrEqual positive tests 375 check(p1.greaterThanOrEqual(p1), "greaterThanOrEqual 1"); 376 check(p2.greaterThanOrEqual(p2), "greaterThanOrEqual 2"); 377 check(n1.greaterThanOrEqual(n1), "greaterThanOrEqual 3"); 378 check(n2.greaterThanOrEqual(n2), "greaterThanOrEqual 4"); 379 380 check(n2.greaterThanOrEqual(p1), "greaterThanOrEqual 5"); 381 check(n2.greaterThanOrEqual(p2), "greaterThanOrEqual 6"); 382 check(n2.greaterThanOrEqual(n1), "greaterThanOrEqual 7"); 383 check(n1.greaterThanOrEqual(p1), "greaterThanOrEqual 8"); 384 check(n1.greaterThanOrEqual(p2), "greaterThanOrEqual 9"); 385 check(p2.greaterThanOrEqual(p1), "greaterThanOrEqual 10"); 386 387 // greaterThanOrEqual negative tests 388 check(!p1.greaterThanOrEqual(n2), "greaterThanOrEqual 11"); 389 check(!p2.greaterThanOrEqual(n2), "greaterThanOrEqual 12"); 390 check(!n1.greaterThanOrEqual(n2), "greaterThanOrEqual 13"); 391 check(!p1.greaterThanOrEqual(n1), "greaterThanOrEqual 14"); 392 check(!p2.greaterThanOrEqual(n1), "greaterThanOrEqual 15"); 393 check(!p1.greaterThanOrEqual(p2), "greaterThanOrEqual 16"); 394 395 System.err.println("RemoteAddress: all tests passed successfully."); 396 } 397 }