annotate agent/src/share/classes/sun/jvm/hotspot/debugger/PageCache.java @ 1913:3b2dea75431e

6984311: JSR 292 needs optional bootstrap method parameters Summary: Allow CONSTANT_InvokeDynamic nodes to have any number of extra operands. Reviewed-by: twisti
author jrose
date Sat, 30 Oct 2010 13:08:23 -0700
parents c18cbe5936b8
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
2 * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 package sun.jvm.hotspot.debugger;
a61af66fc99e Initial load
duke
parents:
diff changeset
26
a61af66fc99e Initial load
duke
parents:
diff changeset
27 /** This class implements an LRU page-level cache of configurable page
a61af66fc99e Initial load
duke
parents:
diff changeset
28 size and number of pages. It is configured with a PageFetcher
a61af66fc99e Initial load
duke
parents:
diff changeset
29 which enables it to transparently satisfy requests which span
a61af66fc99e Initial load
duke
parents:
diff changeset
30 multiple pages when one or more of those pages is not in the
a61af66fc99e Initial load
duke
parents:
diff changeset
31 cache. It is generic enough to be sharable among debugger
a61af66fc99e Initial load
duke
parents:
diff changeset
32 implementations. */
a61af66fc99e Initial load
duke
parents:
diff changeset
33
a61af66fc99e Initial load
duke
parents:
diff changeset
34 import sun.jvm.hotspot.utilities.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
35
a61af66fc99e Initial load
duke
parents:
diff changeset
36 public class PageCache {
a61af66fc99e Initial load
duke
parents:
diff changeset
37 /** The pageSize must be a power of two and implicitly specifies the
a61af66fc99e Initial load
duke
parents:
diff changeset
38 alignment of pages. numPages specifies how many pages should be
a61af66fc99e Initial load
duke
parents:
diff changeset
39 cached. */
a61af66fc99e Initial load
duke
parents:
diff changeset
40 public PageCache(long pageSize,
a61af66fc99e Initial load
duke
parents:
diff changeset
41 long maxNumPages,
a61af66fc99e Initial load
duke
parents:
diff changeset
42 PageFetcher fetcher) {
a61af66fc99e Initial load
duke
parents:
diff changeset
43 checkPageInfo(pageSize, maxNumPages);
a61af66fc99e Initial load
duke
parents:
diff changeset
44 this.pageSize = pageSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
45 this.maxNumPages = maxNumPages;
a61af66fc99e Initial load
duke
parents:
diff changeset
46 this.fetcher = fetcher;
a61af66fc99e Initial load
duke
parents:
diff changeset
47 addressToPageMap = new LongHashMap();
a61af66fc99e Initial load
duke
parents:
diff changeset
48 enabled = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
49 }
a61af66fc99e Initial load
duke
parents:
diff changeset
50
a61af66fc99e Initial load
duke
parents:
diff changeset
51 /** This handles fetches which span multiple pages by virtue of the
a61af66fc99e Initial load
duke
parents:
diff changeset
52 presence of the PageFetcher. Throws UnmappedAddressException if
a61af66fc99e Initial load
duke
parents:
diff changeset
53 a page on which data was requested was unmapped. This can not
a61af66fc99e Initial load
duke
parents:
diff changeset
54 really handle numBytes > 32 bits. */
a61af66fc99e Initial load
duke
parents:
diff changeset
55 public synchronized byte[] getData(long startAddress, long numBytes)
a61af66fc99e Initial load
duke
parents:
diff changeset
56 throws UnmappedAddressException {
a61af66fc99e Initial load
duke
parents:
diff changeset
57 byte[] data = new byte[(int) numBytes];
a61af66fc99e Initial load
duke
parents:
diff changeset
58 long numRead = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
59
a61af66fc99e Initial load
duke
parents:
diff changeset
60 while (numBytes > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
61 long pageBaseAddress = startAddress & pageMask;
a61af66fc99e Initial load
duke
parents:
diff changeset
62 // Look up this page
a61af66fc99e Initial load
duke
parents:
diff changeset
63 Page page = checkPage(getPage(pageBaseAddress), startAddress);
a61af66fc99e Initial load
duke
parents:
diff changeset
64 // Figure out how many bytes to read from this page
a61af66fc99e Initial load
duke
parents:
diff changeset
65 long pageOffset = startAddress - pageBaseAddress;
a61af66fc99e Initial load
duke
parents:
diff changeset
66 long numBytesFromPage = Math.min(pageSize - pageOffset, numBytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
67 // Read them starting at the appropriate offset in the
a61af66fc99e Initial load
duke
parents:
diff changeset
68 // destination buffer
a61af66fc99e Initial load
duke
parents:
diff changeset
69 page.getDataAsBytes(startAddress, numBytesFromPage, data, numRead);
a61af66fc99e Initial load
duke
parents:
diff changeset
70 // Increment offsets
a61af66fc99e Initial load
duke
parents:
diff changeset
71 numRead += numBytesFromPage;
a61af66fc99e Initial load
duke
parents:
diff changeset
72 numBytes -= numBytesFromPage;
a61af66fc99e Initial load
duke
parents:
diff changeset
73 startAddress += numBytesFromPage;
a61af66fc99e Initial load
duke
parents:
diff changeset
74 }
a61af66fc99e Initial load
duke
parents:
diff changeset
75
a61af66fc99e Initial load
duke
parents:
diff changeset
76 return data;
a61af66fc99e Initial load
duke
parents:
diff changeset
77 }
a61af66fc99e Initial load
duke
parents:
diff changeset
78
a61af66fc99e Initial load
duke
parents:
diff changeset
79 public synchronized boolean getBoolean(long address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
80 return (getByte(address) != 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
81 }
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 public synchronized byte getByte(long address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
84 return checkPage(getPage(address & pageMask), address).getByte(address);
a61af66fc99e Initial load
duke
parents:
diff changeset
85 }
a61af66fc99e Initial load
duke
parents:
diff changeset
86
a61af66fc99e Initial load
duke
parents:
diff changeset
87 public synchronized short getShort(long address, boolean bigEndian) {
a61af66fc99e Initial load
duke
parents:
diff changeset
88 return checkPage(getPage(address & pageMask), address).getShort(address, bigEndian);
a61af66fc99e Initial load
duke
parents:
diff changeset
89 }
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 public synchronized char getChar(long address, boolean bigEndian) {
a61af66fc99e Initial load
duke
parents:
diff changeset
92 return checkPage(getPage(address & pageMask), address).getChar(address, bigEndian);
a61af66fc99e Initial load
duke
parents:
diff changeset
93 }
a61af66fc99e Initial load
duke
parents:
diff changeset
94
a61af66fc99e Initial load
duke
parents:
diff changeset
95 public synchronized int getInt(long address, boolean bigEndian) {
a61af66fc99e Initial load
duke
parents:
diff changeset
96 return checkPage(getPage(address & pageMask), address).getInt(address, bigEndian);
a61af66fc99e Initial load
duke
parents:
diff changeset
97 }
a61af66fc99e Initial load
duke
parents:
diff changeset
98
a61af66fc99e Initial load
duke
parents:
diff changeset
99 public synchronized long getLong(long address, boolean bigEndian) {
a61af66fc99e Initial load
duke
parents:
diff changeset
100 return checkPage(getPage(address & pageMask), address).getLong(address, bigEndian);
a61af66fc99e Initial load
duke
parents:
diff changeset
101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
102
a61af66fc99e Initial load
duke
parents:
diff changeset
103 public synchronized float getFloat(long address, boolean bigEndian) {
a61af66fc99e Initial load
duke
parents:
diff changeset
104 return checkPage(getPage(address & pageMask), address).getFloat(address, bigEndian);
a61af66fc99e Initial load
duke
parents:
diff changeset
105 }
a61af66fc99e Initial load
duke
parents:
diff changeset
106
a61af66fc99e Initial load
duke
parents:
diff changeset
107 public synchronized double getDouble(long address, boolean bigEndian) {
a61af66fc99e Initial load
duke
parents:
diff changeset
108 return checkPage(getPage(address & pageMask), address).getDouble(address, bigEndian);
a61af66fc99e Initial load
duke
parents:
diff changeset
109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
110
a61af66fc99e Initial load
duke
parents:
diff changeset
111 /** A mechanism for clearing cached data covering the given region */
a61af66fc99e Initial load
duke
parents:
diff changeset
112 public synchronized void clear(long startAddress, long numBytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
113 long pageBaseAddress = startAddress & pageMask;
a61af66fc99e Initial load
duke
parents:
diff changeset
114 long endAddress = startAddress + numBytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
115 while (pageBaseAddress < endAddress) {
a61af66fc99e Initial load
duke
parents:
diff changeset
116 flushPage(pageBaseAddress);
a61af66fc99e Initial load
duke
parents:
diff changeset
117 pageBaseAddress += pageSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
118 }
a61af66fc99e Initial load
duke
parents:
diff changeset
119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
120
a61af66fc99e Initial load
duke
parents:
diff changeset
121 /** A mechanism for clearing out the cache is necessary to handle
a61af66fc99e Initial load
duke
parents:
diff changeset
122 detaching and reattaching */
a61af66fc99e Initial load
duke
parents:
diff changeset
123 public synchronized void clear() {
a61af66fc99e Initial load
duke
parents:
diff changeset
124 // Should probably break next/prev links in list as well
a61af66fc99e Initial load
duke
parents:
diff changeset
125 addressToPageMap.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
126 lruList = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
127 numPages = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
129
a61af66fc99e Initial load
duke
parents:
diff changeset
130 /** Disables the page cache; no further pages will be added to the
a61af66fc99e Initial load
duke
parents:
diff changeset
131 cache and all existing pages will be flushed. Call this when the
a61af66fc99e Initial load
duke
parents:
diff changeset
132 target process has been resumed. */
a61af66fc99e Initial load
duke
parents:
diff changeset
133 public synchronized void disable() {
a61af66fc99e Initial load
duke
parents:
diff changeset
134 enabled = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
135 clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
137
a61af66fc99e Initial load
duke
parents:
diff changeset
138 /** Enables the page cache; fetched pages will be added to the
a61af66fc99e Initial load
duke
parents:
diff changeset
139 cache. Call this when the target process has been suspended. */
a61af66fc99e Initial load
duke
parents:
diff changeset
140 public synchronized void enable() {
a61af66fc99e Initial load
duke
parents:
diff changeset
141 enabled = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
143
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 //--------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // Internals only below this point
a61af66fc99e Initial load
duke
parents:
diff changeset
147 //
a61af66fc99e Initial load
duke
parents:
diff changeset
148
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // This is implemented with two data structures: a hash table for
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // fast lookup by a page's base address and a circular doubly-linked
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // list for implementing LRU behavior.
a61af66fc99e Initial load
duke
parents:
diff changeset
152
a61af66fc99e Initial load
duke
parents:
diff changeset
153 private boolean enabled;
a61af66fc99e Initial load
duke
parents:
diff changeset
154 private long pageSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
155 private long maxNumPages;
a61af66fc99e Initial load
duke
parents:
diff changeset
156 private long pageMask;
a61af66fc99e Initial load
duke
parents:
diff changeset
157 private long numPages;
a61af66fc99e Initial load
duke
parents:
diff changeset
158 private PageFetcher fetcher;
a61af66fc99e Initial load
duke
parents:
diff changeset
159 private LongHashMap addressToPageMap; // Map<long, Page>
a61af66fc99e Initial load
duke
parents:
diff changeset
160 private Page lruList; // Most recently fetched page, or null
a61af66fc99e Initial load
duke
parents:
diff changeset
161
a61af66fc99e Initial load
duke
parents:
diff changeset
162 /** Page fetcher plus LRU functionality */
a61af66fc99e Initial load
duke
parents:
diff changeset
163 private Page getPage(long pageBaseAddress) {
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // Check head of LRU list first to avoid hash table lookup and
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // extra list work if possible
a61af66fc99e Initial load
duke
parents:
diff changeset
166 if (lruList != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
167 if (lruList.getBaseAddress() == pageBaseAddress) {
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // Hit. Return it.
a61af66fc99e Initial load
duke
parents:
diff changeset
169 return lruList;
a61af66fc99e Initial load
duke
parents:
diff changeset
170 }
a61af66fc99e Initial load
duke
parents:
diff changeset
171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // Long key = new Long(pageBaseAddress);
a61af66fc99e Initial load
duke
parents:
diff changeset
173 long key = pageBaseAddress;
a61af66fc99e Initial load
duke
parents:
diff changeset
174 Page page = (Page) addressToPageMap.get(key);
a61af66fc99e Initial load
duke
parents:
diff changeset
175 if (page == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // System.err.println("** Cache miss at address 0x" + Long.toHexString(pageBaseAddress) + " **");
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // Fetch new page
a61af66fc99e Initial load
duke
parents:
diff changeset
178 page = fetcher.fetchPage(pageBaseAddress, pageSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
179 if (enabled) {
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // Add to cache, evicting last element if necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
181 addressToPageMap.put(key, page);
a61af66fc99e Initial load
duke
parents:
diff changeset
182 if (Assert.ASSERTS_ENABLED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
183 Assert.that(page == (Page) addressToPageMap.get(pageBaseAddress),
a61af66fc99e Initial load
duke
parents:
diff changeset
184 "must have found page in cache!");
a61af66fc99e Initial load
duke
parents:
diff changeset
185 }
a61af66fc99e Initial load
duke
parents:
diff changeset
186 addPageToList(page);
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // See whether eviction of oldest is necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
188 if (numPages == maxNumPages) {
a61af66fc99e Initial load
duke
parents:
diff changeset
189 Page evictedPage = lruList.getPrev();
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // System.err.println("-> Evicting page at 0x" + Long.toHexString(evictedPage.getBaseAddress()) +
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // "; " + countPages() + " pages left (expect " + numPages + ")");
a61af66fc99e Initial load
duke
parents:
diff changeset
192 removePageFromList(evictedPage);
a61af66fc99e Initial load
duke
parents:
diff changeset
193 addressToPageMap.remove(evictedPage.getBaseAddress());
a61af66fc99e Initial load
duke
parents:
diff changeset
194 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
195 ++numPages;
a61af66fc99e Initial load
duke
parents:
diff changeset
196 }
a61af66fc99e Initial load
duke
parents:
diff changeset
197 }
a61af66fc99e Initial load
duke
parents:
diff changeset
198 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
199 // Page already in cache, move to front of list
a61af66fc99e Initial load
duke
parents:
diff changeset
200 removePageFromList(page);
a61af66fc99e Initial load
duke
parents:
diff changeset
201 addPageToList(page);
a61af66fc99e Initial load
duke
parents:
diff changeset
202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
203 return page;
a61af66fc99e Initial load
duke
parents:
diff changeset
204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
205
a61af66fc99e Initial load
duke
parents:
diff changeset
206 private Page checkPage(Page page, long startAddress) {
a61af66fc99e Initial load
duke
parents:
diff changeset
207 if (!page.isMapped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
208 throw new UnmappedAddressException(startAddress);
a61af66fc99e Initial load
duke
parents:
diff changeset
209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
210 return page;
a61af66fc99e Initial load
duke
parents:
diff changeset
211 }
a61af66fc99e Initial load
duke
parents:
diff changeset
212
a61af66fc99e Initial load
duke
parents:
diff changeset
213 private int countPages() {
a61af66fc99e Initial load
duke
parents:
diff changeset
214 Page page = lruList;
a61af66fc99e Initial load
duke
parents:
diff changeset
215 int num = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
216 if (page == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
217 return num;
a61af66fc99e Initial load
duke
parents:
diff changeset
218 }
a61af66fc99e Initial load
duke
parents:
diff changeset
219 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
220 ++num;
a61af66fc99e Initial load
duke
parents:
diff changeset
221 page = page.getNext();
a61af66fc99e Initial load
duke
parents:
diff changeset
222 } while (page != lruList);
a61af66fc99e Initial load
duke
parents:
diff changeset
223 return num;
a61af66fc99e Initial load
duke
parents:
diff changeset
224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
225
a61af66fc99e Initial load
duke
parents:
diff changeset
226 private void flushPage(long pageBaseAddress) {
a61af66fc99e Initial load
duke
parents:
diff changeset
227 long key = pageBaseAddress;
a61af66fc99e Initial load
duke
parents:
diff changeset
228 Page page = (Page) addressToPageMap.remove(key);
a61af66fc99e Initial load
duke
parents:
diff changeset
229 if (page != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
230 removePageFromList(page);
a61af66fc99e Initial load
duke
parents:
diff changeset
231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
233
a61af66fc99e Initial load
duke
parents:
diff changeset
234 // Adds given page to head of list
a61af66fc99e Initial load
duke
parents:
diff changeset
235 private void addPageToList(Page page) {
a61af66fc99e Initial load
duke
parents:
diff changeset
236 if (lruList == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
237 lruList = page;
a61af66fc99e Initial load
duke
parents:
diff changeset
238 page.setNext(page);
a61af66fc99e Initial load
duke
parents:
diff changeset
239 page.setPrev(page);
a61af66fc99e Initial load
duke
parents:
diff changeset
240 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
241 // Add to front of list
a61af66fc99e Initial load
duke
parents:
diff changeset
242 page.setNext(lruList);
a61af66fc99e Initial load
duke
parents:
diff changeset
243 page.setPrev(lruList.getPrev());
a61af66fc99e Initial load
duke
parents:
diff changeset
244 lruList.getPrev().setNext(page);
a61af66fc99e Initial load
duke
parents:
diff changeset
245 lruList.setPrev(page);
a61af66fc99e Initial load
duke
parents:
diff changeset
246 lruList = page;
a61af66fc99e Initial load
duke
parents:
diff changeset
247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
248 }
a61af66fc99e Initial load
duke
parents:
diff changeset
249
a61af66fc99e Initial load
duke
parents:
diff changeset
250 // Removes given page from list
a61af66fc99e Initial load
duke
parents:
diff changeset
251 private void removePageFromList(Page page) {
a61af66fc99e Initial load
duke
parents:
diff changeset
252 if (page.getNext() == page) {
a61af66fc99e Initial load
duke
parents:
diff changeset
253 lruList = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
254 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
255 if (lruList == page) {
a61af66fc99e Initial load
duke
parents:
diff changeset
256 lruList = page.getNext();
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
258 page.getPrev().setNext(page.getNext());
a61af66fc99e Initial load
duke
parents:
diff changeset
259 page.getNext().setPrev(page.getPrev());
a61af66fc99e Initial load
duke
parents:
diff changeset
260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
261 page.setPrev(null);
a61af66fc99e Initial load
duke
parents:
diff changeset
262 page.setNext(null);
a61af66fc99e Initial load
duke
parents:
diff changeset
263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
264
a61af66fc99e Initial load
duke
parents:
diff changeset
265 /** Ensure that page size fits within 32 bits and is a power of two, and that maxNumPages > 0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
266 private void checkPageInfo(long pageSize, long maxNumPages) {
a61af66fc99e Initial load
duke
parents:
diff changeset
267 if ((pageSize <= 0) || maxNumPages <= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
268 throw new IllegalArgumentException("pageSize and maxNumPages must both be greater than zero");
a61af66fc99e Initial load
duke
parents:
diff changeset
269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
270 long tmpPageSize = pageSize >>> 32;
a61af66fc99e Initial load
duke
parents:
diff changeset
271 if (tmpPageSize != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
272 throw new IllegalArgumentException("pageSize " + pageSize + " too big (must fit within 32 bits)");
a61af66fc99e Initial load
duke
parents:
diff changeset
273 }
a61af66fc99e Initial load
duke
parents:
diff changeset
274 int numNonZeroBits = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
275 for (int i = 0; i < 32; ++i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
276 if ((pageSize & 1L) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
277 ++numNonZeroBits;
a61af66fc99e Initial load
duke
parents:
diff changeset
278 if ((numNonZeroBits > 1) || (i == 0)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
279 throw new IllegalArgumentException("pageSize " + pageSize + " must be a power of two");
a61af66fc99e Initial load
duke
parents:
diff changeset
280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
282 pageSize >>>= 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
283 if (numNonZeroBits == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
284 pageMask = (pageMask << 1) | 1L;
a61af66fc99e Initial load
duke
parents:
diff changeset
285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
286 }
a61af66fc99e Initial load
duke
parents:
diff changeset
287 pageMask = ~pageMask;
a61af66fc99e Initial load
duke
parents:
diff changeset
288 }
a61af66fc99e Initial load
duke
parents:
diff changeset
289 }