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 }