/** Set the current variable defined state. */ public void setDefined(Bits newDefined) { if (alive && newDefined != state.defined) { Bits diff = new Bits(state.defined).xorSet(newDefined); for (int adr = diff.nextBit(0); adr >= 0; adr = diff.nextBit(adr+1)) { if (adr >= nextreg) state.defined.excl(adr); else if (state.defined.isMember(adr)) setUndefined(adr); else setDefined(adr); } } }
public void visitAssert(JCAssert tree) { final Bits initsExit = new Bits(inits); final Bits uninitsExit = new Bits(uninits); scanCond(tree.cond); uninitsExit.andSet(uninitsWhenTrue); if (tree.detail != null) { inits.assign(initsWhenFalse); uninits.assign(uninitsWhenFalse); scanExpr(tree.detail); } inits.assign(initsExit); uninits.assign(uninitsExit); }
/** Set the current variable defined state. */ public void setDefined(Bits newDefined) { if (alive && newDefined != state.defined) { Bits diff = state.defined.dup().xorSet(newDefined); for (int adr = diff.nextBit(0); adr >= 0; adr = diff.nextBit(adr+1)) { if (adr >= nextreg) state.defined.excl(adr); else if (state.defined.isMember(adr)) setUndefined(adr); else setDefined(adr); } } }
public void visitForeachLoop(JCEnhancedForLoop tree) { visitVarDef(tree.var); ListBuffer<PendingExit> prevPendingExits = pendingExits; boolean prevLoopPassTwo = loopPassTwo; int nextadrPrev = nextadr; scan(tree.expr); Bits initsStart = inits.dup(); Bits uninitsStart = uninits.dup(); letInit(tree.pos(), tree.var.sym); pendingExits = new ListBuffer<PendingExit>(); do { Bits uninitsEntry = uninits.dup(); scanStat(tree.body); alive |= resolveContinues(tree); if (log.nerrors != 0 || loopPassTwo || uninitsEntry.diffSet(uninits).nextBit(firstadr) == -1) break; uninits = uninitsEntry.andSet(uninits); loopPassTwo = true; alive = true; } while (true); loopPassTwo = prevLoopPassTwo; inits = initsStart; uninits = uninitsStart.andSet(uninits); resolveBreaks(tree, prevPendingExits); alive = true; nextadr = nextadrPrev; }
FlowKind prevFlowKind = flowKind; flowKind = FlowKind.NORMAL; final Bits initsSkip = new Bits(true); final Bits uninitsSkip = new Bits(true); pendingExits = new ListBuffer<>(); int prevErrors = log.nerrors; do { final Bits uninitsEntry = new Bits(uninits); uninitsEntry.excludeFrom(nextadr); scan(tree.body); resolveContinues(tree); scanCond(tree.cond); if (!flowKind.isFinal()) { initsSkip.assign(initsWhenFalse); uninitsSkip.assign(uninitsWhenFalse); new Bits(uninitsEntry).diffSet(uninitsWhenTrue).nextBit(firstadr)==-1) break; inits.assign(initsWhenTrue); uninits.assign(uninitsEntry.andSet(uninitsWhenTrue)); flowKind = FlowKind.SPECULATIVE_LOOP; } while (true); flowKind = prevFlowKind; inits.assign(initsSkip); uninits.assign(uninitsSkip); resolveBreaks(tree, prevPendingExits);
/** Test Bits.nextBit(int). */ public static void main(String[] args) { java.util.Random r = new java.util.Random(); Bits bits = new Bits(); int dupCount = 0; for (int i=0; i<125; i++) { int k; do { k = r.nextInt(250); } while (bits.isMember(k)); System.out.println("adding " + k); bits.incl(k); } int count = 0; for (int i = bits.nextBit(0); i >= 0; i = bits.nextBit(i+1)) { System.out.println("found " + i); count ++; } if (count != 125) throw new Error(); } }
private Bits generalOp(Bits xs, int i, BitsOpKind opKind) { Assert.check(currentState != BitsState.UNKNOWN); oldBits = dupBits(); stateBeforeOp = currentState; switch (opKind) { case AND_SET: super.andSet(xs); break; case OR_SET: super.orSet(xs); break; case XOR_SET: super.xorSet(xs); break; case DIFF_SET: super.diffSet(xs); break; case CLEAR: super.clear(); break; case EXCL_BIT: super.excl(i); break; case EXCL_RANGE: super.excludeFrom(i); break; } changed(); return this; }
ListBuffer<PendingExit> prevPendingExits = pendingExits; pendingExits = new ListBuffer<PendingExit>(); Bits initsTry = inits.dup(); uninitsTry = uninits.dup(); scanStat(tree.body); List<Type> thrownInTry = thrown; caught = caughtPrev; boolean aliveEnd = alive; uninitsTry.andSet(uninits); Bits initsEnd = inits; Bits uninitsEnd = uninits; inits = initsTry.dup(); uninits = uninitsTry.dup(); scan(param); inits.incl(param.sym.adr); uninits.excl(param.sym.adr); scanStat(l.head.body); initsEnd.andSet(inits); uninitsEnd.andSet(uninits); nextadr = nextadrCatch; aliveEnd |= alive; List<Type> savedThrown = thrown; thrown = List.nil(); inits = initsTry.dup(); uninits = uninitsTry.dup(); ListBuffer<PendingExit> exits = pendingExits;
/** Exclude [start...end] from this set. */ public void excludeFrom(int start) { Assert.check(currentState != BitsState.UNKNOWN); Bits temp = new Bits(); temp.sizeTo(bits.length); temp.inclRange(0, start); internalAndSet(temp); currentState = BitsState.NORMAL; }
public void visitTry(JCTry tree) { ListBuffer<JCVariableDecl> resourceVarDecls = new ListBuffer<>(); final Bits uninitsTryPrev = new Bits(uninitsTry); ListBuffer<AssignPendingExit> prevPendingExits = pendingExits; pendingExits = new ListBuffer<>(); final Bits initsTry = new Bits(inits); uninitsTry.assign(uninits); for (JCTree resource : tree.resources) { if (resource instanceof JCVariableDecl) { uninitsTry.andSet(uninits); final Bits initsEnd = new Bits(inits); final Bits uninitsEnd = new Bits(uninits); int nextadrCatch = nextadr; final Bits initsCatchPrev = new Bits(initsTry); final Bits uninitsCatchPrev = new Bits(uninitsTry); inits.assign(initsCatchPrev); uninits.assign(uninitsCatchPrev); scan(param); initsEnd.andSet(inits); uninitsEnd.andSet(uninits); nextadr = nextadrCatch; inits.assign(initsTry); uninits.assign(uninitsTry); ListBuffer<AssignPendingExit> exits = pendingExits; pendingExits = prevPendingExits;
public AbstractAssignAnalyzer(Bits inits, Symtab syms, Names names) { this.inits = inits; uninits = new Bits(); uninitsTry = new Bits(); initsWhenTrue = new Bits(true); initsWhenFalse = new Bits(true); uninitsWhenTrue = new Bits(true); uninitsWhenFalse = new Bits(true); this.syms = syms; this.names = names; }
public void visitAssert(JCAssert tree) { Bits initsExit = inits.dup(); Bits uninitsExit = uninits.dup(); scanCond(tree.cond); uninitsExit.andSet(uninitsWhenTrue); if (tree.detail != null) { inits = initsWhenFalse; uninits = uninitsWhenFalse; scanExpr(tree.detail); } inits = initsExit; uninits = uninitsExit; }
/** Analyze a condition. Make sure to set (un)initsWhenTrue(WhenFalse) * rather than (un)inits on exit. */ void scanCond(JCTree tree) { if (tree.type.isFalse()) { if (inits == null) merge(); initsWhenTrue = inits.dup(); initsWhenTrue.inclRange(firstadr, nextadr); uninitsWhenTrue = uninits.dup(); uninitsWhenTrue.inclRange(firstadr, nextadr); initsWhenFalse = inits; uninitsWhenFalse = uninits; } else if (tree.type.isTrue()) { if (inits == null) merge(); initsWhenFalse = inits.dup(); initsWhenFalse.inclRange(firstadr, nextadr); uninitsWhenFalse = uninits.dup(); uninitsWhenFalse.inclRange(firstadr, nextadr); initsWhenTrue = inits; uninitsWhenTrue = uninits; } else { scan(tree); if (inits != null) split(); } inits = uninits = null; }
/** Analyze a condition. Make sure to set (un)initsWhenTrue(WhenFalse) * rather than (un)inits on exit. */ void scanCond(JCTree tree) { if (tree.type.isFalse()) { if (inits.isReset()) merge(tree); initsWhenTrue.assign(inits); initsWhenTrue.inclRange(firstadr, nextadr); uninitsWhenTrue.assign(uninits); uninitsWhenTrue.inclRange(firstadr, nextadr); initsWhenFalse.assign(inits); uninitsWhenFalse.assign(uninits); } else if (tree.type.isTrue()) { if (inits.isReset()) merge(tree); initsWhenFalse.assign(inits); initsWhenFalse.inclRange(firstadr, nextadr); uninitsWhenFalse.assign(uninits); uninitsWhenFalse.inclRange(firstadr, nextadr); initsWhenTrue.assign(inits); uninitsWhenTrue.assign(uninits); } else { scan(tree); if (!inits.isReset()) split(tree.type != syms.unknownType); } if (tree.type != syms.unknownType) { resetBits(inits, uninits); } }