/* * 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.jikesrvm.mm.mmtk; import org.mmtk.plan.Plan; import org.mmtk.policy.ImmortalSpace; import org.mmtk.utility.Constants; import org.mmtk.utility.heap.VMRequest; import org.jikesrvm.VM; import org.jikesrvm.runtime.BootRecord; import org.jikesrvm.HeapLayoutConstants; import org.jikesrvm.runtime.Magic; import org.jikesrvm.objectmodel.JavaHeader; import org.jikesrvm.SizeConstants; import org.vmmagic.unboxed.*; import org.vmmagic.pragma.*; @Uninterruptible public class Memory extends org.mmtk.vm.Memory implements Constants, HeapLayoutConstants, SizeConstants { protected final Address getHeapStartConstant() { return BOOT_IMAGE_DATA_START; } protected final Address getHeapEndConstant() { return MAXIMUM_MAPPABLE; } protected final Address getAvailableStartConstant() { return BOOT_IMAGE_CODE_END; } protected final Address getAvailableEndConstant() { return MAXIMUM_MAPPABLE; } protected final byte getLogBytesInAddressConstant() { return SizeConstants.LOG_BYTES_IN_ADDRESS; } protected final byte getLogBytesInWordConstant() { return SizeConstants.LOG_BYTES_IN_WORD; } protected final byte getLogBytesInPageConstant() { return SizeConstants.LOG_BYTES_IN_PAGE; } protected final byte getLogMinAlignmentConstant() { return JavaHeader.LOG_MIN_ALIGNMENT;} protected final int getMaxBytesPaddingConstant() { return SizeConstants.BYTES_IN_DOUBLE; } protected final int getAlignmentValueConstant() { return JavaHeader.ALIGNMENT_VALUE;} /* On Intel we align code to 16 bytes as recommended in the optimization manual */ protected final byte getMaxAlignmentShiftConstant() { return (VM.BuildForIA32 ? 1 : 0) + SizeConstants.LOG_BYTES_IN_LONG - SizeConstants.LOG_BYTES_IN_INT; } private static ImmortalSpace bootSpace; /* FIXME the following was established via trial and error :-( */ // private static int BOOT_SEGMENT_MB = 4+(BOOT_IMAGE_SIZE.toInt()>>LOG_BYTES_IN_MBYTE); private static int BOOT_SEGMENT_MB = (0x10000000>>LOG_BYTES_IN_MBYTE); /** * Return the space associated with/reserved for the VM. In the * case of Jikes RVM this is the boot image space.<p> * * The boot image space must be mapped at the start of available * virtual memory, hence we use the constructor that requests the * lowest address in the address space. The address space awarded * to this space depends on the order in which the request is made. * If this request is not the first request for virtual memory then * the Space allocator will die with an error stating that the * request could not be satisfied. The remedy is to ensure it is * initialized first. * * @return The space managed by the virtual machine. In this case, * the boot image space is returned. */ @Interruptible public final ImmortalSpace getVMSpace() { if (bootSpace == null) { bootSpace = new ImmortalSpace("boot", Plan.DEFAULT_POLL_FREQUENCY, VMRequest.create(BOOT_SEGMENT_MB)); } return bootSpace; } /** Global preparation for a collection. */ public final void globalPrepareVMSpace() { bootSpace.prepare(); } /** Per-collector preparation for a collection. */ public final void collectorPrepareVMSpace() {} /** Per-collector post-collection work. */ public final void collectorReleaseVMSpace() {} /** Global post-collection work. */ public final void globalReleaseVMSpace() { bootSpace.release(); } /** * Sets the range of addresses associated with a heap. * * @param id the heap identifier * @param start the address of the start of the heap * @param end the address of the end of the heap */ public final void setHeapRange(int id, Address start, Address end) { BootRecord.the_boot_record.setHeapRange(id, start, end); } /** * Demand zero mmaps an area of virtual memory. * * @param start the address of the start of the area to be mapped * @param size the size, in bytes, of the area to be mapped * @return 0 if successful, otherwise the system errno */ public final int dzmmap(Address start, int size) { Address result = org.jikesrvm.runtime.Memory.dzmmap(start, Extent.fromIntZeroExtend(size)); if (result.EQ(start)) return 0; if (result.GT(Address.fromIntZeroExtend(127))) { VM.sysWrite("demand zero mmap with MAP_FIXED on ", start); VM.sysWriteln(" returned some other address", result); VM.sysFail("mmap with MAP_FIXED has unexpected behavior"); } return result.toInt(); } /** * Protects access to an area of virtual memory. * * @param start the address of the start of the area to be mapped * @param size the size, in bytes, of the area to be mapped * @return <code>true</code> if successful, otherwise * <code>false</code> */ public final boolean mprotect(Address start, int size) { return org.jikesrvm.runtime.Memory.mprotect(start, Extent.fromIntZeroExtend(size), org.jikesrvm.runtime.Memory.PROT_NONE); } /** * Allows access to an area of virtual memory. * * @param start the address of the start of the area to be mapped * @param size the size, in bytes, of the area to be mapped * @return <code>true</code> if successful, otherwise * <code>false</code> */ public final boolean munprotect(Address start, int size) { return org.jikesrvm.runtime.Memory.mprotect(start, Extent.fromIntZeroExtend(size), org.jikesrvm.runtime.Memory.PROT_READ | org.jikesrvm.runtime.Memory.PROT_WRITE | org.jikesrvm.runtime.Memory.PROT_EXEC); } /** * Zero a region of memory. * @param start Start of address range (inclusive) * @param len Length in bytes of range to zero * Returned: nothing */ public final void zero(Address start, Extent len) { org.jikesrvm.runtime.Memory.zero(start,len); } /** * Zero a range of pages of memory. * @param start Start of address range (must be a page address) * @param len Length in bytes of range (must be multiple of page size) */ public final void zeroPages(Address start, int len) { /* AJG: Add assertions to check conditions documented above. */ org.jikesrvm.runtime.Memory.zeroPages(start,len); } /** * Logs the contents of an address and the surrounding memory to the * error output. * * @param start the address of the memory to be dumped * @param beforeBytes the number of bytes before the address to be * included * @param afterBytes the number of bytes after the address to be * included */ public final void dumpMemory(Address start, int beforeBytes, int afterBytes) { org.jikesrvm.runtime.Memory.dumpMemory(start,beforeBytes,afterBytes); } /* * Utilities from the VM class */ @Inline public final void sync() { Magic.sync(); } @Inline public final void isync() { Magic.isync(); } }