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.opt.bc2ir; 014 015import static org.jikesrvm.compilers.opt.driver.OptConstants.SYNTH_CATCH_BCI; 016import static org.jikesrvm.compilers.opt.ir.Operators.GET_CAUGHT_EXCEPTION; 017 018import org.jikesrvm.classloader.TypeReference; 019import org.jikesrvm.compilers.opt.inlining.InlineSequence; 020import org.jikesrvm.compilers.opt.ir.BasicBlock; 021import org.jikesrvm.compilers.opt.ir.ControlFlowGraph; 022import org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock; 023import org.jikesrvm.compilers.opt.ir.GenericRegisterPool; 024import org.jikesrvm.compilers.opt.ir.Instruction; 025import org.jikesrvm.compilers.opt.ir.Nullary; 026import org.jikesrvm.compilers.opt.ir.operand.RegisterOperand; 027import org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand; 028import org.jikesrvm.compilers.opt.ir.operand.TypeOperand; 029 030/** 031 * Extend BasicBlockLE for handler blocks 032 */ 033final class HandlerBlockLE extends BasicBlockLE { 034 /** 035 * The RegisterOperand that code should use to access 036 * the caught exception object 037 */ 038 final RegisterOperand exceptionObject; 039 040 /** 041 * The synthetic entry basic block for this handler. 042 * It contains the instruction sequence to get the caught exception object 043 * into a "normal" register operand (exceptionObject); 044 */ 045 final ExceptionHandlerBasicBlock entryBlock; 046 047 /** 048 * Create a new exception handler BBLE (and exception handler basic block) 049 * for the specified bytecode index and exception type. 050 * 051 * @param loc bytecode index 052 * @param position inline sequence 053 * @param eType exception type 054 * @param temps the register pool to allocate exceptionObject from 055 * @param exprStackSize max size of expression stack 056 * @param cfg ControlFlowGraph into which the block 057 * will eventually be inserted 058 */ 059 HandlerBlockLE(int loc, InlineSequence position, TypeOperand eType, GenericRegisterPool temps, 060 int exprStackSize, ControlFlowGraph cfg) { 061 super(loc); 062 entryBlock = new ExceptionHandlerBasicBlock(SYNTH_CATCH_BCI, position, eType, cfg); 063 block = new BasicBlock(loc, position, cfg); 064 // NOTE: We intentionally use throwable rather than eType to avoid 065 // having the complexity of having to regenerate the handler when a 066 // new type of caught exception is added. Since we shouldn't care about 067 // the performance of code in exception handling blocks, this 068 // should be the right tradeoff. 069 exceptionObject = temps.makeTemp(TypeReference.JavaLangThrowable); 070 BC2IR.setGuardForRegOp(exceptionObject, new TrueGuardOperand()); // know not null 071 high = loc; 072 // Set up expression stack on entry to have the caught exception operand. 073 stackState = new OperandStack(exprStackSize); 074 stackState.push(exceptionObject); 075 setStackKnown(); 076 // entry block contains instructions to transfer the caught 077 // exception object to exceptionObject. 078 Instruction s = Nullary.create(GET_CAUGHT_EXCEPTION, exceptionObject.copyD2D()); 079 entryBlock.appendInstruction(s); 080 s.bcIndex = SYNTH_CATCH_BCI; 081 entryBlock.insertOut(block); 082 } 083 084 void addCaughtException(TypeOperand et) { 085 entryBlock.addCaughtException(et); 086 } 087 088 byte mayCatchException(TypeReference et) { 089 return entryBlock.mayCatchException(et); 090 } 091 092 byte mustCatchException(TypeReference et) { 093 return entryBlock.mustCatchException(et); 094 } 095}