/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.jikesrvm.mm.mmtk.gcspy; import org.mmtk.utility.Log; import org.mmtk.vm.VM; import org.mmtk.utility.gcspy.GCspy; import static org.jikesrvm.runtime.SysCall.sysCall; import org.jikesrvm.objectmodel.JavaHeaderConstants; import org.vmmagic.unboxed.*; import org.vmmagic.pragma.*; /** * Generic GCspy Server Interpreter * * This class implements the GCspy server. * The server runs as a separate pthread and communicates with GCspy * clients. It handles commands from the client and passes data to it. * Mostly it forwards calls to the C gcspy library. */ @Uninterruptible public class ServerInterpreter extends org.mmtk.vm.gcspy.ServerInterpreter implements JavaHeaderConstants { /** * Create a new ServerInterpreter singleton. * @param name The name of the server * @param port The number of the port on which to communicate * @param verbose Whether the server is to run verbosely */ @Interruptible public void init(String name, int port, boolean verbose) { if (org.jikesrvm.VM.BuildWithGCSpy) { if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!initialised, "Tried to re-init server interpreter"); initialised = true; if (DEBUG) Log.writeln("-- Initialising main server on port ",port); Address tmp = GCspy.util.getBytes(name); server = sysCall.gcspyMainServerInit(port, MAX_LEN, tmp, verbose?1:0); if (DEBUG) { Log.writeln("gcspy_main_server_t address = "); Log.writeln(server); } GCspy.util.free(tmp); // Set up the list of ServerSpaces spaces = new org.jikesrvm.mm.mmtk.gcspy.ServerSpace[MAX_SPACES]; } } /** * Add an event to the ServerInterpreter. * @param num the event number * @param name the event name */ public void addEvent(int num, String name) { if (org.jikesrvm.VM.BuildWithGCSpy) { if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(initialised, "ServerInterpreter.addEvent: server not initiialised"); Address tmp = GCspy.util.getBytes(name); sysCall.gcspyMainServerAddEvent(server, num, tmp); GCspy.util.free(tmp); } } /** * Set the general info for the ServerInterpreter. * @param info the information */ public void setGeneralInfo(String info) { if (org.jikesrvm.VM.BuildWithGCSpy) { if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(initialised, "ServerInterpreter.setGeneralInfo: server not initiialised"); Address tmp = GCspy.util.getBytes(info); sysCall.gcspyMainServerSetGeneralInfo(server, tmp); GCspy.util.free(tmp); } } /** * Start the server, running its main loop in a pthread. * @param wait Whether to wait for the client to connect */ public void startServer(boolean wait) { if (org.jikesrvm.VM.BuildWithGCSpy) { if (DEBUG) { Log.write("Starting GCSpy server, wait="); Log.writeln(wait); } Address serverOuterLoop = sysCall.gcspyMainServerOuterLoop(); sysCall.gcspyStartserver(server, wait?1:0, serverOuterLoop); } } /** * Are we connected to a GCspy client? * @param event The current event * @return true if we are connected */ public boolean isConnected(int event) { if (org.jikesrvm.VM.BuildWithGCSpy) { if (DEBUG) Log.writeln("ServerInterpreter.isConnected, server=", server); if (!initialised) return false; int res = sysCall.gcspyMainServerIsConnected(server, event); return (res != 0); } else { return false; } } /** * Start compensation timer so that time spent gathering data is * not confused with the time spent in the application and the VM. */ public void startCompensationTimer() { if (org.jikesrvm.VM.BuildWithGCSpy) { if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(initialised, "ServerInterpreter.startCompensationTimer: server not initiialised"); sysCall.gcspyMainServerStartCompensationTimer(server); } } /** * Stop compensation timer so that time spent gathering data is * not confused with the time spent in the application and the VM.r */ public void stopCompensationTimer() { if (org.jikesrvm.VM.BuildWithGCSpy) { if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(initialised, "ServerInterpreter.stopCompensationTimer: server not initiialised"); sysCall.gcspyMainServerStopCompensationTimer(server); } } /** * Indicate that we are at a server safe point (e.g. the end of a GC). * This is a point at which the server can pause, play one, etc. * @param event The current event */ public void serverSafepoint(int event) { if (org.jikesrvm.VM.BuildWithGCSpy) { if (DEBUG) Log.writeln("ServerInterpreter.serverSafepoint, server=", server); if (!initialised) return; sysCall.gcspyMainServerSafepoint(server, event); } } /** * Discover the smallest header size for objects. * @return the size in bytes */ public int computeHeaderSize() { return JAVA_HEADER_BYTES+OTHER_HEADER_BYTES; } }