Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/tools/jdi/PacketStream.java
38920 views
/*1* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.tools.jdi;2627import com.sun.jdi.*;28import java.util.*;29import java.io.ByteArrayOutputStream;3031class PacketStream {32final VirtualMachineImpl vm;33private int inCursor = 0;34final Packet pkt;35private ByteArrayOutputStream dataStream = new ByteArrayOutputStream();36private boolean isCommitted = false;3738PacketStream(VirtualMachineImpl vm, int cmdSet, int cmd) {39this.vm = vm;40this.pkt = new Packet();41pkt.cmdSet = (short)cmdSet;42pkt.cmd = (short)cmd;43}4445PacketStream(VirtualMachineImpl vm, Packet pkt) {46this.vm = vm;47this.pkt = pkt;48this.isCommitted = true; /* read only stream */49}5051int id() {52return pkt.id;53}5455void send() {56if (!isCommitted) {57pkt.data = dataStream.toByteArray();58vm.sendToTarget(pkt);59isCommitted = true;60}61}6263void waitForReply() throws JDWPException {64if (!isCommitted) {65throw new InternalException("waitForReply without send");66}6768vm.waitForTargetReply(pkt);6970if (pkt.errorCode != Packet.ReplyNoError) {71throw new JDWPException(pkt.errorCode);72}73}7475void writeBoolean(boolean data) {76if(data) {77dataStream.write( 1 );78} else {79dataStream.write( 0 );80}81}8283void writeByte(byte data) {84dataStream.write( data );85}8687void writeChar(char data) {88dataStream.write( (byte)((data >>> 8) & 0xFF) );89dataStream.write( (byte)((data >>> 0) & 0xFF) );90}9192void writeShort(short data) {93dataStream.write( (byte)((data >>> 8) & 0xFF) );94dataStream.write( (byte)((data >>> 0) & 0xFF) );95}9697void writeInt(int data) {98dataStream.write( (byte)((data >>> 24) & 0xFF) );99dataStream.write( (byte)((data >>> 16) & 0xFF) );100dataStream.write( (byte)((data >>> 8) & 0xFF) );101dataStream.write( (byte)((data >>> 0) & 0xFF) );102}103104void writeLong(long data) {105dataStream.write( (byte)((data >>> 56) & 0xFF) );106dataStream.write( (byte)((data >>> 48) & 0xFF) );107dataStream.write( (byte)((data >>> 40) & 0xFF) );108dataStream.write( (byte)((data >>> 32) & 0xFF) );109110dataStream.write( (byte)((data >>> 24) & 0xFF) );111dataStream.write( (byte)((data >>> 16) & 0xFF) );112dataStream.write( (byte)((data >>> 8) & 0xFF) );113dataStream.write( (byte)((data >>> 0) & 0xFF) );114}115116void writeFloat(float data) {117writeInt(Float.floatToIntBits(data));118}119120void writeDouble(double data) {121writeLong(Double.doubleToLongBits(data));122}123124void writeID(int size, long data) {125switch (size) {126case 8:127writeLong(data);128break;129case 4:130writeInt((int)data);131break;132case 2:133writeShort((short)data);134break;135default:136throw new UnsupportedOperationException("JDWP: ID size not supported: " + size);137}138}139140void writeNullObjectRef() {141writeObjectRef(0);142}143144void writeObjectRef(long data) {145writeID(vm.sizeofObjectRef, data);146}147148void writeClassRef(long data) {149writeID(vm.sizeofClassRef, data);150}151152void writeMethodRef(long data) {153writeID(vm.sizeofMethodRef, data);154}155156void writeFieldRef(long data) {157writeID(vm.sizeofFieldRef, data);158}159160void writeFrameRef(long data) {161writeID(vm.sizeofFrameRef, data);162}163164void writeByteArray(byte[] data) {165dataStream.write(data, 0, data.length);166}167168void writeString(String string) {169try {170byte[] stringBytes = string.getBytes("UTF8");171writeInt(stringBytes.length);172writeByteArray(stringBytes);173} catch (java.io.UnsupportedEncodingException e) {174throw new InternalException("Cannot convert string to UTF8 bytes");175}176}177178void writeLocation(Location location) {179ReferenceTypeImpl refType = (ReferenceTypeImpl)location.declaringType();180byte tag;181if (refType instanceof ClassType) {182tag = JDWP.TypeTag.CLASS;183} else if (refType instanceof InterfaceType) {184// It's possible to have executable code in an interface185tag = JDWP.TypeTag.INTERFACE;186} else {187throw new InternalException("Invalid Location");188}189writeByte(tag);190writeClassRef(refType.ref());191writeMethodRef(((MethodImpl)location.method()).ref());192writeLong(location.codeIndex());193}194195void writeValue(Value val) {196try {197writeValueChecked(val);198} catch (InvalidTypeException exc) { // should never happen199throw new RuntimeException(200"Internal error: Invalid Tag/Type pair");201}202}203204void writeValueChecked(Value val) throws InvalidTypeException {205writeByte(ValueImpl.typeValueKey(val));206writeUntaggedValue(val);207}208209void writeUntaggedValue(Value val) {210try {211writeUntaggedValueChecked(val);212} catch (InvalidTypeException exc) { // should never happen213throw new RuntimeException(214"Internal error: Invalid Tag/Type pair");215}216}217218void writeUntaggedValueChecked(Value val) throws InvalidTypeException {219byte tag = ValueImpl.typeValueKey(val);220if (isObjectTag(tag)) {221if (val == null) {222writeObjectRef(0);223} else {224if (!(val instanceof ObjectReference)) {225throw new InvalidTypeException();226}227writeObjectRef(((ObjectReferenceImpl)val).ref());228}229} else {230switch (tag) {231case JDWP.Tag.BYTE:232if(!(val instanceof ByteValue))233throw new InvalidTypeException();234235writeByte(((PrimitiveValue)val).byteValue());236break;237238case JDWP.Tag.CHAR:239if(!(val instanceof CharValue))240throw new InvalidTypeException();241242writeChar(((PrimitiveValue)val).charValue());243break;244245case JDWP.Tag.FLOAT:246if(!(val instanceof FloatValue))247throw new InvalidTypeException();248249writeFloat(((PrimitiveValue)val).floatValue());250break;251252case JDWP.Tag.DOUBLE:253if(!(val instanceof DoubleValue))254throw new InvalidTypeException();255256writeDouble(((PrimitiveValue)val).doubleValue());257break;258259case JDWP.Tag.INT:260if(!(val instanceof IntegerValue))261throw new InvalidTypeException();262263writeInt(((PrimitiveValue)val).intValue());264break;265266case JDWP.Tag.LONG:267if(!(val instanceof LongValue))268throw new InvalidTypeException();269270writeLong(((PrimitiveValue)val).longValue());271break;272273case JDWP.Tag.SHORT:274if(!(val instanceof ShortValue))275throw new InvalidTypeException();276277writeShort(((PrimitiveValue)val).shortValue());278break;279280case JDWP.Tag.BOOLEAN:281if(!(val instanceof BooleanValue))282throw new InvalidTypeException();283284writeBoolean(((PrimitiveValue)val).booleanValue());285break;286}287}288}289290291292/**293* Read byte represented as one bytes.294*/295byte readByte() {296byte ret = pkt.data[inCursor];297inCursor += 1;298return ret;299}300301/**302* Read boolean represented as one byte.303*/304boolean readBoolean() {305byte ret = readByte();306return (ret != 0);307}308309/**310* Read char represented as two bytes.311*/312char readChar() {313int b1, b2;314315b1 = pkt.data[inCursor++] & 0xff;316b2 = pkt.data[inCursor++] & 0xff;317318return (char)((b1 << 8) + b2);319}320321/**322* Read short represented as two bytes.323*/324short readShort() {325int b1, b2;326327b1 = pkt.data[inCursor++] & 0xff;328b2 = pkt.data[inCursor++] & 0xff;329330return (short)((b1 << 8) + b2);331}332333/**334* Read int represented as four bytes.335*/336int readInt() {337int b1,b2,b3,b4;338339b1 = pkt.data[inCursor++] & 0xff;340b2 = pkt.data[inCursor++] & 0xff;341b3 = pkt.data[inCursor++] & 0xff;342b4 = pkt.data[inCursor++] & 0xff;343344return ((b1 << 24) + (b2 << 16) + (b3 << 8) + b4);345}346347/**348* Read long represented as eight bytes.349*/350long readLong() {351long b1,b2,b3,b4;352long b5,b6,b7,b8;353354b1 = pkt.data[inCursor++] & 0xff;355b2 = pkt.data[inCursor++] & 0xff;356b3 = pkt.data[inCursor++] & 0xff;357b4 = pkt.data[inCursor++] & 0xff;358359b5 = pkt.data[inCursor++] & 0xff;360b6 = pkt.data[inCursor++] & 0xff;361b7 = pkt.data[inCursor++] & 0xff;362b8 = pkt.data[inCursor++] & 0xff;363364return ((b1 << 56) + (b2 << 48) + (b3 << 40) + (b4 << 32)365+ (b5 << 24) + (b6 << 16) + (b7 << 8) + b8);366}367368/**369* Read float represented as four bytes.370*/371float readFloat() {372return Float.intBitsToFloat(readInt());373}374375/**376* Read double represented as eight bytes.377*/378double readDouble() {379return Double.longBitsToDouble(readLong());380}381382/**383* Read string represented as four byte length followed by384* characters of the string.385*/386String readString() {387String ret;388int len = readInt();389390try {391ret = new String(pkt.data, inCursor, len, "UTF8");392} catch(java.io.UnsupportedEncodingException e) {393System.err.println(e);394ret = "Conversion error!";395}396inCursor += len;397return ret;398}399400private long readID(int size) {401switch (size) {402case 8:403return readLong();404case 4:405return (long)readInt();406case 2:407return (long)readShort();408default:409throw new UnsupportedOperationException("JDWP: ID size not supported: " + size);410}411}412413/**414* Read object represented as vm specific byte sequence.415*/416long readObjectRef() {417return readID(vm.sizeofObjectRef);418}419420long readClassRef() {421return readID(vm.sizeofClassRef);422}423424ObjectReferenceImpl readTaggedObjectReference() {425byte typeKey = readByte();426return vm.objectMirror(readObjectRef(), typeKey);427}428429ObjectReferenceImpl readObjectReference() {430return vm.objectMirror(readObjectRef());431}432433StringReferenceImpl readStringReference() {434long ref = readObjectRef();435return vm.stringMirror(ref);436}437438ArrayReferenceImpl readArrayReference() {439long ref = readObjectRef();440return vm.arrayMirror(ref);441}442443ThreadReferenceImpl readThreadReference() {444long ref = readObjectRef();445return vm.threadMirror(ref);446}447448ThreadGroupReferenceImpl readThreadGroupReference() {449long ref = readObjectRef();450return vm.threadGroupMirror(ref);451}452453ClassLoaderReferenceImpl readClassLoaderReference() {454long ref = readObjectRef();455return vm.classLoaderMirror(ref);456}457458ClassObjectReferenceImpl readClassObjectReference() {459long ref = readObjectRef();460return vm.classObjectMirror(ref);461}462463ReferenceTypeImpl readReferenceType() {464byte tag = readByte();465long ref = readObjectRef();466return vm.referenceType(ref, tag);467}468469/**470* Read method reference represented as vm specific byte sequence.471*/472long readMethodRef() {473return readID(vm.sizeofMethodRef);474}475476/**477* Read field reference represented as vm specific byte sequence.478*/479long readFieldRef() {480return readID(vm.sizeofFieldRef);481}482483/**484* Read field represented as vm specific byte sequence.485*/486Field readField() {487ReferenceTypeImpl refType = readReferenceType();488long fieldRef = readFieldRef();489return refType.getFieldMirror(fieldRef);490}491492/**493* Read frame represented as vm specific byte sequence.494*/495long readFrameRef() {496return readID(vm.sizeofFrameRef);497}498499/**500* Read a value, first byte describes type of value to read.501*/502ValueImpl readValue() {503byte typeKey = readByte();504return readUntaggedValue(typeKey);505}506507ValueImpl readUntaggedValue(byte typeKey) {508ValueImpl val = null;509510if (isObjectTag(typeKey)) {511val = vm.objectMirror(readObjectRef(), typeKey);512} else {513switch(typeKey) {514case JDWP.Tag.BYTE:515val = new ByteValueImpl(vm, readByte());516break;517518case JDWP.Tag.CHAR:519val = new CharValueImpl(vm, readChar());520break;521522case JDWP.Tag.FLOAT:523val = new FloatValueImpl(vm, readFloat());524break;525526case JDWP.Tag.DOUBLE:527val = new DoubleValueImpl(vm, readDouble());528break;529530case JDWP.Tag.INT:531val = new IntegerValueImpl(vm, readInt());532break;533534case JDWP.Tag.LONG:535val = new LongValueImpl(vm, readLong());536break;537538case JDWP.Tag.SHORT:539val = new ShortValueImpl(vm, readShort());540break;541542case JDWP.Tag.BOOLEAN:543val = new BooleanValueImpl(vm, readBoolean());544break;545546case JDWP.Tag.VOID:547val = new VoidValueImpl(vm);548break;549}550}551return val;552}553554/**555* Read location represented as vm specific byte sequence.556*/557Location readLocation() {558byte tag = readByte();559long classRef = readObjectRef();560long methodRef = readMethodRef();561long codeIndex = readLong();562if (classRef != 0) {563/* Valid location */564ReferenceTypeImpl refType = vm.referenceType(classRef, tag);565return new LocationImpl(vm, refType, methodRef, codeIndex);566} else {567/* Null location (example: uncaught exception) */568return null;569}570}571572byte[] readByteArray(int length) {573byte[] array = new byte[length];574System.arraycopy(pkt.data, inCursor, array, 0, length);575inCursor += length;576return array;577}578579List<Value> readArrayRegion() {580byte typeKey = readByte();581int length = readInt();582List<Value> list = new ArrayList<Value>(length);583boolean gettingObjects = isObjectTag(typeKey);584for (int i = 0; i < length; i++) {585/*586* Each object comes back with a type key which might587* identify a more specific type than the type key we588* passed in, so we use it in the decodeValue call.589* (For primitives, we just use the original one)590*/591if (gettingObjects) {592typeKey = readByte();593}594Value value = readUntaggedValue(typeKey);595list.add(value);596}597598return list;599}600601void writeArrayRegion(List<Value> srcValues) {602writeInt(srcValues.size());603for (int i = 0; i < srcValues.size(); i++) {604Value value = srcValues.get(i);605writeUntaggedValue(value);606}607}608609int skipBytes(int n) {610inCursor += n;611return n;612}613614byte command() {615return (byte)pkt.cmd;616}617618static boolean isObjectTag(byte tag) {619return (tag == JDWP.Tag.OBJECT) ||620(tag == JDWP.Tag.ARRAY) ||621(tag == JDWP.Tag.STRING) ||622(tag == JDWP.Tag.THREAD) ||623(tag == JDWP.Tag.THREAD_GROUP) ||624(tag == JDWP.Tag.CLASS_LOADER) ||625(tag == JDWP.Tag.CLASS_OBJECT);626}627}628629630