/* * 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.ir; import java.util.Enumeration; import org.jikesrvm.compilers.opt.OptimizingCompilerException; /** * A container for the chain of exception handlers for a basic block. * * * @see BasicBlock * @see ExceptionHandlerBasicBlock */ public final class ExceptionHandlerBasicBlockBag { /** * The array of ExceptionHandlerBasicBlocks constructed by BC2IR * based on the local set of handlers visible within a single method */ private ExceptionHandlerBasicBlock[] local; /** * If this is an inlined method, then this points to the enclosing * method's (the caller's) ExcpetionHandlerBasicBlockBag. If this is * the outermost method, then this is null */ private final ExceptionHandlerBasicBlockBag caller; /** * only for use by BC2IR; return {@link #caller} * @return the contents of {@link #caller} */ public ExceptionHandlerBasicBlockBag getCaller() { return caller; } /** * Create an EHBBB * @param l the local array of EHBBs * @param c the enclosing EHBBB */ public ExceptionHandlerBasicBlockBag(ExceptionHandlerBasicBlock[] l, ExceptionHandlerBasicBlockBag c) { local = l; caller = c; } /** * Takes an element out of the bag. Throws an exception if the block * to remove is not in the bag. * * @param bb the block to remove */ public void remove(BasicBlock bb) { for (int i = 0; i < local.length; i++) { if (bb == local[i]) { ExceptionHandlerBasicBlock[] newLocal = new ExceptionHandlerBasicBlock[local.length - 1]; for (int j = 0; j < i; j++) newLocal[j] = local[j]; for (int j = i + 1; j < local.length; j++) newLocal[j - 1] = local[j]; local = newLocal; return; } } throw new OptimizingCompilerException("Removing block not present in bag: " + bb); } /** * An enumeration of all the exception handler basic blocks * (transitively) in the EHBBB. * @return An enumeration of the exception handler basic blocks in the bag. */ public Enumeration<BasicBlock> enumerator() { return new Enumeration<BasicBlock>() { private int cur_idx = 0; private ExceptionHandlerBasicBlockBag cur_bag = null; // Initialize enumeration to point to first ehbb (if any) { ExceptionHandlerBasicBlockBag c = ExceptionHandlerBasicBlockBag.this; while (c != null && (c.local == null || c.local.length == 0)) { c = c.caller; } if (c != null) { cur_bag = c; } } @Override public boolean hasMoreElements() { return cur_bag != null; } @Override public BasicBlock nextElement() { ExceptionHandlerBasicBlock ans; try { ans = cur_bag.local[cur_idx++]; } catch (NullPointerException e) { java.util.NoSuchElementException nse = new java.util.NoSuchElementException(); nse.initCause(e); throw nse; } // Now advance state to point to next element. if (cur_idx == cur_bag.local.length) { cur_bag = cur_bag.caller; while (cur_bag != null && (cur_bag.local == null || cur_bag.local.length == 0)) { cur_bag = cur_bag.caller; } if (cur_bag != null) { cur_idx = 0; // found the next array, reset idx to first element. } } return ans; } }; } }