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.compilers.baseline;
014
015 import org.jikesrvm.ArchitectureSpecific;
016 import org.jikesrvm.VM;
017 import org.jikesrvm.classloader.ExceptionHandlerMap;
018 import org.jikesrvm.classloader.TypeReference;
019 import org.jikesrvm.compilers.common.ExceptionTable;
020
021 /**
022 * Encoding of try ranges in the final machinecode and the
023 * corresponding exception type and catch block start.
024 */
025 final class BaselineExceptionTable extends ExceptionTable {
026
027 /**
028 * Encode an exception table
029 * @param emap the exception table to encode
030 * @param bytecodeMap mapping from bytecode to machinecode offsets
031 * @return the encoded exception table
032 */
033 static int[] encode(ExceptionHandlerMap emap, int[] bytecodeMap) {
034 int[] startPCs = emap.getStartPC();
035 int[] endPCs = emap.getEndPC();
036 int[] handlerPCs = emap.getHandlerPC();
037 TypeReference[] exceptionTypes = emap.getExceptionTypes();
038 int tableSize = startPCs.length;
039 int[] eTable = new int[tableSize * 4];
040
041 for (int i = 0; i < tableSize; i++) {
042 eTable[i * 4 + TRY_START] =
043 bytecodeMap[startPCs[i]] << ArchitectureSpecific.RegisterConstants.LG_INSTRUCTION_WIDTH;
044 eTable[i * 4 + TRY_END] =
045 bytecodeMap[endPCs[i]] << ArchitectureSpecific.RegisterConstants.LG_INSTRUCTION_WIDTH;
046 eTable[i * 4 + CATCH_START] =
047 bytecodeMap[handlerPCs[i]] << ArchitectureSpecific.RegisterConstants.LG_INSTRUCTION_WIDTH;
048 try {
049 eTable[i * 4 + EX_TYPE] = exceptionTypes[i].resolve().getId();
050 } catch (NoClassDefFoundError except) {
051 // Yuck. If this happens beatup Dave and make him do the right thing.
052 // For now, we are forcing early loading of exception types to
053 // avoid a bunch of ugly issues in resolving the type when delivering
054 // the exception. The problem is that we currently can't allow a GC
055 // while in the midst of delivering an exception and resolving the
056 // type reference might entail calling arbitrary classloader code.
057 VM.sysWriteln("Trouble resolving a caught exception at compile time:");
058 except.printStackTrace(); // sysFail won't print the stack trace that
059 // lead to the NoClassDefFoundError.
060 VM.sysFail("Unable to resolve caught exception type at compile time");
061 }
062 }
063 return eTable;
064 }
065 }