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.ssa;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.RegisterSpec;
20fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dx.rop.code.RegisterSpecSet;
21fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dx.util.MutabilityControl;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.HashMap;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.List;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Container for local variable information for a particular {@link
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * com.android.dx.ssa.SsaMethod}.
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Stolen from {@link com.android.dx.rop.code.LocalVariableInfo}.
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class LocalVariableInfo         extends MutabilityControl {
3199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code >= 0;} the register count for the method */
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final int regCount;
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
3599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code non-null;} {@link com.android.dx.rop.code.RegisterSpecSet} to use when indicating a block
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * that has no locals; it is empty and immutable but has an appropriate
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * max size for the method
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final RegisterSpecSet emptySet;
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
4299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code non-null;} array consisting of register sets representing the
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * sets of variables already assigned upon entry to each block,
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * where array indices correspond to block indices
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final RegisterSpecSet[] blockStarts;
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
4899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} map from instructions to the variable each assigns */
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final HashMap<SsaInsn, RegisterSpec> insnAssignments;
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an instance.
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
5499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param method {@code non-null;} the method being represented by this instance
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public LocalVariableInfo(SsaMethod method) {
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (method == null) {
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("method == null");
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        List<SsaBasicBlock> blocks = method.getBlocks();
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.regCount = method.getRegCount();
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.emptySet = new RegisterSpecSet(regCount);
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.blockStarts = new RegisterSpecSet[blocks.size()];
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.insnAssignments =
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            new HashMap<SsaInsn, RegisterSpec>(/*hint here*/);
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        emptySet.setImmutable();
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets the register set associated with the start of the block with
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the given index.
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
7699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param index {@code >= 0;} the block index
7799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param specs {@code non-null;} the register set to associate with the block
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setStarts(int index, RegisterSpecSet specs) {
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throwIfImmutable();
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (specs == null) {
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("specs == null");
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            blockStarts[index] = specs;
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (ArrayIndexOutOfBoundsException ex) {
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Translate the exception.
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException("bogus index");
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Merges the given register set into the set for the block with the
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * given index. If there was not already an associated set, then this
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * is the same as calling {@link #setStarts}. Otherwise, this will
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * merge the two sets and call {@link #setStarts} on the result of the
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * merge.
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
10199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param index {@code >= 0;} the block index
10299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param specs {@code non-null;} the register set to merge into the start set
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * for the block
10499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code true} if the merge resulted in an actual change
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * to the associated set (including storing one for the first time) or
10699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code false} if there was no change
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean mergeStarts(int index, RegisterSpecSet specs) {
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RegisterSpecSet start = getStarts0(index);
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean changed = false;
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (start == null) {
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            setStarts(index, specs);
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return true;
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RegisterSpecSet newStart = start.mutableCopy();
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newStart.intersect(specs, true);
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (start.equals(newStart)) {
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newStart.setImmutable();
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        setStarts(index, newStart);
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return true;
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the register set associated with the start of the block
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * with the given index. This returns an empty set with the appropriate
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * max size if no set was associated with the block in question.
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
13599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param index {@code >= 0;} the block index
13699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the associated register set
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public RegisterSpecSet getStarts(int index) {
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RegisterSpecSet result = getStarts0(index);
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (result != null) ? result : emptySet;
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the register set associated with the start of the given
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * block. This is just convenient shorthand for
14799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code getStarts(block.getLabel())}.
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
14999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param block {@code non-null;} the block in question
15099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the associated register set
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public RegisterSpecSet getStarts(SsaBasicBlock block) {
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return getStarts(block.getIndex());
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets a mutable copy of the register set associated with the
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * start of the block with the given index. This returns a
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * newly-allocated empty {@link RegisterSpecSet} of appropriate
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * max size if there is not yet any set associated with the block.
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
16299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param index {@code >= 0;} the block index
16399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the associated register set
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public RegisterSpecSet mutableCopyOfStarts(int index) {
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RegisterSpecSet result = getStarts0(index);
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (result != null) ?
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result.mutableCopy() : new RegisterSpecSet(regCount);
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Adds an assignment association for the given instruction and
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * register spec. This throws an exception if the instruction
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * doesn't actually perform a named variable assignment.
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <b>Note:</b> Although the instruction contains its own spec for
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the result, it still needs to be passed in explicitly to this
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * method, since the spec that is stored here should always have a
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * simple type and the one in the instruction can be an arbitrary
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@link com.android.dx.rop.type.TypeBearer} (such as a constant value).
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
18399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param insn {@code non-null;} the instruction in question
18499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param spec {@code non-null;} the associated register spec
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void addAssignment(SsaInsn insn, RegisterSpec spec) {
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throwIfImmutable();
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (insn == null) {
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("insn == null");
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (spec == null) {
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("spec == null");
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        insnAssignments.put(insn, spec);
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the named register being assigned by the given instruction, if
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * previously stored in this instance.
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
20499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param insn {@code non-null;} instruction in question
20599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code null-ok;} the named register being assigned, if any
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public RegisterSpec getAssignment(SsaInsn insn) {
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return insnAssignments.get(insn);
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the number of assignments recorded by this instance.
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
21499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= 0;} the number of assignments
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getAssignmentCount() {
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return insnAssignments.size();
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void debugDump() {
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int index = 0 ; index < blockStarts.length; index++) {
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (blockStarts[index] == null) {
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                continue;
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (blockStarts[index] == emptySet) {
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                System.out.printf("%04x: empty set\n", index);
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                System.out.printf("%04x: %s\n", index, blockStarts[index]);
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Helper method, to get the starts for a index, throwing the
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * right exception for range problems.
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
23899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param index {@code >= 0;} the block index
23999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code null-ok;} associated register set or {@code null} if there
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * is none
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private RegisterSpecSet getStarts0(int index) {
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return blockStarts[index];
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (ArrayIndexOutOfBoundsException ex) {
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Translate the exception.
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException("bogus index");
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
251