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; 014 015import static org.mmtk.utility.Constants.*; 016 017import org.mmtk.utility.heap.*; 018 019import org.mmtk.vm.VM; 020 021import org.vmmagic.unboxed.*; 022import org.vmmagic.pragma.*; 023 024/* 025 import org.jikesrvm.Offset; 026 * Conversions between different units. 027 */ 028@Uninterruptible public class Conversions { 029 030 // public static Address roundDownVM(Address addr) { 031 // return roundDown(addr.toWord(), VMResource.LOG_BYTES_IN_REGION).toAddress(); 032 // } 033 034 // public static Extent roundDownVM(Extent bytes) { 035 // return roundDown(bytes.toWord(), VMResource.LOG_BYTES_IN_REGION).toExtent(); 036 // } 037 038 public static Address roundDownMB(Address addr) { 039 return roundDown(addr.toWord(), LOG_BYTES_IN_MBYTE).toAddress(); 040 } 041 042 public static Extent roundDownMB(Extent bytes) { 043 return roundDown(bytes.toWord(), LOG_BYTES_IN_MBYTE).toExtent(); 044 } 045 046 private static Word roundDown(Word value, int logBase) { 047 Word mask = Word.one().lsh(logBase).minus(Word.one()).not(); 048 return value.and(mask); 049 } 050 051 public static int roundDown(int value, int alignment) { 052 return value & ~(alignment - 1); 053 } 054 055 // Round up (if necessary) 056 // 057 public static int MBToPages(int megs) { 058 if (LOG_BYTES_IN_PAGE <= LOG_BYTES_IN_MBYTE) 059 return (megs << (LOG_BYTES_IN_MBYTE - LOG_BYTES_IN_PAGE)); 060 else 061 return (megs + ((BYTES_IN_PAGE >>> LOG_BYTES_IN_MBYTE) - 1)) >>> (LOG_BYTES_IN_PAGE - LOG_BYTES_IN_MBYTE); 062 } 063 064 public static int bytesToMmapChunksUp(Extent bytes) { 065 return bytes.plus(Mmapper.MMAP_CHUNK_BYTES - 1).toWord().rshl(Mmapper.LOG_MMAP_CHUNK_BYTES).toInt(); 066 } 067 068 public static int pagesToMmapChunksUp(int pages) { 069 return bytesToMmapChunksUp(pagesToBytes(pages)); 070 } 071 072 public static int addressToMmapChunksDown(Address addr) { 073 Word chunk = addr.toWord().rshl(Mmapper.LOG_MMAP_CHUNK_BYTES); 074 return chunk.toInt(); 075 } 076 077 public static int addressToPagesDown(Address addr) { 078 Word chunk = addr.toWord().rshl(LOG_BYTES_IN_PAGE); 079 return chunk.toInt(); 080 } 081 082 public static int addressToPages(Address addr) { 083 int page = addressToPagesDown(addr); 084 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(pagesToAddress(page).EQ(addr)); 085 return page; 086 } 087 088 public static Address pagesToAddress(int pages) { 089 return Word.fromIntZeroExtend(pages).lsh(LOG_BYTES_IN_PAGE).toAddress(); 090 } 091 092 public static int addressToMmapChunksUp(Address addr) { 093 Word chunk = addr.plus(Mmapper.MMAP_CHUNK_BYTES - 1).toWord().rshl(Mmapper.LOG_MMAP_CHUNK_BYTES); 094 return chunk.toInt(); 095 } 096 097 public static Extent pagesToBytes(int pages) { 098 return Word.fromIntZeroExtend(pages).lsh(LOG_BYTES_IN_PAGE).toExtent(); 099 } 100 101 public static int pagesToMBytes(int pages) { 102 return pages >> (LOG_BYTES_IN_MBYTE - LOG_BYTES_IN_PAGE); 103 } 104 105 public static int pagesToKBytes(int pages) { 106 return pages << (LOG_BYTES_IN_PAGE - LOG_BYTES_IN_KBYTE); 107 } 108 109 public static int bytesToPagesUp(Extent bytes) { 110 return bytes.plus(BYTES_IN_PAGE - 1).toWord().rshl(LOG_BYTES_IN_PAGE).toInt(); 111 } 112 113 public static int bytesToPages(Extent bytes) { 114 int pages = bytesToPagesUp(bytes); 115 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(pagesToAddress(pages).toWord().toExtent().EQ(bytes)); 116 return pages; 117 } 118 119 public static int bytesToPages(Offset bytes) { 120 if (VM.VERIFY_ASSERTIONS) { 121 long val = bytes.toLong(); 122 VM.assertions._assert(val >= MIN_INT && val <= MAX_INT); 123 } 124 if (bytes.sGE(Offset.zero())) 125 return bytesToPagesUp(Extent.fromIntSignExtend(bytes.toInt())); 126 else 127 return -bytesToPagesUp(Extent.fromIntSignExtend(-bytes.toInt())); 128 } 129 130 public static Address mmapChunksToAddress(int chunk) { 131 return Word.fromIntZeroExtend(chunk).lsh(Mmapper.LOG_MMAP_CHUNK_BYTES).toAddress(); 132 } 133 134 public static Address pageAlign(Address address) { 135 return address.toWord().rshl(LOG_BYTES_IN_PAGE).lsh(LOG_BYTES_IN_PAGE).toAddress(); 136 } 137 138 public static int pageAlign(int value) { 139 return (value >> LOG_BYTES_IN_PAGE) << LOG_BYTES_IN_PAGE; 140 } 141 142 public static boolean isPageAligned(Address address) { 143 return pageAlign(address).EQ(address); 144 } 145 146 public static boolean isPageAligned(int value) { 147 return pageAlign(value) == value; 148 } 149}