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