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 // 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 }