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 */
013package org.mmtk.vm.gcspy;
014
015import org.vmmagic.pragma.*;
016import 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() {
062    return server;
063  }
064
065  /**
066   * Add a GCspy ServerSpace to the ServerInterpreter.
067   * This method returns a unique space ID for the ServerSpace
068   * (again used in calls to the C library).
069   *
070   * @param space the ServerSpace to add
071   * @return a unique id for this space
072   * @exception IndexOutOfBoundsException on attempt to add more than
073   * MAX_SPACES spaces
074   */
075  @Interruptible
076  public int addSpace(ServerSpace space) {
077    int id = 0;
078    while (id < MAX_SPACES) {
079      if (spaces[id] == null) {
080        spaces[id] = space;
081        return id;
082      }
083      id++;
084    }
085    throw new IndexOutOfBoundsException(
086        "Too many spaces to add to interpreter.\nSet MAX_SPACES to higher value in ServerInterpreter.");
087  }
088
089  /**
090   * Start the server, running its main loop in a pthread.
091   * @param wait Whether to wait for the client to connect
092   */
093  public abstract void startServer(boolean wait);
094
095  /**
096   * Are we connected to a GCspy client?
097   * @param event The current event
098   * @return {@code true} if we are connected
099   */
100  public abstract boolean isConnected(int event);
101
102  /**
103   * Start compensation timer so that time spent gathering data is
104   * not confused with the time spent in the application and the VM.
105   */
106  public abstract void startCompensationTimer();
107
108  /**
109   * Stop compensation timer so that time spent gathering data is
110   * not confused with the time spent in the application and the VM.r
111   */
112  public abstract void stopCompensationTimer();
113
114  /**
115   * Indicate that we are at a server safe point (e.g. the end of a GC).
116   * This is a point at which the server can pause, play one, etc.
117   * @param event The current event
118   */
119  public abstract void serverSafepoint(int event);
120
121  /**
122   * Discover the smallest header size for objects.
123   * @return the size in bytes
124   */
125  public abstract int computeHeaderSize();
126}