LOGIN   :::   RECOVER PASS   :::   GET ACCOUNT    
Browse
  • Projects
  • Code (CVS)
  • Forums
  • News
  • Articles
  • Polls
  •  
    OpenCores
  • FAQ
  • CVS HowTo
  • Mission
  • Media
  • Tools
  • Advertise
  • Mirrors
  • Logos
  • Contact us
  • Job Opportunity
  •  
    Tools
  • Search
      
  • Download Cores (CVSGet)
  •  
    More
  • Wishbone
  • Perlilog
  • EDA tools
  • OpenTech CD
  •  
    Navigation: All forums > Cvs-checkins > Message List > Message Post

    Message

    Reply | Reply all
    Date Prev | Date Next | Thread Prev | Thread Next Date Index | Thread Index

    From: cvs at opencores.org<cvs@o...>
    Date: Fri Jan 18 23:31:34 CET 2008
    Subject: [cvs-checkins] MODIFIED: jop ...
    Top
    Date: 00/08/01 18:23:31

    Modified: jop/java/target/src/test/debug JopDebugKernel.java
    Log:
    - Changes to add support for get/set operations on instance fields.

    - Changed the way the debug IO streams are created.

    - Removed some useless comments

    - Added some methods to access object handle internal fields

    - Added some methods to access class structure internal fields

    - Other changes



    Methods changed:

    118: public static final void breakpoint()

    731: private static void setDebugStreams(InputStream in, OutputStream out)



    Methods added:

    1114: private static int getInstanceSizeFromClass(int classReference)

    1119: private static int getPointerToStaticPrimitiveFields(int classReference)

    1125: private static int getPointerToSuperclass(int classReference)

    1139: private static int getClassPointerFromObjectHandle(int objectHandle)

    1162: private static int getInstanceField(int objectHandle, int fieldIndex)

    1215: private static void setInstanceField(int objectHandle, int fieldIndex,

    1216: int fieldValue)

    1261: private static void clearFlagForInstanceFieldAccess()

    1271: private static void setErrorCodeForInstanceFieldAccess(int errorCode)

    1281: private static int getErrorCodeForInstanceFieldAccess()

    1293: private static boolean isSuccessfulLastInstanceFieldAccess()

    1637: private static void handleGetInstanceVariable() throws IOException

    1714: private static void handleSetInstanceVariable() throws IOException

    1789: private static final int getObjectPointer(int objectHandle)

    1804: private static final int getObjectSize(int objectHandle)

    1819: private static final int getMethodTablePointerOrArrayLength(int objectHandle)

    1834: private static final boolean isArrayType(int objectHandle)

    2642: private static final void printObjectHandle(int handle)




    Revision Changes Path
    1.8 jop/java/target/src/test/debug/JopDebugKernel.java

    http://www.opencores.org/cvsweb.shtml/jop/java/target/src/test/debug/JopDebugKernel.java.diff?r1=1.7&r2=1.8

    (In the diff below, changes in quantity of whitespace are not shown.)

    Index: JopDebugKernel.java
    ===================================================================
    RCS file: /cvsroot/paulo/jop/java/target/src/test/debug/JopDebugKernel.java,v
    retrieving revision 1.7
    retrieving revision 1.8
    diff -u -b -r1.7 -r1.8
    --- JopDebugKernel.java 19 Dec 2007 20:39:52 -0000 1.7
    +++ JopDebugKernel.java 18 Jan 2008 22:31:33 -0000 1.8
    @@ -27,8 +27,11 @@
    import java.io.InputStream;
    import java.io.OutputStream;

    +import org.apache.bcel.Constants;
    +
    import debug.constants.TagConstants;
    import com.jopdesign.sys.Const;
    +import com.jopdesign.sys.GC;
    import com.jopdesign.sys.Native;

    import debug.constants.CommandConstants;
    @@ -80,6 +83,10 @@
    // a variable to hold the frame pointer of the breakpoint method
    private static int breakpointFramePointer;

    + // an internal flag to inform error codes during object access.
    + // used to avoid memory allocation when creating exceptions.
    + private static int errorCodeForInstanceFieldAccess;
    +
    // internal flag to turn on/off tracing messages //private static boolean shouldPrintInternalMessages = false; private static boolean shouldPrintInternalMessages = true; @@ -220,6 +227,22 @@ continue; } + // get a field from an object + if((commandset == 9) && (command == 2)) + { + debugPrintln("GetValues (2)"); + handleGetInstanceVariable(); + continue; + } + + // set a field into an object + if((commandset == 9) && (command == 3)) + { + debugPrintln("SetValues (3)"); + handleSetInstanceVariable(); + continue; + } + // resume execution. Finish this method and continue. if((commandset == 11) && (command == 3)) { @@ -722,7 +745,7 @@ } /** - * This method can be used in the future to set the streams which will be + * This method can be used in the future, to set the streams which will be * used to communicate with the JOP machine. * * @param in @@ -730,9 +753,24 @@ */ private static void setDebugStreams(InputStream in, OutputStream out) { + if(in instanceof DataInputStream) + { + inputStream = (DataInputStream) in; + } + else + { inputStream = new DataInputStream(in); + } + + if(out instanceof DataOutputStream) + { + outputStream = (DataOutputStream) out; + } + else + { outputStream = new DataOutputStream(out); } + } private static int getCPLocalsArgsFromMP(int mp) { @@ -1063,27 +1101,6 @@ } /** - * Get the framePointer at the given index. - * The depth of the first frame (for the main method) is zero. - * Methods called inside "main" will have depth = 1 - * and so on. - * - * @param framePointer - * @return - */ -// public static final int getFramePointerAt(int framePointer, int index) -// { -// int count = getStackDepth(); -// while(isFirstFrame(framePointer) == false && (index < count)) -// { -// count--; -// framePointer = getNextFramePointer(framePointer); -// } -// -// return framePointer; -// } - - /** * Return the current stack depth. * * @return @@ -1094,35 +1111,188 @@ return getStackDepth(framePointer); } - private static int getInstanceSize(int object) + private static int getInstanceSizeFromClass(int classReference) { - int classReference = getClassReference(object); return Native.rdMem(classReference); } - private static int getClassReference(int object) + private static int getPointerToStaticPrimitiveFields(int classReference) + { + classReference++; + return Native.rdMem(classReference); + } + + private static int getPointerToSuperclass(int classReference) + { + classReference+=3; + return Native.rdMem(classReference); + } + + /** + * Return the class pointer from an object. + * Be careful: if a handle to an array is passed, this method will + * return zero. Hence, DON't USE IT WITH ARRAYS!!! it just DOES NOT WORK. + * + * @param objectHandle + * @return + */ + private static int getClassPointerFromObjectHandle(int objectHandle) + { + int classPointer = 0; + if(isArrayType(objectHandle) == false) + { + synchronized(GC.getMutex()) + { + classPointer = getMethodTablePointerOrArrayLength(objectHandle); + // fix the offset to point to the class structure (instance size) + classPointer -= 5; + } + } + + return classPointer; + } + + /** + * Get the value of one instance field. + * + * @param objectHandle + * @param fieldIndex + * @return + */ + private static int getInstanceField(int objectHandle, int fieldIndex) + { + int size; + int value = 0; + int objectPointer; + + synchronized(GC.getMutex()) + { + // for development only + printObjectHandle(objectHandle); + + // clear the error flag + clearFlagForInstanceFieldAccess(); + + // get the object size + size = getObjectSize(objectHandle); + + debugPrint(" object size: "); + debugPrintln(size); + + // check if the field index makes sense. Access only if it's a valid one. + if(fieldIndex >= 0 && fieldIndex < size) + { + // get the object pointer + objectPointer = getObjectPointer(objectHandle); + + //use it to access the object content + value = Native.rdMem(objectPointer + fieldIndex); + } + else + { + // set an error code to inform that this operation failed. + setErrorCodeForInstanceFieldAccess(ErrorConstants.ERROR_INVALID_FIELDID); + + debugPrint(" Invalid index: "); + debugPrintln(fieldIndex); + + debugPrint(" Num. instance locals is: "); + debugPrintln(size); + } + } + + return value; + } + + /** + * Set the value of one instance field. + * + * @param objectHandle + * @param fieldIndex + * @param fieldValue + * @return + */ + private static void setInstanceField(int objectHandle, int fieldIndex, + int fieldValue) + { + int size; + int objectPointer; + + synchronized(GC.getMutex()) { - int classreference = 0; + // for development only + printObjectHandle(objectHandle); - // return one byte and read the pointer to the virtual method table - object --; - classreference = Native.rdMem(object); + // clear the error flag + clearFlagForInstanceFieldAccess(); + + // get the object size + size = getObjectSize(objectHandle); + + debugPrint(" object size: "); + debugPrintln(size); + + // check if the field index makes sense. Access only if it's a valid one. + if(fieldIndex >= 0 && fieldIndex < size) + { + // get the object pointer + objectPointer = getObjectPointer(objectHandle); + + //use it to access the object content + Native.wrMem(fieldValue, objectPointer + fieldIndex); + } + else + { + // set an error code to inform that this operation failed. + setErrorCodeForInstanceFieldAccess(ErrorConstants.ERROR_INVALID_FIELDID); + + debugPrint(" Invalid index: "); + debugPrintln(fieldIndex); + + debugPrint(" Num. instance locals is: "); + debugPrintln(size); + } + } + } - // adjust to point to the "instance size" field - classreference--; - classreference--; + /** + * Clear the error flag. Setup for next access. + */ + private static void clearFlagForInstanceFieldAccess() + { + errorCodeForInstanceFieldAccess = 0; + } - return classreference; + /** + * Set an error code to inform that something went wrong. + * + * @param errorCode + */ + private static void setErrorCodeForInstanceFieldAccess(int errorCode) + { + errorCodeForInstanceFieldAccess = errorCode; } - private static int getConstantPoolFromClassReference(int classReference) + /** + * Return the error code, if any. + * + * @return + */ + private static int getErrorCodeForInstanceFieldAccess() { - // get reference to the first method. There will always be some, - // due to generated/synthetic methods such as the default constructur - int methodReference = Native.rdMem(classReference + 2); - int constantPoolReference = getCPFromMP(methodReference); + return errorCodeForInstanceFieldAccess; + } - return constantPoolReference; + /** + * Check if the last operation of "instance field access" + * was successful or not. If the error code is zero, then + * report success. + * + * @return + */ + private static boolean isSuccessfulLastInstanceFieldAccess() + { + return (errorCodeForInstanceFieldAccess == 0); } /** @@ -1460,6 +1630,218 @@ } /** + * Handle a "Get instance variable" command. + * + * @throws IOException + */ + private static void handleGetInstanceVariable() throws IOException + { + int objectHandle; + int counter; + int numFields; + int fieldIndex; + int fieldValue; + + // read the object handle + objectHandle = debugChannel.readIntValue(); + + // What happens if the GC is working and change the pointers + // before or during an access? Let's stay on the safe size. + // Lock the GC while manipulating objects directly. + synchronized(GC.getMutex()) + { + // check if the reference type is a valid one. + if(GC.isValidObjectHandle(objectHandle) == false) + { + debugPrint("Failure: invalid object handle."); + debugPrint(objectHandle); + debugPrintln(); + + // send a packet with an error code and return. + debugChannel.sendReplyWithErrorCode(ErrorConstants.ERROR_INVALID_OBJECT); + return; + } + + // read the number of fields to be accessed. + numFields = debugChannel.readIntValue(); + + // prepare the reply packet + debugChannel.prepareInstanceValuesPacket(numFields); + + // fill in the packet with all information requested + for(counter = 0; counter < numFields; counter++) + { + fieldIndex = debugChannel.readIntValue(); + fieldValue = getInstanceField(objectHandle, fieldIndex); + + // check if an error happened during field access. + // if so, stop the loop and send an error packet. + if(isSuccessfulLastInstanceFieldAccess() == false) + { + debugPrint("Failure accessing field # "); + debugPrint(counter); + debugPrint(". field index: "); + debugPrint(fieldIndex); + debugPrintln(); + + break; + } + + debugChannel.writeInstanceFieldValue(fieldValue); + } + } + // end of synchronized block. Now the GC can work freely. + + // check the error flag. If there's an error, send an error code. + // otherwise, all data is correct. Send it to the server. + if(isSuccessfulLastInstanceFieldAccess() == false) + { + // send a packet with an error code. + debugChannel.sendReplyWithErrorCode(getErrorCodeForInstanceFieldAccess()); + } + else + { + // great! packet ready. Send it to the server. + debugChannel.sendInstanceFieldValuesReply(); + } + } + + /** + * Handle a "Set instance variable" command. + * + * @throws IOException + */ + private static void handleSetInstanceVariable() throws IOException + { + int objectHandle; + int counter; + int numFields; + int fieldIndex; + int fieldValue; + + // read the object handle + objectHandle = debugChannel.readIntValue(); + + // What happens if the GC is working and change the pointers + // before or during an access? Let's stay on the safe size. + // Lock the GC while manipulating objects directly. + synchronized(GC.getMutex()) + { + // check if the reference type is a valid one. + if(GC.isValidObjectHandle(objectHandle) == false) + { + debugPrint("Failure: invalid object handle."); + debugPrint(objectHandle); + debugPrintln(); + + // send a packet with an error code and return. + debugChannel.sendReplyWithErrorCode(ErrorConstants.ERROR_INVALID_OBJECT); + return; + } + + // read the number of fields to be accessed. + numFields = debugChannel.readIntValue(); + + // fill in the packet with all information requested + for(counter = 0; counter < numFields; counter++) + { + fieldIndex = debugChannel.readIntValue(); + fieldValue = debugChannel.readIntValue(); + setInstanceField(objectHandle, fieldIndex, fieldValue); + + // check if an error happened during field access. + // if so, stop the loop and send an error packet. + if(isSuccessfulLastInstanceFieldAccess() == false) + { + debugPrint("Failure accessing field # "); + debugPrint(counter); + debugPrint(". field index: "); + debugPrint(fieldIndex); + debugPrint(". new field value: "); + debugPrint(fieldValue); + debugPrintln(); + + break; + } + } + } + // end of synchronized block. Now the GC can work freely. + + // check the error flag. If there's an error, send an error code. + // otherwise, all data is correct. Send it to the server. + if(isSuccessfulLastInstanceFieldAccess() == false) + { + // send a packet with an error code. + debugChannel.sendReplyWithErrorCode(getErrorCodeForInstanceFieldAccess()); + } + else + { + // great! all operations were done. Send an ack to the server. + debugChannel.sendReply(); + } + } + + /** + * Return the actual object pointer + * @param objectHandle + * @return + */ + private static final int getObjectPointer(int objectHandle) + { + // let's synchronize on the GC to avoid concurrency problems. + synchronized(GC.getMutex()) + { + return Native.rdMem(objectHandle + GC.OFF_PTR); + } + } + + /** + * Return the instance size. + * + * @param handle + * @return + */ + private static final int getObjectSize(int objectHandle) + { + // let's synchronize on the GC to avoid concurrency problems. + synchronized(GC.getMutex()) + { + return Native.rdMem(objectHandle + GC.OFF_SIZE); + } + } + + /** + * Return the method table pointer (or array length if it's an array). + * + * @param handle + * @return + */ + private static final int getMethodTablePointerOrArrayLength(int objectHandle) + { + // let's synchronize on the GC to avoid concurrency problems. + synchronized(GC.getMutex()) + { + return Native.rdMem(objectHandle + GC.OFF_MTAB_ALEN); + } + } + + /** + * Check if the handle control an array object. + * + * @param handle + * @return + */ + private static final boolean isArrayType(int objectHandle) + { + // let's synchronize on the GC to avoid concurrency problems. + synchronized(GC.getMutex()) + { + //return (Native.rdMem(objectHandle + GC.OFF_TYPE) == GC.IS_REFARR); + return (Native.rdMem(objectHandle + GC.OFF_TYPE) == Constants.T_ARRAY); + } + } + + /** * Test to check if some types of packets are being properly * created. * @throws IOException @@ -2251,4 +2633,90 @@ { return shouldPrintInternalMessages; } + + /** + * Print information about one object handle. + * + * @param handle + */ + private static final void printObjectHandle(int handle) + { +// * According to GC class, the handle contains following data: +// * 0 pointer to the object in the heap or 0 when the handle is free +// * 1 pointer to the method table or length of an array +// * 2 size - could be in class info +// * 3 type info: object, primitve array or ref array +// * 4 pointer to next handle of same type (used or free) +// * 5 gray list +// * 6 space marker - either toSpace or fromSpace + + int data, type; + + // let's synchronize on the GC to avoid concurrency problems. + synchronized(GC.getMutex()) + { + System.out.print("Handle content: "); + + for(data = 0; data < 8; data ++) + { + int value = Native.rdMem(handle + data); + EmbeddedOutputStream.printIntHex(value, System.out); + debugPrint(" "); + } + + System.out.println(); + + data = Native.rdMem(handle + GC.OFF_PTR); + type = Native.rdMem(handle + GC.OFF_TYPE); + + if(data == 0) + { + System.out.println("Free handle: "); + System.out.println(handle); + } + else + { + System.out.print("Object pointer: "); + System.out.println(data); + } + + data = Native.rdMem(handle + GC.OFF_MTAB_ALEN); + if(type == GC.IS_OBJ) + { + System.out.print("Method table: "); + System.out.println(data); + } + else + { + System.out.print("Array length: "); + System.out.println(data); + } + + // this is the last access to the handle content. + // close synchronization block and release GC lock. + data = Native.rdMem(handle + GC.OFF_SIZE); + } + + System.out.print("Instance size: "); + System.out.println(data); + + System.out.print("Type: "); + System.out.print(type); + System.out.print(" "); + + if(type == GC.IS_OBJ) + { + System.out.print("Type: Object (not an array) - "); + System.out.println(type); + } + if(type == GC.IS_REFARR) + { + System.out.println("Type: Array"); + System.out.println(type); + } + + // for now, don't print the remaining fields. Not yet necessary. + // if more fields were added, remember to include on the sync block above. + System.out.println(""); + } }

     
    Copyright (c) 1999 OPENCORES.ORG. All rights reserved.