Files
SDK_RK3288/art/compiler/dex/reference_map_calculator.h

133 lines
5.3 KiB
C++

/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ART_COMPILER_DEX_REFERENCE_MAP_CALCULATOR_H_
#define ART_COMPILER_DEX_REFERENCE_MAP_CALCULATOR_H_
#include "compiler_internals.h"
#include "pass_me.h"
namespace art {
/**
* @brief Pass is used to recalculate GC maps.
* @details This is needed in presence of optimizations that remove writes to reference
* registers and also in presence of optimizations using compiler temporaries.
*/
class ReferenceMapCalculator : public PassME {
public:
ReferenceMapCalculator() : PassME("ReferenceMapCalculator", kNoNodes) {
default_options_.Put("CrossCheckMaps", OptionContent(0));
}
/**
* @brief Used to control whether the pass needs to run.
* @param data The pass data.
* @return Returns true if pass should apply.
*/
virtual bool Gate(const PassDataHolder* data) const;
/**
* @brief Used to prepare structures and then iterates through all blocks to calculate
* reference information.
* @param data The pass data.
*/
virtual void Start(PassDataHolder* data) const;
protected:
/**
* @brief Helper data structure for pass to hold information about MIRs and object references.
*/
struct ReferenceMapDataHolder {
SafeMap<MIR*, ArenaBitVector*> mir_to_ref_vrs; /**!< Map of instructions to live reference bitmaps. */
std::set<MIR*> mirs_with_check; /**!< The instructions that are split into two halves. */
};
/**
* @brief Used for verbosity to print the compiler generated reference map at each suspend point.
* @param c_unit The compilation unit.
* @param ref_data The pass data.
*/
void LogReferenceMap(CompilationUnit* c_unit, ReferenceMapDataHolder* ref_data) const;
/**
* @brief This is used to fix case of overlapping offsets. This is done
* because each suspend point may have a different map.
* @details When overlapping offsets are found, a new is requested from
* MIRGraph.
* @param mir_graph The MIRGraph.
* @param ref_data The pass data.
*/
void CheckAndFixOffsetProblem(MIRGraph* mir_graph, ReferenceMapDataHolder* ref_data) const;
/**
* @brief Used to walk through all generated GC maps and add them to the MIRGraph.
* @param mir_graph The MIRGraph.
* @param ref_data The pass data.
*/
void AddGCMapsToMirGraph(MIRGraph* mir_graph, ReferenceMapDataHolder* ref_data) const;
/**
* @brief Useful for debugging by checking the generated GC map against original.
* @details There may be false positives because a reference dies as its use
* while verifier may see it live for longer.
* @param mir_graph The MIRGraph.
* @param ref_data The pass data.
*/
void CrossCheckGCMap(MIRGraph* mir_graph, ReferenceMapDataHolder* ref_data) const;
/**
* @brief Used to check whether an instruction will generate a safepoint.
* @details The logic here takes into account whether instruction has been broken
* up into a check half. This is because the safepoints are expressed at that point
* in the control flow graph. So if an instruction has a check half, the check
* will say it has safepoints while the instruction will say it does not.
* @param mir_graph The MIRGraph.
* @param mir The instruction to check if it has safepoints.
* @param ref_data This holds a list of instructions that have a kMirOpCheck half.
* @return Returns whether the instruction will generate a safepoint.
*/
bool HasSafepoint(MIRGraph* mir_graph, MIR* mir, ReferenceMapDataHolder* ref_data) const;
/**
* @brief This is used to find the instructions with kMirOpCheck opcode.
* @param bb The basic block to check.
* @param ref_data This holds a list that is updated by this function to contain
* the instruction for which the kMirOpCheck instruction corresponds to.
*/
void FindCheckInstructions(BasicBlock* bb, ReferenceMapDataHolder* ref_data) const;
/**
* @brief Used to calculate the reference maps for instructions in basic block.
* @details The algorithm that is used is as follows:
* -#) Go through the successors and calculate union of all live-in vrs.
* -#) Determine the current BB live out ssa registers by using the successor
* live-in information.
* -#) Record only the set of reference ssa registers. Keep this as working set.
* -#) Walk through the instructions backwards.
* -#) For each instruction, remove the define from working set. But add all
* reference ssa registers to the working set. This covers all live ssa reference
* registers up to this point.
* @param data The pass data.
* @return Always returns false because it does not change the control flow graph.
*/
bool CalculateBBRefInfo(MIRGraph* mir_graph, BasicBlock* bb, ReferenceMapDataHolder* ref_data) const;
};
} // namespace art
#endif // ART_COMPILER_DEX_REFERENCE_MAP_CALCULATOR_H_