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}