1917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/*
2917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Copyright (C) 2007 The Android Open Source Project
3917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
4917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Licensed under the Apache License, Version 2.0 (the "License");
5917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * you may not use this file except in compliance with the License.
6917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * You may obtain a copy of the License at
7917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
8917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *      http://www.apache.org/licenses/LICENSE-2.0
9917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
10917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Unless required by applicable law or agreed to in writing, software
11917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * distributed under the License is distributed on an "AS IS" BASIS,
12917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * See the License for the specific language governing permissions and
14917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * limitations under the License.
15917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */
16917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
17917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpackage com.android.dexgen.dex.code;
18917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
19917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.code.BasicBlock;
20917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.code.BasicBlockList;
21917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.code.Insn;
22917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.code.RopMethod;
23917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.code.SourcePosition;
24917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
25917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/**
26917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Container for the set of {@link CodeAddress} instances associated with
27917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * the blocks of a particular method. Each block has a corresponding
28917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * start address, end address, and last instruction address.
29917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */
30917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpublic final class BlockAddresses {
31917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@code non-null;} array containing addresses for the start of each basic
32917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * block (indexed by basic block label) */
33917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private final CodeAddress[] starts;
34917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
35917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@code non-null;} array containing addresses for the final instruction
36917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * of each basic block (indexed by basic block label) */
37917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private final CodeAddress[] lasts;
38917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
39917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@code non-null;} array containing addresses for the end (just past the
40917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * final instruction) of each basic block (indexed by basic block
41917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * label) */
42917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private final CodeAddress[] ends;
43917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
44917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
45917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Constructs an instance.
46917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
47917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param method {@code non-null;} the method to have block addresses for
48917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
49917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public BlockAddresses(RopMethod method) {
50917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        BasicBlockList blocks = method.getBlocks();
51917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int maxLabel = blocks.getMaxLabel();
52917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
53917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        this.starts = new CodeAddress[maxLabel];
54917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        this.lasts = new CodeAddress[maxLabel];
55917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        this.ends = new CodeAddress[maxLabel];
56917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
57917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        setupArrays(method);
58917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
59917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
60917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
61917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Gets the instance for the start of the given block.
62917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
63917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param block {@code non-null;} the block in question
64917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the appropriate instance
65917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
66917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public CodeAddress getStart(BasicBlock block) {
67917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return starts[block.getLabel()];
68917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
69917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
70917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
71917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Gets the instance for the start of the block with the given label.
72917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
73917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param label {@code non-null;} the label of the block in question
74917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the appropriate instance
75917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
76917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public CodeAddress getStart(int label) {
77917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return starts[label];
78917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
79917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
80917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
81917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Gets the instance for the final instruction of the given block.
82917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
83917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param block {@code non-null;} the block in question
84917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the appropriate instance
85917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
86917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public CodeAddress getLast(BasicBlock block) {
87917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return lasts[block.getLabel()];
88917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
89917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
90917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
91917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Gets the instance for the final instruction of the block with
92917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * the given label.
93917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
94917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param label {@code non-null;} the label of the block in question
95917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the appropriate instance
96917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
97917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public CodeAddress getLast(int label) {
98917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return lasts[label];
99917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
100917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
101917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
102917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Gets the instance for the end (address after the final instruction)
103917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * of the given block.
104917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
105917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param block {@code non-null;} the block in question
106917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the appropriate instance
107917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
108917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public CodeAddress getEnd(BasicBlock block) {
109917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return ends[block.getLabel()];
110917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
111917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
112917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
113917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Gets the instance for the end (address after the final instruction)
114917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * of the block with the given label.
115917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
116917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param label {@code non-null;} the label of the block in question
117917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the appropriate instance
118917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
119917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public CodeAddress getEnd(int label) {
120917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return ends[label];
121917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
122917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
123917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
124917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Sets up the address arrays.
125917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
126917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private void setupArrays(RopMethod method) {
127917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        BasicBlockList blocks = method.getBlocks();
128917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int sz = blocks.size();
129917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
130917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        for (int i = 0; i < sz; i++) {
131917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            BasicBlock one = blocks.get(i);
132917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            int label = one.getLabel();
133917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            Insn insn = one.getInsns().get(0);
134917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
135917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            starts[label] = new CodeAddress(insn.getPosition());
136917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
137917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            SourcePosition pos = one.getLastInsn().getPosition();
138917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
139917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            lasts[label] = new CodeAddress(pos);
140917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            ends[label] = new CodeAddress(pos);
141917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
142917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
143917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul}
144