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    }