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.jikesrvm.mm.mmtk;
014
015 import org.mmtk.plan.Plan;
016 import org.mmtk.policy.ImmortalSpace;
017 import org.mmtk.utility.Constants;
018 import org.mmtk.utility.heap.VMRequest;
019
020 import org.jikesrvm.VM;
021 import org.jikesrvm.runtime.BootRecord;
022 import org.jikesrvm.HeapLayoutConstants;
023 import org.jikesrvm.runtime.Magic;
024 import org.jikesrvm.objectmodel.JavaHeader;
025 import org.jikesrvm.SizeConstants;
026
027 import org.vmmagic.unboxed.*;
028 import org.vmmagic.pragma.*;
029
030 @Uninterruptible public class Memory extends org.mmtk.vm.Memory
031 implements Constants, HeapLayoutConstants, SizeConstants {
032
033 protected final Address getHeapStartConstant() { return BOOT_IMAGE_DATA_START; }
034 protected final Address getHeapEndConstant() { return MAXIMUM_MAPPABLE; }
035 protected final Address getAvailableStartConstant() { return BOOT_IMAGE_CODE_END; }
036 protected final Address getAvailableEndConstant() { return MAXIMUM_MAPPABLE; }
037 protected final byte getLogBytesInAddressConstant() { return SizeConstants.LOG_BYTES_IN_ADDRESS; }
038 protected final byte getLogBytesInWordConstant() { return SizeConstants.LOG_BYTES_IN_WORD; }
039 protected final byte getLogBytesInPageConstant() { return SizeConstants.LOG_BYTES_IN_PAGE; }
040 protected final byte getLogMinAlignmentConstant() { return JavaHeader.LOG_MIN_ALIGNMENT;}
041 protected final int getMaxBytesPaddingConstant() { return SizeConstants.BYTES_IN_DOUBLE; }
042 protected final int getAlignmentValueConstant() { return JavaHeader.ALIGNMENT_VALUE;}
043
044 /* On Intel we align code to 16 bytes as recommended in the optimization manual */
045 protected final byte getMaxAlignmentShiftConstant() { return (VM.BuildForIA32 ? 1 : 0) + SizeConstants.LOG_BYTES_IN_LONG - SizeConstants.LOG_BYTES_IN_INT; }
046
047 private static ImmortalSpace bootSpace;
048
049 /* FIXME the following was established via trial and error :-( */
050 // private static int BOOT_SEGMENT_MB = 4+(BOOT_IMAGE_SIZE.toInt()>>LOG_BYTES_IN_MBYTE);
051 private static int BOOT_SEGMENT_MB = (0x10000000>>LOG_BYTES_IN_MBYTE);
052
053 /**
054 * Return the space associated with/reserved for the VM. In the
055 * case of Jikes RVM this is the boot image space.<p>
056 *
057 * The boot image space must be mapped at the start of available
058 * virtual memory, hence we use the constructor that requests the
059 * lowest address in the address space. The address space awarded
060 * to this space depends on the order in which the request is made.
061 * If this request is not the first request for virtual memory then
062 * the Space allocator will die with an error stating that the
063 * request could not be satisfied. The remedy is to ensure it is
064 * initialized first.
065 *
066 * @return The space managed by the virtual machine. In this case,
067 * the boot image space is returned.
068 */
069 @Interruptible
070 public final ImmortalSpace getVMSpace() {
071 if (bootSpace == null) {
072 bootSpace = new ImmortalSpace("boot", Plan.DEFAULT_POLL_FREQUENCY, VMRequest.create(BOOT_SEGMENT_MB));
073 }
074 return bootSpace;
075 }
076
077 /** Global preparation for a collection. */
078 public final void globalPrepareVMSpace() { bootSpace.prepare(); }
079
080 /** Per-collector preparation for a collection. */
081 public final void collectorPrepareVMSpace() {}
082
083 /** Per-collector post-collection work. */
084 public final void collectorReleaseVMSpace() {}
085
086 /** Global post-collection work. */
087 public final void globalReleaseVMSpace() { bootSpace.release(); }
088
089 /**
090 * Sets the range of addresses associated with a heap.
091 *
092 * @param id the heap identifier
093 * @param start the address of the start of the heap
094 * @param end the address of the end of the heap
095 */
096 public final void setHeapRange(int id, Address start, Address end) {
097 BootRecord.the_boot_record.setHeapRange(id, start, end);
098 }
099
100 /**
101 * Demand zero mmaps an area of virtual memory.
102 *
103 * @param start the address of the start of the area to be mapped
104 * @param size the size, in bytes, of the area to be mapped
105 * @return 0 if successful, otherwise the system errno
106 */
107 public final int dzmmap(Address start, int size) {
108 Address result = org.jikesrvm.runtime.Memory.dzmmap(start, Extent.fromIntZeroExtend(size));
109 if (result.EQ(start)) return 0;
110 if (result.GT(Address.fromIntZeroExtend(127))) {
111 VM.sysWrite("demand zero mmap with MAP_FIXED on ", start);
112 VM.sysWriteln(" returned some other address", result);
113 VM.sysFail("mmap with MAP_FIXED has unexpected behavior");
114 }
115 return result.toInt();
116 }
117
118 /**
119 * Protects access to an area of virtual memory.
120 *
121 * @param start the address of the start of the area to be mapped
122 * @param size the size, in bytes, of the area to be mapped
123 * @return <code>true</code> if successful, otherwise
124 * <code>false</code>
125 */
126 public final boolean mprotect(Address start, int size) {
127 return org.jikesrvm.runtime.Memory.mprotect(start, Extent.fromIntZeroExtend(size),
128 org.jikesrvm.runtime.Memory.PROT_NONE);
129 }
130
131 /**
132 * Allows access to an area of virtual memory.
133 *
134 * @param start the address of the start of the area to be mapped
135 * @param size the size, in bytes, of the area to be mapped
136 * @return <code>true</code> if successful, otherwise
137 * <code>false</code>
138 */
139 public final boolean munprotect(Address start, int size) {
140 return org.jikesrvm.runtime.Memory.mprotect(start, Extent.fromIntZeroExtend(size),
141 org.jikesrvm.runtime.Memory.PROT_READ |
142 org.jikesrvm.runtime.Memory.PROT_WRITE |
143 org.jikesrvm.runtime.Memory.PROT_EXEC);
144 }
145
146 /**
147 * Zero a region of memory.
148 * @param start Start of address range (inclusive)
149 * @param len Length in bytes of range to zero
150 * Returned: nothing
151 */
152 public final void zero(Address start, Extent len) {
153 org.jikesrvm.runtime.Memory.zero(start,len);
154 }
155
156 /**
157 * Zero a range of pages of memory.
158 * @param start Start of address range (must be a page address)
159 * @param len Length in bytes of range (must be multiple of page size)
160 */
161 public final void zeroPages(Address start, int len) {
162 /* AJG: Add assertions to check conditions documented above. */
163 org.jikesrvm.runtime.Memory.zeroPages(start,len);
164 }
165
166 /**
167 * Logs the contents of an address and the surrounding memory to the
168 * error output.
169 *
170 * @param start the address of the memory to be dumped
171 * @param beforeBytes the number of bytes before the address to be
172 * included
173 * @param afterBytes the number of bytes after the address to be
174 * included
175 */
176 public final void dumpMemory(Address start, int beforeBytes,
177 int afterBytes) {
178 org.jikesrvm.runtime.Memory.dumpMemory(start,beforeBytes,afterBytes);
179 }
180
181 /*
182 * Utilities from the VM class
183 */
184
185 @Inline
186 public final void sync() {
187 Magic.sync();
188 }
189
190 @Inline
191 public final void isync() {
192 Magic.isync();
193 }
194 }