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.compilers.common;
014
015import org.jikesrvm.VM;
016import org.jikesrvm.mm.mminterface.MemoryManager;
017import org.vmmagic.pragma.Uninterruptible;
018
019/**
020 * CodeArray represents a code object (contiguous memory region containing code).
021 * The types of the access methods are platform-dependent.
022 */
023@Uninterruptible
024public final class CodeArray {
025  /** backing array for PPC code arrays during boot image creation */
026  private final int[] ppc_data;
027  /** backing array for x86 code arrays during boot image creation */
028  private final byte[] x86_data;
029
030  CodeArray(int size) {
031    if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED);  // should be unreachable
032    if (VM.BuildForIA32) {
033      x86_data = new byte[size];
034      ppc_data = null;
035    } else if (VM.BuildForPowerPC) {
036      ppc_data = new int[size];
037      x86_data = null;
038    } else {
039      throw new Error("Should not reach here");
040    }
041  }
042
043  public int get(int index) {
044    if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED);  // should be hijacked
045    if (VM.BuildForIA32) {
046      return x86_data[index];
047    } else {
048      return ppc_data[index];
049    }
050  }
051
052  public void set(int index, int v) {
053    if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED);  // should be hijacked
054    if (VM.BuildForIA32) {
055      byte bv = (byte)v;
056      if (VM.VerifyAssertions) VM._assert(v == bv);
057      x86_data[index] = bv;
058    } else {
059      ppc_data[index] = v;
060    }
061  }
062
063  public int length() {
064    if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED);  // should be hijacked
065    if (VM.BuildForIA32) {
066      return x86_data.length;
067    } else {
068      return ppc_data.length;
069    }
070  }
071
072  public Object getBacking() {
073    if (!VM.writingImage) VM.sysFail("CodeArray.getBacking called when not writing boot image");
074    if (VM.BuildForIA32) {
075      return x86_data;
076    } else {
077      return ppc_data;
078    }
079  }
080
081  /**
082   * A helper class to contain the 'real' methods of CodeArray.
083   * Because Jikes RVM believes that CodeArray is really a Code[]
084   * (ie, an array of primitives), we cannot define non-hijacked methods
085   * on the 'class' CodeArray.
086   */
087  public static class Factory {
088    /**
089     * Allocate a code array big enough to contain numInstrs instructions.
090     * @param numInstrs the number of instructions to copy from instrs
091     * @param isHot is this an allocation of code for a hot method?
092     * @return a CodeArray containing the instructions
093     */
094    public static CodeArray create(int numInstrs, boolean isHot) {
095      if (VM.runningVM) {
096        return MemoryManager.allocateCode(numInstrs, isHot);
097      } else {
098        return BootImageCreate.create(numInstrs, isHot);
099      }
100    }
101  }
102
103  /**
104   * Class to create CodeArrays in the boot image that isn't compiled into the VM
105   */
106  private static class BootImageCreate {
107    static CodeArray create(int numInstrs, boolean isHot) {
108      return new CodeArray(numInstrs);
109    }
110  }
111}