All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.umd.cs.findbugs.ba.vna.ValueNumber Maven / Gradle / Ivy

The newest version!
/*
 * Bytecode Analysis Framework
 * Copyright (C) 2003,2004 University of Maryland
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package edu.umd.cs.findbugs.ba.vna;

import edu.umd.cs.findbugs.util.MapCache;
import edu.umd.cs.findbugs.util.Util;

/**
 * 

A "value number" is a value produced somewhere in a methods. We use value * numbers as dataflow values in Frames. When two frame slots have the same * value number, then the same value is in both of those slots. *

*

* Instances of ValueNumbers produced by the same {@link ValueNumberFactory * ValueNumberFactory} are unique, so reference equality may be used to * determine whether or not two value numbers are the same. In general, * ValueNumbers from different factories cannot be compared.

* * @author David Hovemeyer * @see ValueNumberAnalysis */ public class ValueNumber implements Comparable { static MapCache cache = new MapCache<>(200); static int valueNumbersCreated = 0; static int valueNumbersReused = 0; public static int mergeFlags(int flags1, int flags2) { if (flags1 == -1) { return flags2; } if (flags2 == -1) { return flags1; } return flags1 & flags2; } public static synchronized ValueNumber createValueNumber(int number, int flags) { ValueNumber probe = new ValueNumber(number, flags); ValueNumber result = cache.get(probe); if (result != null) { valueNumbersReused++; return result; } cache.put(probe, probe); valueNumbersCreated++; return probe; } public static ValueNumber createValueNumber(int number) { return createValueNumber(number, 0); } static { Util.runLogAtShutdown(() -> System.out.println("Value number statistics: " + valueNumbersCreated + " created, " + valueNumbersReused + " reused")); } /** * The value number. */ final int number; /** * Flags representing meta information about the value. When value numbers are merged, * their flags should be the flags common to both. */ final int flags; /** * Flag specifying that this value was the return value of a called method. */ public static final int RETURN_VALUE = 1; public static final int ARRAY_VALUE = 2; public static final int CONSTANT_CLASS_OBJECT = 4; public static final int PHI_NODE = 8; public static final int CONSTANT_VALUE = 16; /** * Constructor. * * @param number * the value number */ private ValueNumber(int number) { this.number = number; this.flags = 0; } private ValueNumber(int number, int flags) { this.number = number; this.flags = flags; } public int getNumber() { return number; } public int getFlags() { return flags; } public boolean hasFlag(int flag) { return (flags & flag) == flag; } @Override public String toString() { if (flags != 0) { return number + "(" + flags + "),"; } return number + ","; } @Override public int hashCode() { return number * 17 + flags; } @Override public boolean equals(Object o) { if (o instanceof ValueNumber) { return number == ((ValueNumber) o).number && flags == ((ValueNumber) o).flags; } return false; } @Override public int compareTo(ValueNumber other) { int result = number - other.number; if (result != 0) { return result; } return flags - other.flags; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy