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.policy.ImmortalSpace; 016 import org.mmtk.utility.Constants; 017 import org.mmtk.utility.heap.VMRequest; 018 019 import org.jikesrvm.VM; 020 import org.jikesrvm.runtime.BootRecord; 021 import org.jikesrvm.HeapLayoutConstants; 022 import org.jikesrvm.runtime.Magic; 023 import org.jikesrvm.objectmodel.JavaHeader; 024 import org.jikesrvm.SizeConstants; 025 026 import org.vmmagic.unboxed.*; 027 import org.vmmagic.pragma.*; 028 029 @Uninterruptible public class Memory extends org.mmtk.vm.Memory 030 implements Constants, HeapLayoutConstants, SizeConstants { 031 032 @Override 033 protected final Address getHeapStartConstant() { return BOOT_IMAGE_DATA_START; } 034 @Override 035 protected final Address getHeapEndConstant() { return MAXIMUM_MAPPABLE; } 036 @Override 037 protected final Address getAvailableStartConstant() { return BOOT_IMAGE_CODE_END; } 038 @Override 039 protected final Address getAvailableEndConstant() { return MAXIMUM_MAPPABLE; } 040 @Override 041 protected final byte getLogBytesInAddressConstant() { return SizeConstants.LOG_BYTES_IN_ADDRESS; } 042 @Override 043 protected final byte getLogBytesInWordConstant() { return SizeConstants.LOG_BYTES_IN_WORD; } 044 @Override 045 protected final byte getLogBytesInPageConstant() { return SizeConstants.LOG_BYTES_IN_PAGE; } 046 @Override 047 protected final byte getLogMinAlignmentConstant() { return JavaHeader.LOG_MIN_ALIGNMENT;} 048 @Override 049 protected final int getMaxBytesPaddingConstant() { return SizeConstants.BYTES_IN_DOUBLE; } 050 @Override 051 protected final int getAlignmentValueConstant() { return JavaHeader.ALIGNMENT_VALUE;} 052 053 /** On Intel we align code to 16 bytes as recommended in the optimization manual. */ 054 @Override 055 protected final byte getMaxAlignmentShiftConstant() { return (VM.BuildForIA32 ? 1 : 0) + SizeConstants.LOG_BYTES_IN_LONG - SizeConstants.LOG_BYTES_IN_INT; } 056 057 private static ImmortalSpace bootSpace; 058 059 /* FIXME the following was established via trial and error :-( */ 060 // private static int BOOT_SEGMENT_MB = 4+(BOOT_IMAGE_SIZE.toInt()>>LOG_BYTES_IN_MBYTE); 061 private static int BOOT_SEGMENT_MB = (0x10000000>>LOG_BYTES_IN_MBYTE); 062 063 /** 064 * Return the space associated with/reserved for the VM. In the 065 * case of Jikes RVM this is the boot image space.<p> 066 * 067 * The boot image space must be mapped at the start of available 068 * virtual memory, hence we use the constructor that requests the 069 * lowest address in the address space. The address space awarded 070 * to this space depends on the order in which the request is made. 071 * If this request is not the first request for virtual memory then 072 * the Space allocator will die with an error stating that the 073 * request could not be satisfied. The remedy is to ensure it is 074 * initialized first. 075 * 076 * @return The space managed by the virtual machine. In this case, 077 * the boot image space is returned. 078 */ 079 @Override 080 @Interruptible 081 public final ImmortalSpace getVMSpace() { 082 if (bootSpace == null) { 083 bootSpace = new ImmortalSpace("boot", VMRequest.create(BOOT_SEGMENT_MB)); 084 } 085 return bootSpace; 086 } 087 088 @Override 089 public final void globalPrepareVMSpace() { bootSpace.prepare(); } 090 091 @Override 092 public final void collectorPrepareVMSpace() {} 093 094 @Override 095 public final void collectorReleaseVMSpace() {} 096 097 @Override 098 public final void globalReleaseVMSpace() { bootSpace.release(); } 099 100 @Override 101 public final void setHeapRange(int id, Address start, Address end) { 102 BootRecord.the_boot_record.setHeapRange(id, start, end); 103 } 104 105 @Override 106 public final int dzmmap(Address start, int size) { 107 Address result = org.jikesrvm.runtime.Memory.dzmmap(start, Extent.fromIntZeroExtend(size)); 108 if (result.EQ(start)) return 0; 109 if (result.GT(Address.fromIntZeroExtend(127))) { 110 VM.sysWrite("demand zero mmap with MAP_FIXED on ", start); 111 VM.sysWriteln(" returned some other address", result); 112 VM.sysFail("mmap with MAP_FIXED has unexpected behavior"); 113 } 114 return result.toInt(); 115 } 116 117 @Override 118 public final boolean mprotect(Address start, int size) { 119 return org.jikesrvm.runtime.Memory.mprotect(start, Extent.fromIntZeroExtend(size), 120 org.jikesrvm.runtime.Memory.PROT_NONE); 121 } 122 123 @Override 124 public final boolean munprotect(Address start, int size) { 125 return org.jikesrvm.runtime.Memory.mprotect(start, Extent.fromIntZeroExtend(size), 126 org.jikesrvm.runtime.Memory.PROT_READ | 127 org.jikesrvm.runtime.Memory.PROT_WRITE | 128 org.jikesrvm.runtime.Memory.PROT_EXEC); 129 } 130 131 @Override 132 public final void zero(boolean useNT, Address start, Extent len) { 133 org.jikesrvm.runtime.Memory.zero(useNT, start,len); 134 } 135 136 @Override 137 public final void dumpMemory(Address start, int beforeBytes, 138 int afterBytes) { 139 org.jikesrvm.runtime.Memory.dumpMemory(start,beforeBytes,afterBytes); 140 } 141 142 /* 143 * Utilities from the VM class 144 */ 145 146 @Override 147 @Inline 148 public final void sync() { 149 Magic.sync(); 150 } 151 152 @Override 153 @Inline 154 public final void isync() { 155 Magic.isync(); 156 } 157 }