| /* |
| * This file is part of the Jikes RVM project (http://jikesrvm.org). |
| * |
| * This file is licensed to You under the Eclipse Public License (EPL); |
| * You may not use this file except in compliance with the License. You |
| * may obtain a copy of the License at |
| * |
| * http://www.opensource.org/licenses/eclipse-1.0.php |
| * |
| * See the COPYRIGHT.txt file distributed with this work for information |
| * regarding copyright ownership. |
| */ |
| package org.mmtk.utility; |
| |
| import org.mmtk.utility.heap.*; |
| |
| import org.mmtk.vm.VM; |
| |
| import org.vmmagic.unboxed.*; |
| import org.vmmagic.pragma.*; |
| |
| /* |
| import org.jikesrvm.Offset; |
| * Conversions between different units. |
| */ |
| @Uninterruptible public class Conversions implements Constants { |
| |
| // public static Address roundDownVM(Address addr) { |
| // return roundDown(addr.toWord(), VMResource.LOG_BYTES_IN_REGION).toAddress(); |
| // } |
| |
| // public static Extent roundDownVM(Extent bytes) { |
| // return roundDown(bytes.toWord(), VMResource.LOG_BYTES_IN_REGION).toExtent(); |
| // } |
| |
| public static Address roundDownMB(Address addr) { |
| return roundDown(addr.toWord(), LOG_BYTES_IN_MBYTE).toAddress(); |
| } |
| |
| public static Extent roundDownMB(Extent bytes) { |
| return roundDown(bytes.toWord(), LOG_BYTES_IN_MBYTE).toExtent(); |
| } |
| |
| private static Word roundDown(Word value, int logBase) { |
| Word mask = Word.one().lsh(logBase).minus(Word.one()).not(); |
| return value.and(mask); |
| } |
| |
| public static int roundDown(int value, int alignment) { |
| return value & ~(alignment - 1); |
| } |
| |
| // Round up (if necessary) |
| // |
| public static int MBToPages(int megs) { |
| if (LOG_BYTES_IN_PAGE <= LOG_BYTES_IN_MBYTE) |
| return (megs << (LOG_BYTES_IN_MBYTE - LOG_BYTES_IN_PAGE)); |
| else |
| return (megs + ((BYTES_IN_PAGE >>> LOG_BYTES_IN_MBYTE) - 1)) >>> (LOG_BYTES_IN_PAGE - LOG_BYTES_IN_MBYTE); |
| } |
| |
| public static int bytesToMmapChunksUp(Extent bytes) { |
| return bytes.plus(Mmapper.MMAP_CHUNK_BYTES - 1).toWord().rshl(Mmapper.LOG_MMAP_CHUNK_BYTES).toInt(); |
| } |
| |
| public static int pagesToMmapChunksUp(int pages) { |
| return bytesToMmapChunksUp(pagesToBytes(pages)); |
| } |
| |
| public static int addressToMmapChunksDown(Address addr) { |
| Word chunk = addr.toWord().rshl(Mmapper.LOG_MMAP_CHUNK_BYTES); |
| return chunk.toInt(); |
| } |
| |
| public static int addressToPagesDown(Address addr) { |
| Word chunk = addr.toWord().rshl(LOG_BYTES_IN_PAGE); |
| return chunk.toInt(); |
| } |
| |
| public static int addressToPages(Address addr) { |
| int page = addressToPagesDown(addr); |
| if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(pagesToAddress(page).EQ(addr)); |
| return page; |
| } |
| |
| public static Address pagesToAddress(int pages) { |
| return Word.fromIntZeroExtend(pages).lsh(LOG_BYTES_IN_PAGE).toAddress(); |
| } |
| |
| public static int addressToMmapChunksUp(Address addr) { |
| Word chunk = addr.plus(Mmapper.MMAP_CHUNK_BYTES - 1).toWord().rshl(Mmapper.LOG_MMAP_CHUNK_BYTES); |
| return chunk.toInt(); |
| } |
| |
| public static Extent pagesToBytes(int pages) { |
| return Word.fromIntZeroExtend(pages).lsh(LOG_BYTES_IN_PAGE).toExtent(); |
| } |
| |
| public static int pagesToMBytes(int pages) { |
| return pages >> (LOG_BYTES_IN_MBYTE - LOG_BYTES_IN_PAGE); |
| } |
| |
| public static int pagesToKBytes(int pages) { |
| return pages << (LOG_BYTES_IN_PAGE - LOG_BYTES_IN_KBYTE); |
| } |
| |
| /** |
| @deprecated : use int bytesToPagesUp(Extent bytes) if possible |
| */ |
| @Deprecated |
| public static int bytesToPagesUp(int bytes) { |
| return bytesToPagesUp(Extent.fromIntZeroExtend(bytes)); |
| } |
| |
| /** |
| @deprecated : use int bytesToPagesUp(Extent bytes) if possible |
| */ |
| @Deprecated |
| public static int bytesToPages(int bytes) { |
| return bytesToPages(Extent.fromIntZeroExtend(bytes)); |
| } |
| |
| public static int bytesToPagesUp(Extent bytes) { |
| return bytes.plus(BYTES_IN_PAGE-1).toWord().rshl(LOG_BYTES_IN_PAGE).toInt(); |
| } |
| |
| public static int bytesToPages(Extent bytes) { |
| int pages = bytesToPagesUp(bytes); |
| if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(pagesToAddress(pages).toWord().toExtent().EQ(bytes)); |
| return pages; |
| } |
| |
| public static int bytesToPages(Offset bytes) { |
| if (VM.VERIFY_ASSERTIONS) { |
| long val = bytes.toLong(); |
| VM.assertions._assert(val >= MIN_INT && val <= MAX_INT); |
| } |
| if (bytes.sGE(Offset.zero())) |
| return bytesToPagesUp(Extent.fromIntSignExtend(bytes.toInt())); |
| else |
| return -bytesToPagesUp(Extent.fromIntSignExtend(-bytes.toInt())); |
| } |
| |
| public static Address mmapChunksToAddress(int chunk) { |
| return Word.fromIntZeroExtend(chunk).lsh(Mmapper.LOG_MMAP_CHUNK_BYTES).toAddress(); |
| } |
| |
| public static Address pageAlign(Address address) { |
| return address.toWord().rshl(LOG_BYTES_IN_PAGE).lsh(LOG_BYTES_IN_PAGE).toAddress(); |
| } |
| |
| public static int pageAlign(int value) { |
| return (value>>LOG_BYTES_IN_PAGE)<<LOG_BYTES_IN_PAGE; |
| } |
| |
| public static boolean isPageAligned(Address address) { |
| return pageAlign(address).EQ(address); |
| } |
| |
| public static boolean isPageAligned(int value) { |
| return pageAlign(value) == value; |
| } |
| } |