/*
* 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.vmmagic.unboxed.harness;
import java.util.HashMap;
import org.mmtk.harness.lang.Trace;
import org.mmtk.harness.lang.Trace.Item;
import org.vmmagic.unboxed.Address;
import static org.vmmagic.unboxed.harness.MemoryConstants.*;
final class PageTable {
private final HashMap<Long, MemoryPage> pages = new HashMap<Long, MemoryPage>();
private long pageTableEntry(Address p) {
return p.toLong() >>> LOG_BYTES_IN_PAGE;
}
/**
* Internal: get a page by page number, performing appropriate
* checking and synchronization
* @param page
* @return
*/
synchronized MemoryPage getPage(Address p) {
MemoryPage page = pages.get(pageTableEntry(p));
if (page == null) {
throw new RuntimeException("Page not mapped: " + p);
} else if (!page.readable) {
throw new RuntimeException("Page not readable: " + p);
}
return page;
}
synchronized void setReadable(Address p) {
MemoryPage page = pages.get(pageTableEntry(p));
if (page == null) {
throw new RuntimeException("Page not mapped: " + p);
}
page.readable = true;
}
synchronized void setNonReadable(Address p) {
MemoryPage page = pages.get(pageTableEntry(p));
if (page == null) {
throw new RuntimeException("Page not mapped: " + p);
}
page.readable = false;
}
synchronized void mapPage(Address p) {
long page = pageTableEntry(p);
Trace.trace(Item.MEMORY,"Mapping page %s%n", p);
if (pages.get(page) != null) {
throw new RuntimeException("Page already mapped: " + p);
}
pages.put(page, new MemoryPage(p));
}
synchronized void zeroPage(Address p) {
synchronized(pages) {
MemoryPage page = pages.get(pageTableEntry(p));
if (page == null) {
throw new RuntimeException("Page not mapped: " + p);
}
page.zero();
}
}
}