1 11 package org.eclipse.jdt.internal.compiler.codegen; 12 13 import java.util.Arrays ; 14 15 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 16 import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; 17 18 public class BranchLabel extends Label { 19 20 private int[] forwardReferences = new int[10]; private int forwardReferenceCount = 0; 22 BranchLabel delegate; 24 public int tagBits; 26 public final static int WIDE = 1; 27 public final static int USED = 2; 28 29 public BranchLabel() { 30 } 32 33 36 public BranchLabel(CodeStream codeStream) { 37 super(codeStream); 38 } 39 40 43 void addForwardReference(int pos) { 44 if (this.delegate != null) { 45 this.delegate.addForwardReference(pos); 46 return; 47 } 48 final int count = this.forwardReferenceCount; 49 if (count >= 1) { 50 int previousValue = this.forwardReferences[count - 1]; 51 if (previousValue < pos) { 52 int length; 53 if (count >= (length = this.forwardReferences.length)) 54 System.arraycopy(this.forwardReferences, 0, (this.forwardReferences = new int[2*length]), 0, length); 55 this.forwardReferences[this.forwardReferenceCount++] = pos; 56 } else if (previousValue > pos) { 57 int[] refs = this.forwardReferences; 58 for (int i = 0, max = this.forwardReferenceCount; i < max; i++) { 60 if (refs[i] == pos) return; } 62 int length; 63 if (count >= (length = refs.length)) 64 System.arraycopy(refs, 0, (this.forwardReferences = new int[2*length]), 0, length); 65 this.forwardReferences[this.forwardReferenceCount++] = pos; 66 Arrays.sort(this.forwardReferences, 0, this.forwardReferenceCount); 67 } 68 } else { 69 int length; 70 if (count >= (length = this.forwardReferences.length)) 71 System.arraycopy(this.forwardReferences, 0, (this.forwardReferences = new int[2*length]), 0, length); 72 this.forwardReferences[this.forwardReferenceCount++] = pos; 73 } 74 } 75 76 79 public void becomeDelegateFor(BranchLabel otherLabel) { 80 otherLabel.delegate = this; 82 83 final int otherCount = otherLabel.forwardReferenceCount; 85 if (otherCount == 0) return; 86 int[] mergedForwardReferences = new int[this.forwardReferenceCount + otherCount]; 88 int indexInMerge = 0; 89 int j = 0; 90 int i = 0; 91 int max = this.forwardReferenceCount; 92 int max2 = otherLabel.forwardReferenceCount; 93 loop1 : for (; i < max; i++) { 94 final int value1 = this.forwardReferences[i]; 95 for (; j < max2; j++) { 96 final int value2 = otherLabel.forwardReferences[j]; 97 if (value1 < value2) { 98 mergedForwardReferences[indexInMerge++] = value1; 99 continue loop1; 100 } else if (value1 == value2) { 101 mergedForwardReferences[indexInMerge++] = value1; 102 j++; 103 continue loop1; 104 } else { 105 mergedForwardReferences[indexInMerge++] = value2; 106 } 107 } 108 mergedForwardReferences[indexInMerge++] = value1; 109 } 110 for (; j < max2; j++) { 111 mergedForwardReferences[indexInMerge++] = otherLabel.forwardReferences[j]; 112 } 113 this.forwardReferences = mergedForwardReferences; 114 this.forwardReferenceCount = indexInMerge; 115 } 116 117 120 void branch() { 121 this.tagBits |= BranchLabel.USED; 122 if (this.delegate != null) { 123 this.delegate.branch(); 124 return; 125 } 126 if (this.position == Label.POS_NOT_SET) { 127 addForwardReference(this.codeStream.position); 128 this.codeStream.position += 2; 130 this.codeStream.classFileOffset += 2; 131 } else { 132 135 this.codeStream.writePosition(this); 136 } 137 } 138 139 142 void branchWide() { 143 this.tagBits |= BranchLabel.USED; 144 if (this.delegate != null) { 145 this.delegate.branchWide(); 146 return; 147 } 148 if (this.position == Label.POS_NOT_SET) { 149 addForwardReference(this.codeStream.position); 150 this.tagBits |= BranchLabel.WIDE; 152 this.codeStream.position += 4; 153 this.codeStream.classFileOffset += 4; 154 } else { this.codeStream.writeWidePosition(this); 156 } 157 } 158 159 public int forwardReferenceCount() { 160 if (this.delegate != null) this.delegate.forwardReferenceCount(); 161 return forwardReferenceCount; 162 } 163 public int[] forwardReferences() { 164 if (this.delegate != null) this.delegate.forwardReferences(); 165 return forwardReferences; 166 } 167 public void initialize(CodeStream stream) { 168 this.codeStream = stream; 169 this.position = Label.POS_NOT_SET; 170 this.forwardReferenceCount = 0; 171 this.delegate = null; 172 } 173 public boolean isCaseLabel() { 174 return false; 175 } 176 public boolean isStandardLabel(){ 177 return true; 178 } 179 180 183 public void place() { if (CodeStream.DEBUG) System.out.println("\t\t\t\t<place at: "+this.codeStream.position+" - "+ this); 189 if (this.position == Label.POS_NOT_SET) { 191 if ((this.tagBits & BranchLabel.USED) != 0 || this.forwardReferenceCount != 0) { 192 this.position = this.codeStream.getPosition(); 193 } else { 194 this.position = this.codeStream.position; 195 } 196 this.codeStream.addLabel(this); 197 int oldPosition = this.position; 198 boolean isOptimizedBranch = false; 199 if (this.forwardReferenceCount != 0) { 200 isOptimizedBranch = (this.forwardReferences[this.forwardReferenceCount - 1] + 2 == this.position) && (this.codeStream.bCodeStream[this.codeStream.classFileOffset - 3] == Opcodes.OPC_goto); 201 if (isOptimizedBranch) { 202 if (this.codeStream.lastAbruptCompletion == this.position) { 203 this.codeStream.lastAbruptCompletion = -1; 204 } 205 this.codeStream.position = (this.position -= 3); 206 this.codeStream.classFileOffset -= 3; 207 this.forwardReferenceCount--; 208 if (this.codeStream.lastEntryPC == oldPosition) { 209 this.codeStream.lastEntryPC = this.position; 210 } 211 if ((this.codeStream.generateAttributes & (ClassFileConstants.ATTR_VARS | ClassFileConstants.ATTR_STACK_MAP)) != 0) { 213 LocalVariableBinding locals[] = this.codeStream.locals; 214 for (int i = 0, max = locals.length; i < max; i++) { 215 LocalVariableBinding local = locals[i]; 216 if ((local != null) && (local.initializationCount > 0)) { 217 if (local.initializationPCs[((local.initializationCount - 1) << 1) + 1] == oldPosition) { 218 local.initializationPCs[((local.initializationCount - 1) << 1) + 1] = this.position; 221 } 222 if (local.initializationPCs[(local.initializationCount - 1) << 1] == oldPosition) { 223 local.initializationPCs[(local.initializationCount - 1) << 1] = this.position; 224 } 225 } 226 } 227 } 228 if ((this.codeStream.generateAttributes & ClassFileConstants.ATTR_LINES) != 0) { 229 this.codeStream.removeUnusedPcToSourceMapEntries(); 231 } 232 } 233 } 234 for (int i = 0; i < this.forwardReferenceCount; i++) { 235 this.codeStream.writePosition(this, this.forwardReferences[i]); 236 } 237 if (isOptimizedBranch) { 241 this.codeStream.optimizeBranch(oldPosition, this); 242 } 243 } 244 } 245 246 249 public String toString() { 250 String basic = getClass().getName(); 251 basic = basic.substring(basic.lastIndexOf('.')+1); 252 StringBuffer buffer = new StringBuffer (basic); 253 buffer.append('@').append(Integer.toHexString(hashCode())); 254 buffer.append("(position=").append(this.position); if (this.delegate != null) buffer.append("delegate=").append(this.delegate); buffer.append(", forwards = ["); for (int i = 0; i < this.forwardReferenceCount - 1; i++) 258 buffer.append(this.forwardReferences[i] + ", "); if (this.forwardReferenceCount >= 1) 260 buffer.append(this.forwardReferences[this.forwardReferenceCount-1]); 261 buffer.append("] )"); return buffer.toString(); 263 } 264 } 265 | Popular Tags |