BlockAddresses.java revision 2ad60cfc28e14ee8f0bb038720836a4696c478ad
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 2007 The Android Open Source Project
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License");
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * you may not use this file except in compliance with the License.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * You may obtain a copy of the License at
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      http://www.apache.org/licenses/LICENSE-2.0
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Unless required by applicable law or agreed to in writing, software
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS,
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See the License for the specific language governing permissions and
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * limitations under the License.
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)package com.android.dx.dex.code;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import com.android.dx.rop.code.BasicBlock;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import com.android.dx.rop.code.BasicBlockList;
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import com.android.dx.rop.code.Insn;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import com.android.dx.rop.code.RopMethod;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import com.android.dx.rop.code.SourcePosition;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Container for the set of {@link CodeAddress} instances associated with
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the blocks of a particular method. Each block has a corresponding
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * start address, end address, and last instruction address.
29b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) */
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public final class BlockAddresses {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /** non-null; array containing addresses for the start of each basic
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * block (indexed by basic block label) */
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private final CodeAddress[] starts;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /** non-null; array containing addresses for the final instruction
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * of each basic block (indexed by basic block label) */
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private final CodeAddress[] lasts;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /** non-null; array containing addresses for the end (just past the
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * final instruction) of each basic block (indexed by basic block
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * label) */
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private final CodeAddress[] ends;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Constructs an instance.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param method non-null; the method to have block addresses for
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public BlockAddresses(RopMethod method) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BasicBlockList blocks = method.getBlocks();
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int maxLabel = blocks.getMaxLabel();
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.starts = new CodeAddress[maxLabel];
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.lasts = new CodeAddress[maxLabel];
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.ends = new CodeAddress[maxLabel];
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        setupArrays(method);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Gets the instance for the start of the given block.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param block non-null; the block in question
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @return non-null; the appropriate instance
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public CodeAddress getStart(BasicBlock block) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return starts[block.getLabel()];
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Gets the instance for the start of the block with the given label.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param label non-null; the label of the block in question
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @return non-null; the appropriate instance
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public CodeAddress getStart(int label) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return starts[label];
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Gets the instance for the final instruction of the given block.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param block non-null; the block in question
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @return non-null; the appropriate instance
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public CodeAddress getLast(BasicBlock block) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return lasts[block.getLabel()];
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Gets the instance for the final instruction of the block with
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * the given label.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param label non-null; the label of the block in question
95b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)     * @return non-null; the appropriate instance
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public CodeAddress getLast(int label) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return lasts[label];
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Gets the instance for the end (address after the final instruction)
103a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)     * of the given block.
104a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)     *
105a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)     * @param block non-null; the block in question
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @return non-null; the appropriate instance
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public CodeAddress getEnd(BasicBlock block) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ends[block.getLabel()];
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Gets the instance for the end (address after the final instruction)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * of the block with the given label.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param label non-null; the label of the block in question
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @return non-null; the appropriate instance
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public CodeAddress getEnd(int label) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ends[label];
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Sets up the address arrays.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private void setupArrays(RopMethod method) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BasicBlockList blocks = method.getBlocks();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int sz = blocks.size();
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (int i = 0; i < sz; i++) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            BasicBlock one = blocks.get(i);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int label = one.getLabel();
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            Insn insn = one.getInsns().get(0);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            starts[label] = new CodeAddress(insn.getPosition());
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SourcePosition pos = one.getLastInsn().getPosition();
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lasts[label] = new CodeAddress(pos);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ends[label] = new CodeAddress(pos);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)