Search in sources :

Example 1 with BitVector

use of soot.util.BitVector in project soot by Sable.

the class HybridPointsToSet method intersection.

public static HybridPointsToSet intersection(final HybridPointsToSet set1, final HybridPointsToSet set2, PAG pag) {
    final HybridPointsToSet ret = new HybridPointsToSet(Scene.v().getObjectType(), pag);
    BitVector s1Bits = set1.bits;
    BitVector s2Bits = set2.bits;
    if (s1Bits == null || s2Bits == null) {
        if (s1Bits != null) {
            // set2 is smaller
            set2.forall(new P2SetVisitor() {

                @Override
                public void visit(Node n) {
                    if (set1.contains(n))
                        ret.add(n);
                }
            });
        } else {
            // set1 smaller, or both small
            set1.forall(new P2SetVisitor() {

                @Override
                public void visit(Node n) {
                    if (set2.contains(n))
                        ret.add(n);
                }
            });
        }
    } else {
        // both big; do bit-vector operation
        // potential issue: if intersection is small, might
        // use inefficient bit-vector operations later
        ret.bits = BitVector.and(s1Bits, s2Bits);
        ret.empty = false;
    }
    return ret;
}
Also used : BitVector(soot.util.BitVector) Node(soot.jimple.spark.pag.Node)

Example 2 with BitVector

use of soot.util.BitVector in project soot by Sable.

the class SharedHybridSet method nativeAddAll.

private boolean nativeAddAll(SharedHybridSet other, SharedHybridSet exclude) {
    /*
		 * If one of the shared hybrid sets has a bitvector but the other
		 * doesn't, set that bitvector as the base bitvector and add the stuff
		 * from the other overflow list. If they both have a bitvector, AND them
		 * together, then add it to the lookupMap. If neither of them has a
		 * bitvector, just combine the overflow lists.
		 */
    BitVector mask = getBitMask(other, pag);
    if (exclude != null) {
        if (exclude.overflow.size() > 0) {
            // Make exclude only a bitvector, for simplicity
            PointsToBitVector newBitVector;
            if (exclude.bitVector == null) {
                newBitVector = new PointsToBitVector(pag.getAllocNodeNumberer().size());
            } else {
                newBitVector = new PointsToBitVector(exclude.bitVector);
            }
            add(newBitVector, exclude.overflow);
            exclude = new SharedHybridSet(type, pag);
            exclude.bitVector = newBitVector;
        } else // in that case.
        if (exclude.bitVector == null)
            exclude = null;
    }
    int originalSize = size(), originalOnes = originalSize - overflow.size(), otherBitVectorSize = other.size() - other.overflow.size();
    // Decide on the base bitvector
    if (bitVector == null) {
        bitVector = other.bitVector;
        if (bitVector != null) {
            // Maybe both bitvectors were null; in
            // that case, no need to do this
            bitVector.incRefCount();
            // Since merging in new bits might add elements that
            // were
            // already in the overflow list, we have to remove and re-add
            // them all.
            // TODO: Can this be avoided somehow?
            // Maybe by allowing an element to be both in the overflow set
            // and
            // the bitvector?
            // Or could it be better done by checking just the bitvector and
            // removing elements that are there?
            OverflowList toReAdd = overflow;
            overflow = new OverflowList();
            // whether a new bit vector
            boolean newBitVectorCreated = false;
            // was created, which is used to decide whether to re-add the
            // overflow list as an overflow list again or merge it into the
            // new bit vector.
            numElements = otherBitVectorSize;
            if (exclude != null || mask != null) {
                PointsToBitVector result = new PointsToBitVector(bitVector);
                if (exclude != null)
                    result.andNot(exclude.bitVector);
                if (mask != null)
                    result.and(mask);
                if (!result.equals(bitVector)) {
                    add(result, toReAdd);
                    int newBitVectorSize = result.cardinality();
                    numElements = newBitVectorSize;
                    findAppropriateBitVector(result, other.bitVector, otherBitVectorSize, otherBitVectorSize);
                    newBitVectorCreated = true;
                }
            }
            if (// if it was, then toReAdd has
            !newBitVectorCreated) // already been re-added
            {
                for (OverflowList.ListNode i = toReAdd.overflow; i != null; i = i.next) {
                    add(i.elem);
                }
            }
        }
    } else if (other.bitVector != null) {
        // Now both bitvectors are non-null; merge them
        PointsToBitVector newBitVector = new PointsToBitVector(other.bitVector);
        if (exclude != null)
            newBitVector.andNot(exclude.bitVector);
        if (mask != null)
            newBitVector.and(mask);
        newBitVector.or(bitVector);
        if (// if some elements were
        !newBitVector.equals(bitVector)) // actually added
        {
            if (other.overflow.size() != 0) {
                PointsToBitVector toAdd = new PointsToBitVector(newBitVector.size());
                add(toAdd, other.overflow);
                if (mask != null)
                    toAdd.and(mask);
                if (exclude != null)
                    toAdd.andNot(exclude.bitVector);
                newBitVector.or(toAdd);
            }
            // At this point newBitVector is still bitVector + some new bits
            // # of bits in the
            int numOnes = newBitVector.cardinality();
            // new bitvector
            int numAdded = add(newBitVector, overflow);
            numElements += // number of new bits
            numOnes - originalOnes + numAdded - // might be negative due to
            overflow.size();
            if (size() > originalSize) {
                findAppropriateBitVector(newBitVector, other.bitVector, otherBitVectorSize, originalOnes);
                // checkSize();
                return true;
            } else {
                // It might happen that the bitvector being merged in adds some bits
                return false;
            // to the existing bitvector, but that those new bits are all elements that were already
            // in the overflow list.  In that case, the set might not change, and if not we return false.
            // We also leave the set the way it was by not calling findAppropriateBitvector,
            // which maximizes sharing and is fastest in the short term.  I'm not sure whether it
            // would be faster overall to keep the already calculated bitvector anyway.
            }
        }
    }
    // Add all the elements in the overflow list of other, unless they're in
    // exclude
    OverflowList overflow = other.overflow;
    for (OverflowList.ListNode i = overflow.overflow; i != null; i = i.next) {
        // for (int i = 0; i < overflow.size(); ++i) {
        Node nodeToMaybeAdd = i.elem;
        if ((exclude == null) || !exclude.contains(nodeToMaybeAdd)) {
            if (mask == null || mask.get(nodeToMaybeAdd.getNumber())) {
                add(nodeToMaybeAdd);
            }
        }
    }
    // checkSize();
    return size() > originalSize;
}
Also used : BitVector(soot.util.BitVector) Node(soot.jimple.spark.pag.Node)

