/** {@inheritDoc} */
  protected void getNewMonitors(Map<String, Monitor> map) throws MonitorException {
    assert Thread.holdsLock(this);

    int used = prologue.getUsed();
    long modificationTime = prologue.getModificationTimeStamp();

    if ((used > lastUsed) || (lastModificationTime > modificationTime)) {

      lastUsed = used;
      lastModificationTime = modificationTime;

      Monitor monitor = getNextMonitorEntry();
      while (monitor != null) {
        String name = monitor.getName();

        // guard against duplicate entries
        if (!map.containsKey(name)) {
          map.put(name, monitor);

          /*
           * insertedMonitors is null when called from pollFor()
           * via buildMonitorMap(). Since we update insertedMonitors
           * at the end of buildMonitorMap(), it's ok to skip the
           * add here.
           */
          if (insertedMonitors != null) {
            insertedMonitors.add(monitor);
          }
        }
        monitor = getNextMonitorEntry();
      }
    }
  }
  /** {@inheritDoc} */
  protected void buildMonitorMap(Map<String, Monitor> map) throws MonitorException {
    assert Thread.holdsLock(this);

    // start at the beginning of the buffer
    buffer.rewind();

    // create pseudo monitors
    buildPseudoMonitors(map);

    // position buffer to start of the data section
    buffer.position(prologue.getSize());
    nextEntry = buffer.position();
    perfDataItem = 0;

    int used = prologue.getUsed();
    long modificationTime = prologue.getModificationTimeStamp();

    Monitor m = getNextMonitorEntry();
    while (m != null) {
      map.put(m.getName(), m);
      m = getNextMonitorEntry();
    }

    /*
     * set the last modification data. These are set to the values
     * recorded before parsing the data structure. This allows the
     * the data structure to be modified while the Map is being built.
     * The Map may contain more entries than indicated based on the
     * time stamp, but this is handled by ignoring duplicate entries
     * when the Map is updated in getNewMonitors().
     */
    lastUsed = used;
    lastModificationTime = modificationTime;

    // synchronize with the target jvm
    synchWithTarget(map);

    // work around 1.4.2 counter inititization bugs
    kludge(map);

    insertedMonitors = new ArrayList<Monitor>(map.values());
  }
  /** Build the pseudo monitors used to map the prolog data into counters. */
  protected void buildPseudoMonitors(Map<String, Monitor> map) {
    Monitor monitor = null;
    String name = null;
    IntBuffer ib = null;

    name = PerfDataBufferPrologue.PERFDATA_MAJOR_NAME;
    ib = prologue.majorVersionBuffer();
    monitor = new PerfIntegerMonitor(name, Units.NONE, Variability.CONSTANT, false, ib);
    map.put(name, monitor);

    name = PerfDataBufferPrologue.PERFDATA_MINOR_NAME;
    ib = prologue.minorVersionBuffer();
    monitor = new PerfIntegerMonitor(name, Units.NONE, Variability.CONSTANT, false, ib);
    map.put(name, monitor);

    name = PerfDataBufferPrologue.PERFDATA_BUFFER_SIZE_NAME;
    ib = prologue.sizeBuffer();
    monitor = new PerfIntegerMonitor(name, Units.BYTES, Variability.MONOTONIC, false, ib);
    map.put(name, monitor);

    name = PerfDataBufferPrologue.PERFDATA_BUFFER_USED_NAME;
    ib = prologue.usedBuffer();
    monitor = new PerfIntegerMonitor(name, Units.BYTES, Variability.MONOTONIC, false, ib);
    map.put(name, monitor);

    name = PerfDataBufferPrologue.PERFDATA_OVERFLOW_NAME;
    ib = prologue.overflowBuffer();
    monitor = new PerfIntegerMonitor(name, Units.BYTES, Variability.MONOTONIC, false, ib);
    map.put(name, monitor);
    this.overflow = (IntegerMonitor) monitor;

    name = PerfDataBufferPrologue.PERFDATA_MODTIMESTAMP_NAME;
    LongBuffer lb = prologue.modificationTimeStampBuffer();
    monitor = new PerfLongMonitor(name, Units.TICKS, Variability.MONOTONIC, false, lb);
    map.put(name, monitor);
  }
 /**
  * Construct a PerfDataBufferImpl instance.
  *
  * <p>This class is dynamically loaded by {@link AbstractPerfDataBuffer#createPerfDataBuffer}, and
  * this constructor is called to instantiate the instance.
  *
  * @param buffer the buffer containing the instrumentation data
  * @param lvmid the Local Java Virtual Machine Identifier for this instrumentation buffer.
  */
 public PerfDataBuffer(ByteBuffer buffer, int lvmid) throws MonitorException {
   super(buffer, lvmid);
   prologue = new PerfDataBufferPrologue(buffer);
   this.buffer.order(prologue.getByteOrder());
 }