Exemplo n.º 1
0
static bool validate_sget(DexMethod* context, DexOpcodeField* opfield) {
  auto opcode = opfield->opcode();
  switch (opcode) {
  case OPCODE_SGET_WIDE:
    unhandled_inline++;
    return false;
  case OPCODE_SGET:
  case OPCODE_SGET_BOOLEAN:
  case OPCODE_SGET_BYTE:
  case OPCODE_SGET_CHAR:
  case OPCODE_SGET_SHORT:
    return true;
  default:
    auto field = resolve_field(opfield->field(), FieldSearch::Static);
    always_assert_log(field->is_concrete(), "Must be a concrete field");
    auto value = field->get_static_value();
    always_assert_log(
        false,
        "Unexpected field type in inline_*sget %s for field %s value %s in "
        "method %s\n",
        SHOW(opfield),
        SHOW(field),
        value != nullptr ? value->show().c_str() : "('nullptr')",
        SHOW(context));
  }
  return false;
}
Exemplo n.º 2
0
static int
setup_bounds(struct node *node)
{
	node->upper_bound = max_value;

	if (is_qsearch(node)) {
		node->lower_bound = get_static_value(node);
		if (node->lower_bound >= node->beta) {
			node->value = node->lower_bound;
			return stand_pat_cutoff;
		}
	}
	else {
		node->lower_bound = -max_value;
	}

	// if a side has only a king left, the best value it can get is zero
	if (node->root_distance > 0) {
		if (is_singular(node->pos->map[1]))
			node->lower_bound = max(0, node->lower_bound);

		// no need to use "min(0, node->upper_bound)",
		// upper_bound is not affected before this
		if (is_singular(node->pos->map[0]))
			node->upper_bound = 0;
	}

	return 0;
}
Exemplo n.º 3
0
void inline_sget(DexMethod* method, DexOpcodeField* opfield) {
  if (!validate_sget(method, opfield)) return;
  auto opcode = OPCODE_CONST;
  auto dest = opfield->dest();
  auto field = resolve_field(opfield->field(), FieldSearch::Static);
  always_assert_log(field->is_concrete(), "Must be a concrete field");
  auto value = field->get_static_value();
  /* FIXME for sget_wide case */
  uint32_t v = value != nullptr ? (uint32_t)value->value() : 0;

  auto newopcode = (new DexInstruction(opcode))->set_dest(dest)->set_literal(v);
  replace_opcode(method, opfield, newopcode);
}
Exemplo n.º 4
0
static int
adjust_depth(struct node *node)
{
	// Don't touch the depth of the root node!
	if (node->root_distance == 0)
		return 0;

	node->depth += node->forced_extension;

	if (node->root_distance >= node_array_length - 1) {
		// search space exploding exponentially?
		// forced static eval, cut tree at this depth
		node->value = get_static_value(node);
		return too_deep;
	}

	if (node->depth < PLY && node->depth > 0)
		node->depth = PLY;

	return 0;
}
Exemplo n.º 5
0
void inline_cheap_sget(DexMethod* method, DexOpcodeField* opfield) {
  if (!validate_sget(method, opfield)) return;
  auto dest = opfield->dest();
  auto field = resolve_field(opfield->field(), FieldSearch::Static);
  always_assert_log(field->is_concrete(), "Must be a concrete field");
  auto value = field->get_static_value();
  /* FIXME for sget_wide case */
  uint32_t v = value != nullptr ? (uint32_t)value->value() : 0;
  auto opcode = [&] {
    if ((v & 0xffff) == v) {
      return OPCODE_CONST_16;
    } else if ((v & 0xffff0000) == v) {
      return OPCODE_CONST_HIGH16;
    }
    always_assert_log(false,
                      "Bad inline_cheap_sget queued up, can't fit to"
                      " CONST_16 or CONST_HIGH16, bailing\n");
  }();

  auto newopcode = (new DexInstruction(opcode, 0))->set_dest(dest)->set_literal(v);
  replace_opcode(method, opfield, newopcode);
}
Exemplo n.º 6
0
static int
try_null_move_prune(struct node *node)
{
	if (!node->common->sd.settings.use_null_moves)
		return 0;

	if (node->forced_pv != 0)
		return 0;

	if (ht_entry_prevents_null_move(node, node->deep_entry))
		return 0;

	if (ht_entry_prevents_null_move(node, node->fresh_entry))
		return 0;

	if (node->has_repetition_in_history)
		return 0;

	int advantage = get_static_value(node) - node->beta;

	if ((node->root_distance == 0)
	    || node[-1].is_in_null_move_search
	    || (node->expected_type == PV_node)
	    || (advantage < - 100)
	    || (node->depth <= 4 * PLY)
	    || (node->depth > 7 * PLY && advantage < 0)
	    || is_in_check(node->pos)
	    || (node->mo->count < 18))
		return 0;

	if (advantage < 0 && opponent_has_positive_capture(node))
		return 0;

	if (node->non_pawn_move_count < 9
	    || node->non_pawn_move_piece_count < 2)
		return 0;

	struct node *child = node + 1;

	position_flip(child->pos, node->pos);

	int required = node->beta;
	if (node->depth < 9 * PLY)
		required += ((node->depth - 4 * PLY) * pawn_value) / PLY;
	else
		required += 5 * pawn_value;

	child->has_repetition_in_history = false;
	child->is_GHI_barrier = true;
	child->expected_type = all_node;
	child->alpha = -required - 1;
	child->beta = -required;

	child->depth = node->depth - PLY - 3 * PLY;
	if (child->depth < PLY)
		child->depth = PLY;

	node->is_in_null_move_search = true;
	debug_trace_tree_push_move(node, 0);
	int value = negamax_child(node);
	debug_trace_tree_pop_move(node);
	node->is_in_null_move_search = false;

	if (value > required && value <= mate_value) {
		node->value = node->beta;
		return prune_successfull;
	}
	else {
		node->null_move_search_failed = true;
	}

	return 0;
}