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    }