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.ir;
014
015 import org.jikesrvm.compilers.opt.OptimizingCompilerException;
016
017 /**
018 * A container for the chain of exception handlers for a basic block.
019 *
020 *
021 * @see BasicBlock
022 * @see ExceptionHandlerBasicBlock
023 */
024 public final class ExceptionHandlerBasicBlockBag {
025
026 /**
027 * The array of ExceptionHandlerBasicBlocks constructed by BC2IR
028 * based on the local set of handlers visible within a single method
029 */
030 private ExceptionHandlerBasicBlock[] local;
031
032 /**
033 * If this is an inlined method, then this points to the enclosing
034 * method's (the caller's) ExcpetionHandlerBasicBlockBag. If this is
035 * the outermost method, then this is null
036 */
037 private final ExceptionHandlerBasicBlockBag caller;
038
039 /**
040 * only for use by BC2IR; return {@link #caller}
041 * @return the contents of {@link #caller}
042 */
043 public ExceptionHandlerBasicBlockBag getCaller() {
044 return caller;
045 }
046
047 /**
048 * Create an EHBBB
049 * @param l the local array of EHBBs
050 * @param c the enclosing EHBBB
051 */
052 public ExceptionHandlerBasicBlockBag(ExceptionHandlerBasicBlock[] l, ExceptionHandlerBasicBlockBag c) {
053 local = l;
054 caller = c;
055 }
056
057 /**
058 * take an element out f the bag. Throw an exception if the block
059 * to remove is not in the bag
060 */
061 public void remove(BasicBlock bb) {
062 for (int i = 0; i < local.length; i++) {
063 if (bb == local[i]) {
064 ExceptionHandlerBasicBlock[] newLocal = new ExceptionHandlerBasicBlock[local.length - 1];
065
066 for (int j = 0; j < i; j++) newLocal[j] = local[j];
067
068 for (int j = i + 1; j < local.length; j++) newLocal[j - 1] = local[j];
069
070 local = newLocal;
071 return;
072 }
073 }
074
075 throw new OptimizingCompilerException("Removing block not present in bag: " + bb);
076 }
077
078 /**
079 * An enumeration of all the exception handler basic blocks
080 * (transitively) in the EHBBB.
081 * @return An enumeration of the exception handler basic blocks in the bag.
082 */
083 public BasicBlockEnumeration enumerator() {
084 return new BasicBlockEnumeration() {
085 private int cur_idx = 0;
086 private ExceptionHandlerBasicBlockBag cur_bag = null;
087
088 // Initialize enumeration to point to first ehbb (if any)
089 {
090 ExceptionHandlerBasicBlockBag c = ExceptionHandlerBasicBlockBag.this;
091 while (c != null && (c.local == null || c.local.length == 0)) { c = c.caller; }
092 if (c != null) {
093 cur_bag = c;
094 }
095 }
096
097 public boolean hasMoreElements() { return cur_bag != null; }
098
099 public BasicBlock nextElement() { return next(); }
100
101 public BasicBlock next() {
102 ExceptionHandlerBasicBlock ans;
103 try {
104 ans = cur_bag.local[cur_idx++];
105 } catch (NullPointerException e) {
106 throw new java.util.NoSuchElementException();
107 }
108 // Now advance state to point to next element.
109 if (cur_idx == cur_bag.local.length) {
110 cur_bag = cur_bag.caller;
111 while (cur_bag != null && (cur_bag.local == null || cur_bag.local.length == 0)) {
112 cur_bag = cur_bag.caller;
113 }
114 if (cur_bag != null) {
115 cur_idx = 0; // found the next array, reset idx to first element.
116 }
117 }
118 return ans;
119 }
120 };
121 }
122 }
123