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