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.bc2ir; 014 015 import org.jikesrvm.compilers.opt.inlining.InlineSequence; 016 import org.jikesrvm.compilers.opt.ir.BasicBlock; 017 import org.jikesrvm.compilers.opt.ir.ControlFlowGraph; 018 import org.jikesrvm.compilers.opt.ir.operand.Operand; 019 020 /** 021 * This class is used as a 'wrapper' to a basic block to hold 022 * information that is necessary only for IR generation. 023 */ 024 class BasicBlockLE { 025 // Used by BBSet to maintain red/black tree of BBLE's during generation 026 BasicBlockLE parent, left, right; 027 028 /** Start bytecode of this BBLE */ 029 final int low; 030 031 /** Current end bytecode of this BBLE */ 032 int high; 033 034 /** Maximum possible bytecode of this BBLE (wrt exception ranges) */ 035 int max; 036 037 /** Basic block that this BBLE refers to. */ 038 BasicBlock block; 039 040 /** State of the stack at the start of this basic block. */ 041 OperandStack stackState; 042 043 /** State of the local variables at the start of this basic block. */ 044 Operand[] localState; 045 046 /** 047 * The desired fallthrough (next in code order) BBLE (may be {@code null}). 048 * NOTE: we may not always end up actually falling through 049 * (see BBSet.finalPass). 050 */ 051 BasicBlockLE fallThrough; 052 053 /** 054 * The exception handler BBLE's for this block (null if none) 055 */ 056 HandlerBlockLE[] handlers; 057 058 /** 059 * Encoding of random boolean state 060 */ 061 private byte flags; 062 private static final byte STACK_KNOWN = 0x01; 063 private static final byte LOCAL_KNOWN = 0x02; 064 private static final byte SELF_REGEN = 0x04; 065 private static final byte GENERATED = 0x08; 066 private static final byte COLOR = 0x10; //(Red = 0, Black = 1) 067 private static final byte IN_CODE_ORDER = 0x20; 068 069 final void setStackKnown() { flags |= STACK_KNOWN; } 070 071 final void clearStackKnown() { flags &= ~STACK_KNOWN; } 072 073 final boolean isStackKnown() { return (flags & STACK_KNOWN) != 0; } 074 075 final void setLocalKnown() { flags |= LOCAL_KNOWN; } 076 077 final void clearLocalKnown() { flags &= ~LOCAL_KNOWN; } 078 079 final boolean isLocalKnown() { return (flags & LOCAL_KNOWN) != 0; } 080 081 final void setSelfRegen() { flags |= SELF_REGEN; } 082 083 final void clearSelfRegen() { flags &= ~SELF_REGEN; } 084 085 final boolean isSelfRegen() { return (flags & SELF_REGEN) != 0; } 086 087 final void setGenerated() { flags |= GENERATED; } 088 089 final void clearGenerated() { flags &= ~GENERATED; } 090 091 final boolean isGenerated() { return (flags & GENERATED) != 0; } 092 093 final void setBlack() { flags |= COLOR; } 094 095 final boolean isBlack() { return (flags & COLOR) != 0; } 096 097 final void setRed() { flags &= ~COLOR; } 098 099 final boolean isRed() { return (flags & COLOR) == 0; } 100 101 final void setInCodeOrder() { flags |= IN_CODE_ORDER; } 102 103 final void clearInCodeOrder() { flags &= ~IN_CODE_ORDER; } 104 105 final boolean isInCodeOrder() { return (flags & IN_CODE_ORDER) != 0; } 106 107 /** 108 * Is the BBLE ready to generate? 109 */ 110 final boolean isReadyToGenerate() { 111 // (isStackKnown() && isLocalKnown && !isGenerated) 112 byte READY_MASK = STACK_KNOWN | LOCAL_KNOWN | GENERATED; 113 byte READY_VAL = STACK_KNOWN | LOCAL_KNOWN; 114 return (flags & READY_MASK) == READY_VAL; 115 } 116 117 /** 118 * Save a shallow copy of the given local variable state into this. 119 * @param _localState local variable state to save 120 */ 121 final void copyIntoLocalState(Operand[] _localState) { 122 localState = new Operand[_localState.length]; 123 System.arraycopy(_localState, 0, localState, 0, _localState.length); 124 setLocalKnown(); 125 } 126 127 /** 128 * Return a shallow copy of my local state. 129 */ 130 final Operand[] copyLocalState() { 131 Operand[] ls = new Operand[localState.length]; 132 System.arraycopy(localState, 0, ls, 0, localState.length); 133 return ls; 134 } 135 136 /** 137 * Add an exception handler BBLE to the handlers array. 138 * NOTE: this isn't incredibly efficient, but empirically the expected 139 * number of handlers per basic block is 0, with an observed 140 * maximum across 10,000+ methods of 3. 141 * Until this changes, we just don't care. 142 */ 143 final void addHandler(HandlerBlockLE handler) { 144 if (handlers == null) { 145 handlers = new HandlerBlockLE[1]; 146 handlers[0] = handler; 147 } else { 148 for (HandlerBlockLE handler1 : handlers) { 149 if (handler1 == handler) { 150 return; //already there (was in emap more than once) 151 } 152 } 153 int n = handlers.length; 154 HandlerBlockLE[] tmp = new HandlerBlockLE[n + 1]; 155 for (int i = 0; i < n; i++) { 156 tmp[i] = handlers[i]; 157 } 158 tmp[n] = handler; 159 handlers = tmp; 160 } 161 } 162 163 /** 164 * Create a new BBLE (and basic block) for the specified bytecode index. 165 * 166 * @param loc bytecode index 167 * @param position the inline sequence 168 * @param cfg ControlFlowGraph into which the block 169 * will eventually be inserted 170 */ 171 BasicBlockLE(int loc, InlineSequence position, ControlFlowGraph cfg) { 172 block = new BasicBlock(loc, position, cfg); 173 low = loc; 174 high = loc; 175 } 176 177 // Only for use by subclasses to avoid above constructor. 178 protected BasicBlockLE(int loc) { low = loc; } 179 180 /** 181 * Returns a string representation of this BBLE. 182 */ 183 @Override 184 public String toString() { 185 if (isGenerated()) { 186 return "(" + low + "," + high + "," + max + ")"; 187 } 188 if (isReadyToGenerate()) { 189 return "{" + low + "," + max + "}"; 190 } 191 return "[" + low + "," + max + "]"; 192 } 193 194 /** 195 * Returns a string representation of state that determines if the BBLE 196 * is ready to be generated */ 197 public String genState() { 198 return "(sk=" + isStackKnown() + ", lk=" + isLocalKnown() + ", gen=" + isGenerated() + ")"; 199 } 200 }