/*
* This file is part of the Jikes RVM project (http://jikesrvm.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.
*/
package org.jikesrvm.compilers.opt.bc2ir;
import static org.jikesrvm.compilers.opt.driver.OptConstants.SYNTH_CATCH_BCI;
import static org.jikesrvm.compilers.opt.ir.Operators.GET_CAUGHT_EXCEPTION;
import org.jikesrvm.classloader.TypeReference;
import org.jikesrvm.compilers.opt.inlining.InlineSequence;
import org.jikesrvm.compilers.opt.ir.BasicBlock;
import org.jikesrvm.compilers.opt.ir.ControlFlowGraph;
import org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock;
import org.jikesrvm.compilers.opt.ir.GenericRegisterPool;
import org.jikesrvm.compilers.opt.ir.Instruction;
import org.jikesrvm.compilers.opt.ir.Nullary;
import org.jikesrvm.compilers.opt.ir.operand.RegisterOperand;
import org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand;
import org.jikesrvm.compilers.opt.ir.operand.TypeOperand;
/**
* Extend BasicBlockLE for handler blocks
*/
final class HandlerBlockLE extends BasicBlockLE {
/**
* The RegisterOperand that code should use to access
* the caught exception object
*/
final RegisterOperand exceptionObject;
/**
* The synthetic entry basic block for this handler.
* It contains the instruction sequence to get the caught exception object
* into a "normal" register operand (exceptionObject);
*/
final ExceptionHandlerBasicBlock entryBlock;
/**
* Create a new exception handler BBLE (and exception handler basic block)
* for the specified bytecode index and exception type.
*
* @param loc bytecode index
* @param position inline sequence
* @param eType exception type
* @param temps the register pool to allocate exceptionObject from
* @param exprStackSize max size of expression stack
* @param cfg ControlFlowGraph into which the block
* will eventually be inserted
*/
HandlerBlockLE(int loc, InlineSequence position, TypeOperand eType, GenericRegisterPool temps,
int exprStackSize, ControlFlowGraph cfg) {
super(loc);
entryBlock = new ExceptionHandlerBasicBlock(SYNTH_CATCH_BCI, position, eType, cfg);
block = new BasicBlock(loc, position, cfg);
// NOTE: We intentionally use throwable rather than eType to avoid
// having the complexity of having to regenerate the handler when a
// new type of caught exception is added. Since we shouldn't care about
// the performance of code in exception handling blocks, this
// should be the right tradeoff.
exceptionObject = temps.makeTemp(TypeReference.JavaLangThrowable);
BC2IR.setGuardForRegOp(exceptionObject, new TrueGuardOperand()); // know not null
high = loc;
// Set up expression stack on entry to have the caught exception operand.
stackState = new OperandStack(exprStackSize);
stackState.push(exceptionObject);
setStackKnown();
// entry block contains instructions to transfer the caught
// exception object to exceptionObject.
Instruction s = Nullary.create(GET_CAUGHT_EXCEPTION, exceptionObject.copyD2D());
entryBlock.appendInstruction(s);
s.setBytecodeIndex(SYNTH_CATCH_BCI);
entryBlock.insertOut(block);
}
void addCaughtException(TypeOperand et) {
entryBlock.addCaughtException(et);
}
byte mayCatchException(TypeReference et) {
return entryBlock.mayCatchException(et);
}
byte mustCatchException(TypeReference et) {
return entryBlock.mustCatchException(et);
}
}