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.utility.alloc;
014    
015    import org.mmtk.utility.Constants;
016    
017    import org.vmmagic.unboxed.*;
018    import 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
032    public final class EmbeddedMetaData implements Constants {
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    }