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