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.mmtk.vm.gcspy;
014
015 import org.vmmagic.pragma.*;
016 import org.vmmagic.unboxed.Address;
017
018 /**
019 * Abstract class for the GCspy server interpreter<p>
020 *
021 * Implementing classes will mostly forward calls to the C gcspy library.
022 */
023 @Uninterruptible public abstract class ServerInterpreter {
024
025 protected static final int MAX_LEN = 64 * 1024; // Buffer size
026 protected static final int MAX_SPACES = 32; // Maximum number of spaces
027 protected static boolean initialised = false;
028
029 protected ServerSpace[] spaces; // The server's spaces
030 protected Address server; // a pointer to the c server, gcspy_main_server_t server
031
032 protected static final boolean DEBUG = false;
033
034 /**
035 * Create a new ServerInterpreter singleton.
036 * @param name The name of the server
037 * @param port The number of the port on which to communicate
038 * @param verbose Whether the server is to run verbosely
039 */
040 @Interruptible
041 public abstract void init(String name, int port, boolean verbose);
042
043 /**
044 * Add an event to the ServerInterpreter.
045 * @param num the event number
046 * @param name the event name
047 */
048 public abstract void addEvent(int num, String name);
049
050 /**
051 * Set the general info for the ServerInterpreter.
052 * @param info the information
053 */
054 public abstract void setGeneralInfo(String info);
055
056 /**
057 * Get a pointer to the C server, gcspy_main_server_t.
058 * This address is used in all calls to the server in the C library.
059 * @return the address of the server
060 */
061 public Address getServerAddress() { return server; }
062
063 /**
064 * Add a GCspy ServerSpace to the ServerInterpreter.
065 * This method returns a unique space ID for the ServerSpace
066 * (again used in calls to the C library).
067 *
068 * @param space the ServerSpace to add
069 * @return a unique id for this space
070 * @exception IndexOutOfBoundsException on attempt to add more than
071 * MAX_SPACES spaces
072 */
073 @Interruptible
074 public int addSpace(ServerSpace space) {
075 int id = 0;
076 while (id < MAX_SPACES) {
077 if (spaces[id] == null) {
078 spaces[id] = space;
079 return id;
080 }
081 id++;
082 }
083 throw new IndexOutOfBoundsException(
084 "Too many spaces to add to interpreter.\nSet MAX_SPACES to higher value in ServerInterpreter.");
085 }
086
087 /**
088 * Start the server, running its main loop in a pthread.
089 * @param wait Whether to wait for the client to connect
090 */
091 public abstract void startServer(boolean wait);
092
093 /**
094 * Are we connected to a GCspy client?
095 * @param event The current event
096 * @return {@code true} if we are connected
097 */
098 public abstract boolean isConnected(int event);
099
100 /**
101 * Start compensation timer so that time spent gathering data is
102 * not confused with the time spent in the application and the VM.
103 */
104 public abstract void startCompensationTimer();
105
106 /**
107 * Stop compensation timer so that time spent gathering data is
108 * not confused with the time spent in the application and the VM.r
109 */
110 public abstract void stopCompensationTimer();
111
112 /**
113 * Indicate that we are at a server safe point (e.g. the end of a GC).
114 * This is a point at which the server can pause, play one, etc.
115 * @param event The current event
116 */
117 public abstract void serverSafepoint(int event);
118
119 /**
120 * Discover the smallest header size for objects.
121 * @return the size in bytes
122 */
123 public abstract int computeHeaderSize();
124 }