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 */ 013package org.jikesrvm.mm.mmtk; 014 015import static org.jikesrvm.HeapLayoutConstants.BOOT_IMAGE_DATA_START; 016import static org.jikesrvm.HeapLayoutConstants.BOOT_IMAGE_END; 017import static org.jikesrvm.HeapLayoutConstants.MAXIMUM_MAPPABLE; 018import static org.jikesrvm.runtime.JavaSizeConstants.BYTES_IN_DOUBLE; 019import static org.jikesrvm.runtime.JavaSizeConstants.LOG_BYTES_IN_INT; 020import static org.jikesrvm.runtime.JavaSizeConstants.LOG_BYTES_IN_LONG; 021import static org.jikesrvm.runtime.UnboxedSizeConstants.LOG_BYTES_IN_ADDRESS; 022import static org.jikesrvm.runtime.UnboxedSizeConstants.LOG_BYTES_IN_WORD; 023import static org.mmtk.utility.Constants.LOG_BYTES_IN_MBYTE; 024 025import org.jikesrvm.VM; 026import org.jikesrvm.objectmodel.JavaHeader; 027import org.jikesrvm.runtime.BootRecord; 028import org.jikesrvm.runtime.Magic; 029import org.mmtk.policy.ImmortalSpace; 030import org.mmtk.policy.Space; 031import org.mmtk.utility.heap.VMRequest; 032import org.vmmagic.pragma.Inline; 033import org.vmmagic.pragma.Interruptible; 034import org.vmmagic.pragma.Uninterruptible; 035import org.vmmagic.unboxed.Address; 036import org.vmmagic.unboxed.Extent; 037import org.vmmagic.unboxed.Offset; 038 039@Uninterruptible public class Memory extends org.mmtk.vm.Memory { 040 041 /** 042 * A lie about the size of a virtual memory page. MMTk currently 043 * assumes that the page size is known at bootimage building time (see RVM-816), 044 * so we need to pass some kind of value. 045 */ 046 private static final int LOG_BYTES_IN_PAGE_LIE = 12; 047 048 @Override 049 protected final Address getHeapStartConstant() { 050 return BOOT_IMAGE_DATA_START; 051 } 052 @Override 053 protected final Address getHeapEndConstant() { 054 return MAXIMUM_MAPPABLE; 055 } 056 @Override 057 protected final Address getAvailableStartConstant() { 058 return BOOT_IMAGE_END; 059 } 060 @Override 061 protected final Address getAvailableEndConstant() { 062 return MAXIMUM_MAPPABLE; 063 } 064 @Override 065 protected final byte getLogBytesInAddressConstant() { 066 return LOG_BYTES_IN_ADDRESS; 067 } 068 @Override 069 protected final byte getLogBytesInWordConstant() { 070 return LOG_BYTES_IN_WORD; 071 } 072 @Override 073 protected final byte getLogBytesInPageConstant() { 074 return LOG_BYTES_IN_PAGE_LIE; 075 } 076 @Override 077 protected final byte getLogMinAlignmentConstant() { 078 return JavaHeader.LOG_MIN_ALIGNMENT; 079 } 080 @Override 081 protected final int getMaxBytesPaddingConstant() { 082 return BYTES_IN_DOUBLE; 083 } 084 @Override 085 protected final int getAlignmentValueConstant() { 086 return JavaHeader.ALIGNMENT_VALUE; 087 } 088 089 /** On Intel we align code to 16 bytes as recommended in the optimization manual. */ 090 @Override 091 protected final byte getMaxAlignmentShiftConstant() { 092 return (VM.BuildForIA32 ? 1 : 0) + LOG_BYTES_IN_LONG - LOG_BYTES_IN_INT; 093 } 094 095 private static ImmortalSpace bootSpace; 096 097 private static final int BOOT_SEGMENT_MB; 098 099 static { 100 Offset bootSegmentBytes = BOOT_IMAGE_END.diff(BOOT_IMAGE_DATA_START); 101 BOOT_SEGMENT_MB = org.jikesrvm.runtime.Memory.alignUp(bootSegmentBytes.toInt(), 102 Space.BYTES_IN_CHUNK) >>> LOG_BYTES_IN_MBYTE; 103 } 104 105 /** 106 * Return the space associated with/reserved for the VM. In the 107 * case of Jikes RVM this is the boot image space.<p> 108 * 109 * The boot image space must be mapped at the start of available 110 * virtual memory, hence we use the constructor that requests the 111 * lowest address in the address space. The address space awarded 112 * to this space depends on the order in which the request is made. 113 * If this request is not the first request for virtual memory then 114 * the Space allocator will die with an error stating that the 115 * request could not be satisfied. The remedy is to ensure it is 116 * initialized first. 117 * 118 * @return The space managed by the virtual machine. In this case, 119 * the boot image space is returned. 120 */ 121 @Override 122 @Interruptible 123 public final ImmortalSpace getVMSpace() { 124 if (bootSpace == null) { 125 bootSpace = new ImmortalSpace("boot", VMRequest.fixedSize(BOOT_SEGMENT_MB)); 126 } 127 return bootSpace; 128 } 129 130 @Override 131 public final void globalPrepareVMSpace() { 132 bootSpace.prepare(); 133 } 134 135 @Override 136 public final void collectorPrepareVMSpace() {} 137 138 @Override 139 public final void collectorReleaseVMSpace() {} 140 141 @Override 142 public final void globalReleaseVMSpace() { 143 bootSpace.release(); 144 } 145 146 @Override 147 public final void setHeapRange(int id, Address start, Address end) { 148 BootRecord.the_boot_record.setHeapRange(id, start, end); 149 } 150 151 @Override 152 public final int dzmmap(Address start, int size) { 153 Address result = org.jikesrvm.runtime.Memory.dzmmap(start, Extent.fromIntZeroExtend(size)); 154 if (result.EQ(start)) return 0; 155 if (result.GT(Address.fromIntZeroExtend(127))) { 156 VM.sysWrite("demand zero mmap with MAP_FIXED on ", start); 157 VM.sysWriteln(" returned some other address", result); 158 VM.sysFail("mmap with MAP_FIXED has unexpected behavior"); 159 } 160 return result.toInt(); 161 } 162 163 @Override 164 public final boolean mprotect(Address start, int size) { 165 return org.jikesrvm.runtime.Memory.mprotect(start, Extent.fromIntZeroExtend(size), 166 org.jikesrvm.runtime.Memory.PROT_NONE); 167 } 168 169 @Override 170 public final boolean munprotect(Address start, int size) { 171 return org.jikesrvm.runtime.Memory.mprotect(start, Extent.fromIntZeroExtend(size), 172 org.jikesrvm.runtime.Memory.PROT_READ | 173 org.jikesrvm.runtime.Memory.PROT_WRITE | 174 org.jikesrvm.runtime.Memory.PROT_EXEC); 175 } 176 177 @Override 178 public final void zero(boolean useNT, Address start, Extent len) { 179 org.jikesrvm.runtime.Memory.zero(useNT, start,len); 180 } 181 182 @Override 183 public final void dumpMemory(Address start, int beforeBytes, 184 int afterBytes) { 185 org.jikesrvm.runtime.Memory.dumpMemory(start,beforeBytes,afterBytes); 186 } 187 188 /* 189 * Utilities from the VM class 190 */ 191 192 @Override 193 @Inline 194 public final void sync() { 195 Magic.sync(); 196 } 197 198 @Override 199 @Inline 200 public final void isync() { 201 Magic.isync(); 202 } 203}