/*
* This file is part of the Jikes RVM project (http://jikesrvm.org).
*
* This file is licensed to You under the Common Public License (CPL);
* 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/cpl1.0.php
*
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.
*/
package org.jikesrvm.compilers.opt.ir;
import org.jikesrvm.compilers.opt.OPT_OptimizingCompilerException;
/**
* A container for the chain of exception handlers for a basic block.
*
*
* @see OPT_BasicBlock
* @see OPT_ExceptionHandlerBasicBlock
*/
final class OPT_ExceptionHandlerBasicBlockBag {
/**
* The array of ExceptionHandlerBasicBlocks constructed by BC2IR
* based on the local set of handlers visible within a single method
*/
private OPT_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 OPT_ExceptionHandlerBasicBlockBag caller;
/**
* only for use by BC2IR; return {@link #caller}
* @return the contents of {@link #caller}
*/
OPT_ExceptionHandlerBasicBlockBag getCaller() {
return caller;
}
/**
* Create an EHBBB
* @param l the local array of EHBBs
* @param c the enclosing EHBBB
*/
OPT_ExceptionHandlerBasicBlockBag(OPT_ExceptionHandlerBasicBlock[] l, OPT_ExceptionHandlerBasicBlockBag c) {
local = l;
caller = c;
}
/**
* take an element out f the bag. Throw an exception if the block
* to remove is not in the bag
*/
public void remove(OPT_BasicBlock bb) {
for (int i = 0; i < local.length; i++) {
if (bb == local[i]) {
OPT_ExceptionHandlerBasicBlock[] newLocal = new OPT_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 OPT_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 OPT_BasicBlockEnumeration enumerator() {
return new OPT_BasicBlockEnumeration() {
private int cur_idx = 0;
private OPT_ExceptionHandlerBasicBlockBag cur_bag = null;
// Initialize enumeration to point to first ehbb (if any)
{
OPT_ExceptionHandlerBasicBlockBag c = OPT_ExceptionHandlerBasicBlockBag.this;
while (c != null && (c.local == null || c.local.length == 0)) { c = c.caller; }
if (c != null) {
cur_bag = c;
}
}
public boolean hasMoreElements() { return cur_bag != null; }
public OPT_BasicBlock nextElement() { return next(); }
public OPT_BasicBlock next() {
OPT_ExceptionHandlerBasicBlock ans;
try {
ans = cur_bag.local[cur_idx++];
} catch (NullPointerException e) {
throw new java.util.NoSuchElementException();
}
// 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;
}
};
}
}