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.baseline; 014 015import org.jikesrvm.VM; 016import org.jikesrvm.architecture.ArchConstants; 017import org.jikesrvm.classloader.ExceptionHandlerMap; 018import org.jikesrvm.classloader.TypeReference; 019import 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 */ 025final 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]] << ArchConstants.getLogInstructionWidth(); 044 eTable[i * 4 + TRY_END] = 045 bytecodeMap[endPCs[i]] << ArchConstants.getLogInstructionWidth(); 046 eTable[i * 4 + CATCH_START] = 047 bytecodeMap[handlerPCs[i]] << ArchConstants.getLogInstructionWidth(); 048 try { 049 eTable[i * 4 + EX_TYPE] = exceptionTypes[i].resolve().getId(); 050 } catch (NoClassDefFoundError except) { 051 // For now, we are forcing early loading of exception types to 052 // avoid a bunch of ugly issues in resolving the type when delivering 053 // the exception. The problem is that we currently can't allow a GC 054 // while in the midst of delivering an exception and resolving the 055 // type reference might entail calling arbitrary classloader code. 056 VM.sysWriteln("Trouble resolving a caught exception at compile time:"); 057 except.printStackTrace(); // sysFail won't print the stack trace that 058 // lead to the NoClassDefFoundError. 059 VM.sysFail("Unable to resolve caught exception type at compile time"); 060 } 061 } 062 return eTable; 063 } 064}