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.jikesrvm.mm.mmtk.gcspy;
014
015import org.mmtk.utility.Log;
016import static org.jikesrvm.runtime.SysCall.sysCall;
017import org.jikesrvm.VM;
018import org.mmtk.utility.gcspy.GCspy;
019import org.mmtk.utility.gcspy.drivers.AbstractDriver;
020
021import org.vmmagic.unboxed.*;
022import org.vmmagic.pragma.*;
023
024/**
025 * This class implements the GCspy Space abstraction.
026 * Here, it largely to forward calls to the gcspy C library.
027 */
028@Uninterruptible public class ServerSpace extends org.mmtk.vm.gcspy.ServerSpace {
029
030  /**
031   * Create a new GCspy Space
032   *
033   * @param serverInterpreter The server that owns this space
034   * @param serverName The server's name
035   * @param driverName The space driver's name
036   * @param title Title for the space
037   * @param blockInfo A label for each block
038   * @param tileNum Max number of tiles in this space
039   * @param unused A label for unused blocks
040   * @param mainSpace Whether this space is the main space
041   */
042  public ServerSpace(
043              org.mmtk.vm.gcspy.ServerInterpreter serverInterpreter,
044              String serverName,
045              String driverName,
046              String title,
047              String blockInfo,
048              int tileNum,
049              String unused,
050              boolean mainSpace) {
051    if (VM.BuildWithGCSpy) {
052      spaceId = serverInterpreter.addSpace(this);
053      driver = sysCall.gcspyMainServerAddDriver(serverInterpreter.getServerAddress());
054
055      // Convert Strings to char *
056      Address serverNameAddr = GCspy.util.getBytes(serverName);
057      Address driverNameAddr = GCspy.util.getBytes(driverName);
058      Address titleAddr      = GCspy.util.getBytes(title);
059      Address blockInfoAddr  = GCspy.util.getBytes(blockInfo);
060      Address unusedAddr     = GCspy.util.getBytes((unused == null) ? DEFAULT_UNUSED_STRING : unused);
061
062      // Add the driver to the server and initialise it
063      if (DEBUG) Log.writeln("--   Setting up driver");
064      sysCall.gcspyDriverInit(driver, -1, serverNameAddr, driverNameAddr,
065                                 titleAddr, blockInfoAddr, tileNum,
066                                 unusedAddr, mainSpace ? 1 : 0);
067    }
068  }
069
070
071  /****************************************************************************
072   *
073   * Interface to the GCspy C library
074   */
075
076
077  /**
078   * {@inheritDoc}
079   */
080  @Override
081  public void setTilename(int i, Address start, Address end) {
082    if (VM.BuildWithGCSpy)
083      sysCall.gcspyDriverSetTileNameRange(driver, i, start, end);
084  }
085
086  @Override
087  public void setTilename(int i, Address format, long value) {
088    if (VM.BuildWithGCSpy)
089      sysCall.gcspyDriverSetTileName(driver, i, format, value);
090  }
091
092  @Override
093  public void setTilename(int i, String format, long value) {
094    if (VM.BuildWithGCSpy) {
095      Address tileName = GCspy.util.getBytes(format);
096      setTilename(i, tileName, value);
097      GCspy.util.free(tileName);
098    }
099  }
100
101  @Override
102  public void resize(int size) {
103    if (VM.BuildWithGCSpy)
104      sysCall.gcspyDriverResize(driver, size);
105  }
106
107  @Override
108  public void startCommunication() {
109    if (VM.BuildWithGCSpy)
110      sysCall.gcspyDriverStartComm(driver);
111  }
112
113  @Override
114  public Address addStream(int streamId) {
115    if (VM.BuildWithGCSpy)
116      return sysCall.gcspyDriverAddStream(driver, streamId);
117    else
118      return Address.zero();
119  }
120
121  @Override
122  public void stream(int streamId, int len) {
123    if (VM.BuildWithGCSpy)
124      sysCall.gcspyDriverStream(driver, streamId, len);
125  }
126
127  @Override
128  public void streamByteValue(byte value) {
129    if (VM.BuildWithGCSpy)
130      sysCall.gcspyDriverStreamByteValue(driver, value);
131  }
132
133  @Override
134  public void streamShortValue(short value) {
135    if (VM.BuildWithGCSpy)
136      sysCall.gcspyDriverStreamShortValue(driver, value);
137  }
138
139  @Override
140  public void streamIntValue(int value) {
141    if (VM.BuildWithGCSpy)
142      sysCall.gcspyDriverStreamIntValue(driver, value);
143  }
144
145  @Override
146  public void streamEnd() {
147    if (VM.BuildWithGCSpy)
148      sysCall.gcspyDriverEndOutput(driver);
149  }
150
151  @Override
152  public void summary(int streamId, int len) {
153    if (VM.BuildWithGCSpy)
154      sysCall.gcspyDriverSummary(driver, streamId, len);
155  }
156
157  @Override
158  public void summaryValue(int val) {
159    sysCall.gcspyDriverSummaryValue(driver, val);
160  }
161
162  @Override
163  public void summaryEnd() {
164    if (VM.BuildWithGCSpy)
165      sysCall.gcspyDriverEndOutput(driver);
166  }
167
168  @Override
169  public void sendControls(AbstractDriver space, int tileNum) {
170    // start the stream
171    if (VM.BuildWithGCSpy) {
172      sysCall.gcspyDriverInitOutput(driver);
173      sysCall.gcspyIntWriteControl(
174                              driver/* NOTE driver->interpreter in sys.C*/,
175                              spaceId,
176                              tileNum);
177
178      // send a control for each tile
179      for (int i = 0; i < tileNum; ++i)
180        streamByteValue(space.getControl(i));
181
182      // end the stream
183      sysCall.gcspyDriverEndOutput(driver);
184    }
185  }
186
187  @Override
188  public void spaceInfo(Address info) {
189    if (VM.BuildWithGCSpy)
190      sysCall.gcspyDriverSpaceInfo(driver, info);
191  }
192}