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 java.util.Enumeration; 016 017 import 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 */ 026 public 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 * take an element out f the bag. Throw an exception if the block 061 * to remove is not in the bag 062 */ 063 public void remove(BasicBlock bb) { 064 for (int i = 0; i < local.length; i++) { 065 if (bb == local[i]) { 066 ExceptionHandlerBasicBlock[] newLocal = new ExceptionHandlerBasicBlock[local.length - 1]; 067 068 for (int j = 0; j < i; j++) newLocal[j] = local[j]; 069 070 for (int j = i + 1; j < local.length; j++) newLocal[j - 1] = local[j]; 071 072 local = newLocal; 073 return; 074 } 075 } 076 077 throw new OptimizingCompilerException("Removing block not present in bag: " + bb); 078 } 079 080 /** 081 * An enumeration of all the exception handler basic blocks 082 * (transitively) in the EHBBB. 083 * @return An enumeration of the exception handler basic blocks in the bag. 084 */ 085 public Enumeration<BasicBlock> enumerator() { 086 return new Enumeration<BasicBlock>() { 087 private int cur_idx = 0; 088 private ExceptionHandlerBasicBlockBag cur_bag = null; 089 090 // Initialize enumeration to point to first ehbb (if any) 091 { 092 ExceptionHandlerBasicBlockBag c = ExceptionHandlerBasicBlockBag.this; 093 while (c != null && (c.local == null || c.local.length == 0)) { c = c.caller; } 094 if (c != null) { 095 cur_bag = c; 096 } 097 } 098 099 @Override 100 public boolean hasMoreElements() { return cur_bag != null; } 101 102 @Override 103 public BasicBlock nextElement() { 104 ExceptionHandlerBasicBlock ans; 105 try { 106 ans = cur_bag.local[cur_idx++]; 107 } catch (NullPointerException e) { 108 throw new java.util.NoSuchElementException(); 109 } 110 // Now advance state to point to next element. 111 if (cur_idx == cur_bag.local.length) { 112 cur_bag = cur_bag.caller; 113 while (cur_bag != null && (cur_bag.local == null || cur_bag.local.length == 0)) { 114 cur_bag = cur_bag.caller; 115 } 116 if (cur_bag != null) { 117 cur_idx = 0; // found the next array, reset idx to first element. 118 } 119 } 120 return ans; 121 } 122 }; 123 } 124 } 125