1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.rop.code;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeBearer;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.MutabilityControl;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.HashMap;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Container for local variable information for a particular {@link
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * RopMethod}.
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class LocalVariableInfo
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        extends MutabilityControl {
2999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code >= 0;} the register count for the method */
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final int regCount;
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
3399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code non-null;} {@link RegisterSpecSet} to use when indicating a block
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * that has no locals; it is empty and immutable but has an appropriate
35de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * max size for the method
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final RegisterSpecSet emptySet;
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
4099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code non-null;} array consisting of register sets representing the
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * sets of variables already assigned upon entry to each block,
42de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * where array indices correspond to block labels
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final RegisterSpecSet[] blockStarts;
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
4699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} map from instructions to the variable each assigns */
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final HashMap<Insn, RegisterSpec> insnAssignments;
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an instance.
51de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
5299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param method {@code non-null;} the method being represented by this instance
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public LocalVariableInfo(RopMethod method) {
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (method == null) {
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("method == null");
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        BasicBlockList blocks = method.getBlocks();
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int maxLabel = blocks.getMaxLabel();
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.regCount = blocks.getRegCount();
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.emptySet = new RegisterSpecSet(regCount);
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.blockStarts = new RegisterSpecSet[maxLabel];
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.insnAssignments =
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            new HashMap<Insn, RegisterSpec>(blocks.getInstructionCount());
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        emptySet.setImmutable();
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets the register set associated with the start of the block with
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the given label.
74de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
7599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param label {@code >= 0;} the block label
7699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param specs {@code non-null;} the register set to associate with the block
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setStarts(int label, RegisterSpecSet specs) {
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throwIfImmutable();
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (specs == null) {
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("specs == null");
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            blockStarts[label] = specs;
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (ArrayIndexOutOfBoundsException ex) {
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Translate the exception.
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException("bogus label");
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Merges the given register set into the set for the block with the
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * given label. If there was not already an associated set, then this
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * is the same as calling {@link #setStarts}. Otherwise, this will
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * merge the two sets and call {@link #setStarts} on the result of the
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * merge.
99de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
10099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param label {@code >= 0;} the block label
10199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param specs {@code non-null;} the register set to merge into the start set
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * for the block
10399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code true} if the merge resulted in an actual change
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * to the associated set (including storing one for the first time) or
10599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code false} if there was no change
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean mergeStarts(int label, RegisterSpecSet specs) {
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RegisterSpecSet start = getStarts0(label);
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean changed = false;
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (start == null) {
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            setStarts(label, specs);
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return true;
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RegisterSpecSet newStart = start.mutableCopy();
117b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao        if (start.size() != 0) {
118b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao            newStart.intersect(specs, true);
119b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao        } else {
120b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao            newStart = specs.mutableCopy();
121b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao        }
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (start.equals(newStart)) {
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newStart.setImmutable();
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        setStarts(label, newStart);
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return true;
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the register set associated with the start of the block
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * with the given label. This returns an empty set with the appropriate
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * max size if no set was associated with the block in question.
137de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
13899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param label {@code >= 0;} the block label
13999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the associated register set
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public RegisterSpecSet getStarts(int label) {
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RegisterSpecSet result = getStarts0(label);
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (result != null) ? result : emptySet;
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the register set associated with the start of the given
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * block. This is just convenient shorthand for
15099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code getStarts(block.getLabel())}.
151de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
15299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param block {@code non-null;} the block in question
15399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the associated register set
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public RegisterSpecSet getStarts(BasicBlock block) {
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return getStarts(block.getLabel());
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets a mutable copy of the register set associated with the
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * start of the block with the given label. This returns a
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * newly-allocated empty {@link RegisterSpecSet} of appropriate
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * max size if there is not yet any set associated with the block.
164de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
16599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param label {@code >= 0;} the block label
16699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the associated register set
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public RegisterSpecSet mutableCopyOfStarts(int label) {
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RegisterSpecSet result = getStarts0(label);
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (result != null) ?
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result.mutableCopy() : new RegisterSpecSet(regCount);
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Adds an assignment association for the given instruction and
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * register spec. This throws an exception if the instruction
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * doesn't actually perform a named variable assignment.
179de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <b>Note:</b> Although the instruction contains its own spec for
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the result, it still needs to be passed in explicitly to this
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * method, since the spec that is stored here should always have a
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * simple type and the one in the instruction can be an arbitrary
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@link TypeBearer} (such as a constant value).
185de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
18699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param insn {@code non-null;} the instruction in question
18799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param spec {@code non-null;} the associated register spec
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void addAssignment(Insn insn, RegisterSpec spec) {
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throwIfImmutable();
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (insn == null) {
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("insn == null");
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (spec == null) {
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("spec == null");
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        insnAssignments.put(insn, spec);
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the named register being assigned by the given instruction, if
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * previously stored in this instance.
206de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
20799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param insn {@code non-null;} instruction in question
20899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code null-ok;} the named register being assigned, if any
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public RegisterSpec getAssignment(Insn insn) {
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return insnAssignments.get(insn);
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the number of assignments recorded by this instance.
216de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
21799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= 0;} the number of assignments
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getAssignmentCount() {
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return insnAssignments.size();
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void debugDump() {
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int label = 0 ; label < blockStarts.length; label++) {
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (blockStarts[label] == null) {
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                continue;
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (blockStarts[label] == emptySet) {
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                System.out.printf("%04x: empty set\n", label);
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                System.out.printf("%04x: %s\n", label, blockStarts[label]);
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Helper method, to get the starts for a label, throwing the
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * right exception for range problems.
240de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
24199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param label {@code >= 0;} the block label
24299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code null-ok;} associated register set or {@code null} if there
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * is none
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private RegisterSpecSet getStarts0(int label) {
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return blockStarts[label];
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (ArrayIndexOutOfBoundsException ex) {
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Translate the exception.
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException("bogus label");
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
254