public void generateWideRevertedConditionalBranch(byte revertedOpcode, BranchLabel wideTarget) { BranchLabel intermediate = new BranchLabel(this); if (this.classFileOffset >= this.bCodeStream.length) { resizeByteArray(); } this.position++; this.bCodeStream[this.classFileOffset++] = revertedOpcode; intermediate.branch(); goto_w(wideTarget); intermediate.place(); }
void branchWide() { this.tagBits |= BranchLabel.USED; if (this.delegate != null) { this.delegate.branchWide(); return; } if (this.position == Label.POS_NOT_SET) { addForwardReference(this.codeStream.position); // Leave 4 bytes free to generate the jump offset afterwards this.tagBits |= BranchLabel.WIDE; this.codeStream.position += 4; this.codeStream.classFileOffset += 4; } else { //Position is set. Write it! this.codeStream.writeWidePosition(this); } }
/** * Dispatch the call on its last statement. */ public void branchChainTo(BranchLabel label) { // in order to improve debug attributes for stepping (11431) // we want to inline the jumps to #breakLabel which already got // generated (if any), and have them directly branch to a better // location (the argument label). // we know at this point that the breakLabel already got placed if (this.breakLabel.forwardReferenceCount() > 0) { label.becomeDelegateFor(this.breakLabel); } }
/** * Some placed labels might be branching to a goto bytecode which we can optimize better. */ public boolean inlineForwardReferencesFromLabelsTargeting(BranchLabel targetLabel, int gotoLocation) { if (targetLabel.delegate != null) return false; // already inlined int chaining = L_UNKNOWN; for (int i = this.countLabels - 1; i >= 0; i--) { BranchLabel currentLabel = this.labels[i]; if (currentLabel.position != gotoLocation) break; if (currentLabel == targetLabel) { chaining |= L_CANNOT_OPTIMIZE; // recursive continue; } if (currentLabel.isStandardLabel()) { if (currentLabel.delegate != null) continue; // ignore since already inlined targetLabel.becomeDelegateFor(currentLabel); chaining |= L_OPTIMIZABLE; // optimizable, providing no vetoing continue; } // case label chaining |= L_CANNOT_OPTIMIZE; } return (chaining & (L_OPTIMIZABLE|L_CANNOT_OPTIMIZE)) == L_OPTIMIZABLE; // check was some standards, and no case/recursive }
protected void writeWidePosition(BranchLabel label) { int labelPos = label.position; int offset = labelPos - this.position + 1; this.writeSignedWord(offset); int[] forwardRefs = label.forwardReferences(); for (int i = 0, max = label.forwardReferenceCount(); i < max; i++) { int forward = forwardRefs[i]; offset = labelPos - forward + 1; this.writeSignedWord(forward, offset); } } }
/** * Code generation for labeled statement * * may not need actual source positions recording * * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream */ public void generateCode(BlockScope currentScope, CodeStream codeStream) { if ((this.bits & IsReachable) == 0) { return; } int pc = codeStream.position; if (this.targetLabel != null) { this.targetLabel.initialize(codeStream); if (this.statement != null) { this.statement.generateCode(currentScope, codeStream); } this.targetLabel.place(); } // May loose some local variable initializations : affecting the local variable attributes if (this.mergedInitStateIndex != -1) { codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex); codeStream.addDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex); } codeStream.recordPositionsFrom(pc, this.sourceStart); }
BranchLabel actionLabel = new BranchLabel(codeStream); if (this.action != null) actionLabel.tagBits |= BranchLabel.USED; actionLabel.place(); this.breakLabel.initialize(codeStream); boolean hasContinueLabel = this.continueLabel != null; if (hasContinueLabel) { this.continueLabel.initialize(codeStream); this.continueLabel.place(); codeStream.addDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex); if (this.breakLabel.forwardReferenceCount() > 0) { this.breakLabel.place();
public void goto_w(BranchLabel label) { if (this.classFileOffset >= this.bCodeStream.length) { resizeByteArray(); } this.position++; this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_goto_w; label.branchWide(); this.lastAbruptCompletion = this.position; }
void branch() { this.tagBits |= BranchLabel.USED; if (this.delegate != null) { this.delegate.branch(); return; } if (this.position == Label.POS_NOT_SET) { addForwardReference(this.codeStream.position); // Leave two bytes free to generate the jump afterwards this.codeStream.position += 2; this.codeStream.classFileOffset += 2; } else { /* * Position is set. Write it if it is not a wide branch. */ this.codeStream.writePosition(this); } }
BranchLabel assertionActivationLabel = new BranchLabel(codeStream); codeStream.fieldAccess(Opcodes.OPC_getstatic, this.assertionSyntheticFieldBinding, null /* default declaringClass */); codeStream.ifne(assertionActivationLabel); this.assertExpression.generateOptimizedBoolean(currentScope, codeStream, (falseLabel = new BranchLabel(codeStream)), null , true); codeStream.newJavaLangAssertionError(); codeStream.dup(); codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preAssertInitStateIndex); falseLabel.place(); assertionActivationLabel.place(); } else {
/** * Case code generation * */ public void generateCode(BlockScope currentScope, CodeStream codeStream) { if ((this.bits & ASTNode.IsReachable) == 0) { return; } int pc = codeStream.position; this.targetLabel.place(); codeStream.recordPositionsFrom(pc, this.sourceStart); }
final public void jsr(BranchLabel lbl) { if (this.wideMode) { jsr_w(lbl); return; } this.countLabels = 0; if (this.classFileOffset >= this.bCodeStream.length) { resizeByteArray(); } this.position++; this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_jsr; lbl.branch(); }
public int[] forwardReferences() { if (this.delegate != null) this.delegate.forwardReferences(); return this.forwardReferences; } public void initialize(CodeStream stream) {
public int forwardReferenceCount() { if (this.delegate != null) this.delegate.forwardReferenceCount(); return this.forwardReferenceCount; } public int[] forwardReferences() {
this, this.label, (this.targetLabel = new BranchLabel()), currentScope)), flowInfo);
protected void writeWidePosition(BranchLabel label) { int labelPos = label.position; int offset = labelPos - this.position + 1; this.writeSignedWord(offset); int[] forwardRefs = label.forwardReferences(); for (int i = 0, max = label.forwardReferenceCount(); i < max; i++) { int forward = forwardRefs[i]; offset = labelPos - forward + 1; this.writeSignedWord(forward, offset); } } }
/** * Some placed labels might be branching to a goto bytecode which we can optimize better. */ public boolean inlineForwardReferencesFromLabelsTargeting(BranchLabel targetLabel, int gotoLocation) { if (targetLabel.delegate != null) return false; // already inlined int chaining = L_UNKNOWN; for (int i = this.countLabels - 1; i >= 0; i--) { BranchLabel currentLabel = this.labels[i]; if (currentLabel.position != gotoLocation) break; if (currentLabel == targetLabel) { chaining |= L_CANNOT_OPTIMIZE; // recursive continue; } if (currentLabel.isStandardLabel()) { if (currentLabel.delegate != null) continue; // ignore since already inlined targetLabel.becomeDelegateFor(currentLabel); chaining |= L_OPTIMIZABLE; // optimizable, providing no vetoing continue; } // case label chaining |= L_CANNOT_OPTIMIZE; } return (chaining & (L_OPTIMIZABLE|L_CANNOT_OPTIMIZE)) == L_OPTIMIZABLE; // check was some standards, and no case/recursive }
/** * Code generation for labeled statement * * may not need actual source positions recording * * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream */ public void generateCode(BlockScope currentScope, CodeStream codeStream) { if ((this.bits & IsReachable) == 0) { return; } int pc = codeStream.position; if (this.targetLabel != null) { this.targetLabel.initialize(codeStream); if (this.statement != null) { this.statement.generateCode(currentScope, codeStream); } this.targetLabel.place(); } // May loose some local variable initializations : affecting the local variable attributes if (this.mergedInitStateIndex != -1) { codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex); codeStream.addDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex); } codeStream.recordPositionsFrom(pc, this.sourceStart); }
BranchLabel actionLabel = new BranchLabel(codeStream); if (this.action != null) actionLabel.tagBits |= BranchLabel.USED; actionLabel.place(); this.breakLabel.initialize(codeStream); boolean hasContinueLabel = this.continueLabel != null; if (hasContinueLabel) { this.continueLabel.initialize(codeStream); this.continueLabel.place(); codeStream.addDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex); if (this.breakLabel.forwardReferenceCount() > 0) { this.breakLabel.place();
final public void jsr_w(BranchLabel lbl) { this.countLabels = 0; if (this.classFileOffset >= this.bCodeStream.length) { resizeByteArray(); } this.position++; this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_jsr_w; lbl.branchWide(); }