Example 3 with BitVector

use of soot.util.BitVector in project soot by Sable.

the class TypeResolverBV method remove_transitive_constraints.

private void remove_transitive_constraints() throws TypeException {
    refresh_solved();
    BitVector list = new BitVector();
    list.or(solved);
    list.or(unsolved);
    for (BitSetIterator varIt = list.iterator(); varIt.hasNext(); ) {
        final TypeVariableBV var = typeVariableForId(varIt.next());
        var.removeIndirectRelations();
    }
}
Also used : BitVector(soot.util.BitVector) BitSetIterator(soot.util.BitSetIterator)

Example 4 with BitVector

use of soot.util.BitVector in project soot by Sable.

the class TypeResolverBV method compute_solved.

private void compute_solved() {
    unsolved = new BitVector();
    solved = new BitVector();
    for (TypeVariableBV var : typeVariableList) {
        if (var.depth() == 0) {
            if (var.type() == null) {
                unsolved.set(var.id());
            } else {
                solved.set(var.id());
            }
        }
    }
}
Also used : BitVector(soot.util.BitVector)

Example 5 with BitVector

use of soot.util.BitVector in project soot by Sable.

the class TypeResolverBV method merge_connected_components.

private void merge_connected_components() throws TypeException {
    refresh_solved();
    BitVector list = new BitVector();
    list.or(solved);
    list.or(unsolved);
    new StronglyConnectedComponentsBV(list, this);
}
Also used : BitVector(soot.util.BitVector)

Aggregations

BitVector (soot.util.BitVector)24 SootClass (soot.SootClass)4 AllocNode (soot.jimple.spark.pag.AllocNode)4 BitSetIterator (soot.util.BitSetIterator)4 Node (soot.jimple.spark.pag.Node)3 AnySubType (soot.AnySubType)2 ArrayType (soot.ArrayType)2 NullType (soot.NullType)2 RefLikeType (soot.RefLikeType)2 RefType (soot.RefType)2 Type (soot.Type)2 TypeManager (soot.jimple.spark.internal.TypeManager)2 Iterator (java.util.Iterator)1 LinkedList (java.util.LinkedList)1 DoubleType (soot.DoubleType)1 FloatType (soot.FloatType)1 IntType (soot.IntType)1 LongType (soot.LongType)1