001 /*
002 * This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 * This file is licensed to You under the Eclipse Public License (EPL);
005 * You may not use this file except in compliance with the License. You
006 * may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 * See the COPYRIGHT.txt file distributed with this work for information
011 * regarding copyright ownership.
012 */
013 package org.jikesrvm.mm.mmtk.gcspy;
014
015 import org.mmtk.utility.Log;
016 import org.mmtk.vm.VM;
017 import org.mmtk.utility.gcspy.GCspy;
018
019 import static org.jikesrvm.runtime.SysCall.sysCall;
020 import org.jikesrvm.objectmodel.JavaHeaderConstants;
021
022 import org.vmmagic.unboxed.*;
023 import org.vmmagic.pragma.*;
024
025 /**
026 * Generic GCspy Server Interpreter
027 *
028 * This class implements the GCspy server.
029 * The server runs as a separate pthread and communicates with GCspy
030 * clients. It handles commands from the client and passes data to it.
031 * Mostly it forwards calls to the C gcspy library.
032 */
033 @Uninterruptible public class ServerInterpreter extends org.mmtk.vm.gcspy.ServerInterpreter
034 implements JavaHeaderConstants {
035
036
037 /**
038 * Create a new ServerInterpreter singleton.
039 * @param name The name of the server
040 * @param port The number of the port on which to communicate
041 * @param verbose Whether the server is to run verbosely
042 */
043 @Interruptible
044 public void init(String name, int port, boolean verbose) {
045 if (org.jikesrvm.VM.BuildWithGCSpy) {
046 if (VM.VERIFY_ASSERTIONS)
047 VM.assertions._assert(!initialised, "Tried to re-init server interpreter");
048 initialised = true;
049
050 if (DEBUG)
051 Log.writeln("-- Initialising main server on port ",port);
052
053 Address tmp = GCspy.util.getBytes(name);
054 server = sysCall.gcspyMainServerInit(port, MAX_LEN, tmp, verbose?1:0);
055
056 if (DEBUG) {
057 Log.writeln("gcspy_main_server_t address = "); Log.writeln(server);
058 }
059
060 GCspy.util.free(tmp);
061 // Set up the list of ServerSpaces
062 spaces = new org.jikesrvm.mm.mmtk.gcspy.ServerSpace[MAX_SPACES];
063 }
064 }
065
066 /**
067 * Add an event to the ServerInterpreter.
068 * @param num the event number
069 * @param name the event name
070 */
071 public void addEvent(int num, String name) {
072 if (org.jikesrvm.VM.BuildWithGCSpy) {
073 if (VM.VERIFY_ASSERTIONS)
074 VM.assertions._assert(initialised,
075 "ServerInterpreter.addEvent: server not initiialised");
076
077 Address tmp = GCspy.util.getBytes(name);
078 sysCall.gcspyMainServerAddEvent(server, num, tmp);
079 GCspy.util.free(tmp);
080 }
081 }
082
083 /**
084 * Set the general info for the ServerInterpreter.
085 * @param info the information
086 */
087 public void setGeneralInfo(String info) {
088 if (org.jikesrvm.VM.BuildWithGCSpy) {
089 if (VM.VERIFY_ASSERTIONS)
090 VM.assertions._assert(initialised,
091 "ServerInterpreter.setGeneralInfo: server not initiialised");
092
093 Address tmp = GCspy.util.getBytes(info);
094 sysCall.gcspyMainServerSetGeneralInfo(server, tmp);
095 GCspy.util.free(tmp);
096 }
097 }
098
099 /**
100 * Start the server, running its main loop in a pthread.
101 * @param wait Whether to wait for the client to connect
102 */
103 public void startServer(boolean wait) {
104 if (org.jikesrvm.VM.BuildWithGCSpy) {
105 if (DEBUG) { Log.write("Starting GCSpy server, wait="); Log.writeln(wait); }
106
107 Address serverOuterLoop = sysCall.gcspyMainServerOuterLoop();
108 sysCall.gcspyStartserver(server, wait?1:0, serverOuterLoop);
109 }
110 }
111
112 /**
113 * Are we connected to a GCspy client?
114 * @param event The current event
115 * @return true if we are connected
116 */
117 public boolean isConnected(int event) {
118 if (org.jikesrvm.VM.BuildWithGCSpy) {
119 if (DEBUG)
120 Log.writeln("ServerInterpreter.isConnected, server=", server);
121
122 if (!initialised)
123 return false;
124 int res = sysCall.gcspyMainServerIsConnected(server, event);
125 return (res != 0);
126 } else {
127 return false;
128 }
129 }
130
131 /**
132 * Start compensation timer so that time spent gathering data is
133 * not confused with the time spent in the application and the VM.
134 */
135 public void startCompensationTimer() {
136 if (org.jikesrvm.VM.BuildWithGCSpy) {
137 if (VM.VERIFY_ASSERTIONS)
138 VM.assertions._assert(initialised,
139 "ServerInterpreter.startCompensationTimer: server not initiialised");
140
141 sysCall.gcspyMainServerStartCompensationTimer(server);
142 }
143 }
144
145 /**
146 * Stop compensation timer so that time spent gathering data is
147 * not confused with the time spent in the application and the VM.r
148 */
149 public void stopCompensationTimer() {
150 if (org.jikesrvm.VM.BuildWithGCSpy) {
151 if (VM.VERIFY_ASSERTIONS)
152 VM.assertions._assert(initialised,
153 "ServerInterpreter.stopCompensationTimer: server not initiialised");
154
155 sysCall.gcspyMainServerStopCompensationTimer(server);
156 }
157 }
158
159 /**
160 * Indicate that we are at a server safe point (e.g. the end of a GC).
161 * This is a point at which the server can pause, play one, etc.
162 * @param event The current event
163 */
164 public void serverSafepoint(int event) {
165 if (org.jikesrvm.VM.BuildWithGCSpy) {
166 if (DEBUG)
167 Log.writeln("ServerInterpreter.serverSafepoint, server=", server);
168
169 if (!initialised)
170 return;
171 sysCall.gcspyMainServerSafepoint(server, event);
172 }
173 }
174
175 /**
176 * Discover the smallest header size for objects.
177 * @return the size in bytes
178 */
179 public int computeHeaderSize() {
180 return JAVA_HEADER_BYTES+OTHER_HEADER_BYTES;
181 }
182 }