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.utility.alloc;
014
015import static org.mmtk.utility.Constants.LOG_BYTES_IN_PAGE;
016
017import org.vmmagic.unboxed.*;
018import org.vmmagic.pragma.*;
019
020/**
021 * This plan implements constants and access methods for meta data
022 * that is embedded in allocation spaces (rather than kept on the
023 * side).  The basic idea is that meta data be embedded at a very
024 * coarse power of two granularity for fast access, minimal wastage
025 * and by making the regions coarse, the contiguous meta-data will be
026 * relatively large and thus the probability of L1 conflict misses
027 * will be reduced (as compared with embedding meta-data at the start
028 * of each page which will cause those few cache lines corresponding
029 * to the start of each page to be heavily conflicted).
030 */
031@Uninterruptible
032public final class EmbeddedMetaData {
033
034  /* The (log of the) size of each region of meta data management */
035  public static final int LOG_BYTES_IN_REGION = 22;
036  public static final int BYTES_IN_REGION = 1 << LOG_BYTES_IN_REGION;
037  private static final Word REGION_MASK = Word.fromIntSignExtend(BYTES_IN_REGION - 1);
038  public static final int LOG_PAGES_IN_REGION = LOG_BYTES_IN_REGION - LOG_BYTES_IN_PAGE;
039  public static final int PAGES_IN_REGION = 1 << LOG_PAGES_IN_REGION;
040
041  /**
042   * Given an address, return the beginning of the meta data for the
043   * region containing the address.  This is a fast operation because
044   * it only involves masking out low order bits.
045   *
046   * @param address The address whose meta data is sought.
047   * @return The address of the start of the meta data for the meta
048   * region in which the address is located.
049   */
050  @Inline
051  public static Address getMetaDataBase(Address address) {
052    return address.toWord().and(REGION_MASK.not()).toAddress();
053  }
054
055  /**
056   * Given an address, the density (coverage) of a meta data type, and
057   * the granularity (alignment) of the meta data, return the offset
058   * into the meta data the address.
059   *
060   * @param address The address whose meta data offset is sought.
061   * @param logCoverage The log base two of the coverage of the meta
062   * data in question. For example, a value of 4 would indicate a
063   * coverage of 16; one metadata byte for every 16 bytes of data.
064   * @param logAlign The log base two of the alignment or granularity
065   * of the meta-data (it may be arranged in bytes, words, double
066   * words etc).
067   * @return The offset into the meta-data for this region, given the
068   * specified address and coverage and alignment requirements.
069   */
070  public static Extent getMetaDataOffset(Address address,
071                                                  int logCoverage,
072                                                  int logAlign) {
073    return address.toWord().and(REGION_MASK).rshl(logCoverage + logAlign).lsh(logAlign).toExtent();
074  }
075}