Esempio n. 1
0
char* CompiledLoop::findUpperBound() {
  // find upper bound and loop variable
  int condBCI = findStartOfSend(_endOfCond->bci() - InterpretedIC::size);
  if (condBCI == IllegalBCI) return "loop condition: no send found";
  // first find comparison in loop condition
  Expr* loopCond = _scope->exprStackElems()->at(condBCI);
  if (loopCond == NULL) return "loop condition: no expr (possible compiler bug)";
  if (loopCond->isMergeExpr()) {
    MergeExpr* cond = (MergeExpr*)loopCond;
    if (cond->isSplittable()) {
      Node* first = cond->exprs->first()->node();
      if (first->nPredecessors() == 1) {
        Node* prev = first->firstPrev();
        if (prev->isBranchNode()) _loopBranch = (BranchNode*)prev;
      }
    }
  }
  if (!_loopBranch) return "loop condition: conditional branch not found";
  NonTrivialNode* n = (NonTrivialNode*)_loopBranch->firstPrev();
  PReg* operand;
  if (n->isTArithNode()) {
    operand = ((TArithRRNode*)n)->operand();
  } else if (n->isArithNode()) {
    operand = ((ArithRRNode*)n)->operand();
  } else {
    return "loop condition: comparison not found";
  }
  BranchOpCode op = _loopBranch->op();

  // Now see if it's a simple comparison involving the loop variable
  // and make an initial guess about the loop variable.
  // NB: code generator inverts loop condition, i.e., branch leaves loop
  if (op == LTBranchOp || op == LEBranchOp) {
    // upperBound > loopVar
    _loopVar = operand;
    _upperBound = n->src();
  } else if (op == GTBranchOp || op == GEBranchOp) {
    // loopVar < upperBound
    _loopVar = n->src();
    _upperBound = operand;
  } else {
    return "loop condition: not oneof(<, <=, >, >=)";
  }

  // The above code assumes a loop counting up; check the loopVar now and switch
  // directions if it doesn't work.
  if (checkLoopVar()) {
    // the reverse guess may be wrong too, but it doesn't hurt to try
    PReg* temp = _loopVar; _loopVar = _upperBound; _upperBound = temp;
  }
  return NULL;
}
Esempio n. 2
0
int InterpretedIC::findStartOfSend(methodOop m, int bci) {
  u_char* p = findStartOfSend(m->codes(bci));
  return (p == NULL) ? IllegalBCI : p - m->codes() + 1;
}