void ValueStack::clear_stores() {
  ValueStack* stack = this;
  while (stack != NULL) {
    for (int i = 0; i < stack->_stores.length(); i++) stack->_stores.at_put(i, NULL);
    stack = stack->caller_state();
  }
}
Example #2
0
void Scumm::v6::Scummv6StoreInstruction::processInst(Function&, ValueStack &stack, Engine*, CodeGenerator *codeGen) {
	Scummv6CodeGenerator *cg = (Scummv6CodeGenerator *)codeGen;
	switch (_opcode) {
	case 0x42: // writeByteVar
	case 0x43: // writeWordVar
		{
        ValuePtr p = new VarValue(cg->decodeVarName(static_cast<uint16>(_params[0]->getUnsigned())));
			cg->writeAssignment(p, stack.pop());
		}
		break;
	case 0x46: // byteArrayWrite
	case 0x47: // wordArrayWrite
		{
			ValuePtr value = stack.pop();
			ValueList idxs;
			idxs.push_back(stack.pop());
            ValuePtr p = new ArrayValue(cg->decodeArrayName(static_cast<uint16>(_params[0]->getUnsigned())), idxs);
			cg->writeAssignment(p, value);
		}
		break;
	case 0x4A: // byteArrayIndexedWrite
	case 0x4B: // wordArrayIndexedWrite
		{
			ValuePtr value = stack.pop();
			ValueList idxs;
			idxs.push_front(stack.pop());
			idxs.push_front(stack.pop());
            ValuePtr p = new ArrayValue(cg->decodeArrayName(static_cast<uint16>(_params[0]->getUnsigned())), idxs);
			cg->writeAssignment(p, value);
		}
		break;
	}
}
void ValueStack::eliminate_all_scope_stores(int bci) {
  ValueStack* stack = this;
  while (stack != NULL) {
    stack->eliminate_stores(bci);
    stack = stack->caller_state();
  }
}
Example #4
0
void Scumm::v6::Scummv6ArrayOpInstruction::processInst(Function&, ValueStack &stack, Engine*, CodeGenerator *codeGen) {
	Scummv6CodeGenerator *cg = (Scummv6CodeGenerator *)codeGen;
	switch (_opcode) {
	case 0xA4CD: // arrayOp_assignString
		{
			ValuePtr value = _params[1];
			ValueList idxs;
			idxs.push_front(stack.pop());
            ValuePtr p = new ArrayValue(cg->decodeArrayName(static_cast<uint16>(_params[0]->getUnsigned())), idxs);
			cg->writeAssignment(p, value);
		}
		break;
	case 0xA4D0: // arrayOp_assignIntList
		{
			ValueList idxs;
			idxs.push_front(stack.pop());
			ValuePtr value = cg->createListValue();
            ValuePtr p = new ArrayValue(cg->decodeArrayName(static_cast<uint16>(_params[0]->getUnsigned())), idxs);
			cg->writeAssignment(p, value);
		}
		break;
	case 0xA4D4: // arrayOp_assign2DimList
		{
			ValueList idxs;
			idxs.push_front(stack.pop());
			ValuePtr value = cg->createListValue();
			idxs.push_front(stack.pop());
            ValuePtr p = new ArrayValue(cg->decodeArrayName(static_cast<uint16>(_params[0]->getUnsigned())), idxs);
			cg->writeAssignment(p, value);
		}
		break;
	}
}
ValueStack* ValueStack::push_scope(IRScope* scope) {
  assert(scope->caller() == _scope, "scopes must have caller/callee relationship");
  ValueStack* res = new ValueStack(scope,
                                   scope->method()->max_locals(),
                                   max_stack_size() + scope->method()->max_stack());
  // Preserves stack and monitors.
  res->_stack.appendAll(&_stack);
  res->_locks.appendAll(&_locks);
  assert(res->_stack.size() <= res->max_stack_size(), "stack overflow");
  return res;
}
// Index caller states in s, where 0 is the oldest, 1 its callee, etc.
// Return NULL if n is too large.
// Returns the caller_bci for the next-younger state, also.
static ValueStack* nth_oldest(ValueStack* s, int n, int& bci_result) {
    ValueStack* t = s;
    for (int i = 0; i < n; i++) {
        if (t == NULL)  break;
        t = t->caller_state();
    }
    if (t == NULL)  return NULL;
    for (;;) {
        ValueStack* tc = t->caller_state();
        if (tc == NULL)  return s;
        t = tc;
        bci_result = tc->bci();
        s = s->caller_state();
    }
}
Example #7
0
void Scumm::v6::Scummv6IncDecInstruction::processInst(Function&, ValueStack &stack, Engine*, CodeGenerator *codeGen) {
	Scummv6CodeGenerator *cg = (Scummv6CodeGenerator *)codeGen;
	switch (_opcode) {
	case 0x4E: // byteVarInc
	case 0x4F: // wordVarInc
	case 0x56: // byteVarDec
	case 0x57: // wordVarDec
		{
			std::stringstream s;
			ValuePtr p = new UnaryOpValue(new VarValue(cg->decodeVarName(static_cast<uint16>(_params[0]->getUnsigned()))), _codeGenData, true);
			s << p << ";";
			cg->addOutputLine(s.str());
		}
		break;
	case 0x52: // byteArrayInc
	case 0x53: // wordArrayInc
	case 0x5A: // byteArrayDec
	case 0x5B: // wordArrayDec
		{
			std::stringstream s;
			ValueList idxs;
			idxs.push_front(stack.pop());
            ValuePtr p = new UnaryOpValue(new ArrayValue(cg->decodeVarName(static_cast<uint16>(_params[0]->getUnsigned())), idxs), _codeGenData, true);
			s << p << ";";
			cg->addOutputLine(s.str());
		}
		break;
	}
}
Example #8
0
bool lua_details::listVirtualStack(lua_State* L, ValueStack& stack, size_t table_size_limit)
{
	int size= lua_gettop(L);

	stack.clear();
	stack.reserve(size);

	for (int idx= size - 1; idx > 0; --idx)
	{
		Value v(L, idx, 1, table_size_limit);

		stack.push_back(v);
	}

	return true;
}
void CFGPrinterOutput::print_state(BlockBegin* block) {
  print_begin("states");

  InstructionPrinter ip(true, output());

  ValueStack* state = block->state();
  int index;
  Value value;

  if (state->stack_size() > 0) {
    print_begin("stack");
    print("size %d", state->stack_size());

    for_each_stack_value(state, index, value) {
      ip.print_phi(index, value, block);
      print_operand(value);
      output()->cr();
    }
Example #10
0
void Scumm::v6::Scummv6LoadInstruction::processInst(Function&, ValueStack &stack, Engine*, CodeGenerator *codeGen) {
	Scummv6CodeGenerator *cg = (Scummv6CodeGenerator *)codeGen;
	switch (_opcode) {
	case 0x00: // pushByte
	case 0x01: // pushWord
		stack.push(_params[0]);
		break;
	case 0x02: // pushByteVar
	case 0x03: // pushWordVar
        stack.push(new VarValue(cg->decodeVarName(static_cast<uint16>(_params[0]->getUnsigned()))));
		break;
	case 0x06: // byteArrayRead
	case 0x07: // wordArrayRead
		{
			ValueList idxs;
			idxs.push_front(stack.pop());
            stack.push(new ArrayValue(cg->decodeArrayName(static_cast<uint16>(_params[0]->getUnsigned())), idxs));
			break;
		}
	case 0x0A: // byteArrayIndexedRead
	case 0x0B: // wordArrayIndexedRead
		{
			ValueList idxs;
			idxs.push_front(stack.pop());
			idxs.push_front(stack.pop());
            stack.push(new ArrayValue(cg->decodeArrayName(static_cast<uint16>(_params[0]->getUnsigned())), idxs));
			break;
		}
	}
}
void CFGPrinterOutput::print_state(BlockBegin* block) {
  print_begin("states");

  InstructionPrinter ip(true, output());

  ValueStack* state = block->state();
  int index;
  Value value;

  for_each_state(state) {
    print_begin("locals");
    print("size %d", state->locals_size());
    print("method \"%s\"", method_name(state->scope()->method()));

    for_each_local_value(state, index, value) {
      ip.print_phi(index, value, block);
      print_operand(value);
      output()->cr();
    }
    print_end("locals");

    if (state->stack_size() > 0) {
      print_begin("stack");
      print("size %d", state->stack_size());
      print("method \"%s\"", method_name(state->scope()->method()));

      for_each_stack_value(state, index, value) {
        ip.print_phi(index, value, block);
        print_operand(value);
        output()->cr();
      }
Example #12
0
void LIR_Assembler::record_non_safepoint_debug_info() {
  int         pc_offset = _pending_non_safepoint_offset;
  ValueStack* vstack    = debug_info(_pending_non_safepoint);
  int         bci       = vstack->bci();

  DebugInformationRecorder* debug_info = compilation()->debug_info_recorder();
  assert(debug_info->recording_non_safepoints(), "sanity");

  debug_info->add_non_safepoint(pc_offset);

  // Visit scopes from oldest to youngest.
  for (int n = 0; ; n++) {
    int s_bci = bci;
    ValueStack* s = nth_oldest(vstack, n, s_bci);
    if (s == NULL)  break;
    IRScope* scope = s->scope();
    //Always pass false for reexecute since these ScopeDescs are never used for deopt
    debug_info->describe_scope(pc_offset, scope->method(), s->bci(), false/*reexecute*/);
  }

  debug_info->end_non_safepoint(pc_offset);
}
Example #13
0
Value expression::eval(Value &ret)
{


	
	ValueStack  valstack;
	String str_oper;
	str_oper="oper";
    	POSITION pos=m_postfix.get_top_position();
    	for(; pos; pos=m_postfix.get_next(pos)){
        	const char*s=m_postfix.get(pos);
		if(s[0]=='%' || isalpha(s[0]) )
		{
			//ValueRef vref(getworld()->var_get(s));			
			valstack.add(getworld()->var_get(s));
		}
		else if (isdigit(s[0])){

			valstack.add()=str_to_real(s);
			
		}
		else {
			_oper* p;
			if(s[0]=='\'')
			         p=getworld()->oper_get(s+1);
			else 
				p=getworld()->oper_get(str_oper+s);
			
			p->eval(valstack) ;
		}
	}
	
	ret=valstack.get_last();
	valstack.remove();
	return ret;
			
		
	
}
ValueStack* ValueStack::pop_scope(bool should_eliminate_stores, int bci) {
  assert(_scope->caller() != NULL, "scope must have caller");
  IRScope* scope = _scope->caller();
  int max_stack = max_stack_size() - _scope->method()->max_stack();
  assert(max_stack >= 0, "stack underflow");
  ValueStack* res = new ValueStack(scope,
                                   scope->method()->max_locals(),
                                   max_stack);
  // Preserves stack and monitors. Restores local and store state from caller scope.
  res->_stack.appendAll(&_stack);
  res->_locks.appendAll(&_locks);
  ValueStack* caller = caller_state();
  if (caller != NULL) {
    for (int i = 0; i < caller->_locals.length(); i++) {
      res->_locals.at_put(i, caller->_locals.at(i));
      res->_stores.at_put(i, caller->_stores.at(i));
    }
    assert(res->_locals.length() == res->scope()->method()->max_locals(), "just checking");
    assert(res->_stores.length() == res->scope()->method()->max_locals(), "just checking");
  }
  assert(res->_stack.size() <= res->max_stack_size(), "stack overflow");
  if (EliminateStores && should_eliminate_stores) eliminate_stores(bci);
  return res;
}
Example #15
0
void Scumm::v6::Scummv6StackInstruction::processInst(Function&, ValueStack &stack, Engine*, CodeGenerator*) {
	stack.pop();
}
Example #16
0
void Scumm::v6::Scummv6CondJumpInstruction::processInst(Function&, ValueStack &stack, Engine*, CodeGenerator*) {
	if (_opcode == 0x5D) // jumpFalse
		stack.push(stack.pop()->negate());
}
Example #17
0
void LoopInvariantCodeMotion::process_block(BlockBegin* block) {
  TRACE_VALUE_NUMBERING(tty->print_cr("processing block B%d", block->block_id()));

  Instruction* prev = block;
  Instruction* cur = block->next();

  while (cur != NULL) {

    // determine if cur instruction is loop invariant
    // only selected instruction types are processed here
    bool cur_invariant = false;

    if (cur->as_Constant() != NULL) {
      cur_invariant = !cur->can_trap();
    } else if (cur->as_ArithmeticOp() != NULL || cur->as_LogicOp() != NULL || cur->as_ShiftOp() != NULL) {
      assert(cur->as_Op2() != NULL, "must be Op2");
      Op2* op2 = (Op2*)cur;
      cur_invariant = !op2->can_trap() && is_invariant(op2->x()) && is_invariant(op2->y());
    } else if (cur->as_LoadField() != NULL) {
      LoadField* lf = (LoadField*)cur;
      // deoptimizes on NullPointerException
      cur_invariant = !lf->needs_patching() && !lf->field()->is_volatile() && !_short_loop_optimizer->has_field_store(lf->field()->type()->basic_type()) && is_invariant(lf->obj()) && _insert_is_pred;
    } else if (cur->as_ArrayLength() != NULL) {
      ArrayLength *length = cur->as_ArrayLength();
      cur_invariant = is_invariant(length->array());
    } else if (cur->as_LoadIndexed() != NULL) {
      LoadIndexed *li = (LoadIndexed *)cur->as_LoadIndexed();
      cur_invariant = !_short_loop_optimizer->has_indexed_store(as_BasicType(cur->type())) && is_invariant(li->array()) && is_invariant(li->index()) && _insert_is_pred;
    }

    if (cur_invariant) {
      // perform value numbering and mark instruction as loop-invariant
      _gvn->substitute(cur);

      if (cur->as_Constant() == NULL) {
        // ensure that code for non-constant instructions is always generated
        cur->pin();
      }

      // remove cur instruction from loop block and append it to block before loop
      Instruction* next = cur->next();
      Instruction* in = _insertion_point->next();
      _insertion_point = _insertion_point->set_next(cur);
      cur->set_next(in);

      //  Deoptimize on exception
      cur->set_flag(Instruction::DeoptimizeOnException, true);

      //  Clear exception handlers
      cur->set_exception_handlers(NULL);

      TRACE_VALUE_NUMBERING(tty->print_cr("Instruction %c%d is loop invariant", cur->type()->tchar(), cur->id()));

      if (cur->state_before() != NULL) {
        cur->set_state_before(_state->copy());
      }
      if (cur->exception_state() != NULL) {
        cur->set_exception_state(_state->copy());
      }

      cur = prev->set_next(next);

    } else {
      prev = cur;
      cur = cur->next();
    }
  }
}
void InstructionPrinter::do_BlockBegin(BlockBegin* x) {
  // print block id
  BlockEnd* end = x->end();
  output()->print("B%d ", x->block_id());

  // print flags
  bool printed_flag = false;
  if (x->is_set(BlockBegin::std_entry_flag)) {
    if (!printed_flag) output()->print("(");
    output()->print("S"); printed_flag = true;
  }
  if (x->is_set(BlockBegin::osr_entry_flag)) {
    if (!printed_flag) output()->print("(");
    output()->print("O"); printed_flag = true;
  }
  if (x->is_set(BlockBegin::exception_entry_flag)) {
    if (!printed_flag) output()->print("(");
    output()->print("E"); printed_flag = true;
  }
  if (x->is_set(BlockBegin::subroutine_entry_flag)) {
    if (!printed_flag) output()->print("(");
    output()->print("s"); printed_flag = true;
  }
  if (x->is_set(BlockBegin::parser_loop_header_flag)) {
    if (!printed_flag) output()->print("(");
    output()->print("LH"); printed_flag = true;
  }
  if (x->is_set(BlockBegin::backward_branch_target_flag)) {
    if (!printed_flag) output()->print("(");
    output()->print("b"); printed_flag = true;
  }
  if (x->is_set(BlockBegin::was_visited_flag)) {
    if (!printed_flag) output()->print("(");
    output()->print("V"); printed_flag = true;
  }
  if (printed_flag) output()->print(") ");

  // print block bci range
output()->print("[%d, %d]",x->bci(),(end==NULL?InvocationEntryBci:end->bci()));

  // print block successors
  if (end != NULL && end->number_of_sux() > 0) {
    output()->print(" ->");
    for (int i = 0; i < end->number_of_sux(); i++) {
      output()->print(" B%d", end->sux_at(i)->block_id());
    }
  }
  // print exception handlers
  if (x->number_of_exception_handlers() > 0) {
    output()->print(" (xhandlers ");
    for (int i = 0; i < x->number_of_exception_handlers();  i++) {
      if (i > 0) output()->print(" ");
      output()->print("B%d", x->exception_handler_at(i)->block_id());
    }
    output()->put(')');
  }

  // print dominator block
  if (x->dominator() != NULL) {
    output()->print(" dom B%d", x->dominator()->block_id());
  }

  // print predecessors and successors
  if (x->successors()->length() > 0) {
    output()->print(" sux:");
    for (int i = 0; i < x->successors()->length(); i ++) {
      output()->print(" B%d", x->successors()->at(i)->block_id());
    }
  }

  if (x->number_of_preds() > 0) {
    output()->print(" pred:");
    for (int i = 0; i < x->number_of_preds(); i ++) {
      output()->print(" B%d", x->pred_at(i)->block_id());
    }
  }

  if (!_print_phis) {
    return;
  }

  // print phi functions
  bool has_phis_in_locals = false;
  bool has_phis_on_stack = false;

  if (x->end() && x->end()->state()) {
    ValueStack* state = x->state();

    int i = 0;
    while (!has_phis_on_stack && i < state->stack_size()) {
      Value v = state->stack_at_inc(i);
      has_phis_on_stack = is_phi_of_block(v, x);
    }

    do {
      for (i = 0; !has_phis_in_locals && i < state->locals_size();) {
        Value v = state->local_at(i);
        has_phis_in_locals = is_phi_of_block(v, x);
        // also ignore illegal HiWords
        if (v && !v->type()->is_illegal()) i += v->type()->size(); else i ++;
      }
      state = state->caller_state();
    } while (state != NULL);

  }

  // print values in locals
  if (has_phis_in_locals) {
    output()->cr(); output()->print_cr("Locals:");

    ValueStack* state = x->state();
    do {
      for (int i = 0; i < state->locals_size();) {
        Value v = state->local_at(i);
        if (v) {
          print_phi(i, v, x); output()->cr();
          // also ignore illegal HiWords
          i += (v->type()->is_illegal() ? 1 : v->type()->size());
        } else {
          i ++;
        }
      }
      output()->cr();
      state = state->caller_state();
    } while (state != NULL);
  }

  // print values on stack
  if (has_phis_on_stack) {
    output()->print_cr("Stack:");
    int i = 0;
    while (i < x->state()->stack_size()) {
      int o = i;
      Value v = x->state()->stack_at_inc(i);
      if (v) {
        print_phi(o, v, x); output()->cr();
      }
    }
  }
}