1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_TOOLS_DEXANALYZE_DEXANALYZE_BYTECODE_H_ 18 #define ART_TOOLS_DEXANALYZE_DEXANALYZE_BYTECODE_H_ 19 20 #include <array> 21 #include <vector> 22 #include <map> 23 24 #include "base/safe_map.h" 25 #include "dexanalyze_experiments.h" 26 #include "dex/code_item_accessors.h" 27 #include "dex/dex_file_types.h" 28 29 namespace art { 30 namespace dexanalyze { 31 32 enum BytecodeExperiment { 33 kExperimentInvoke, 34 kExperimentInstanceField, 35 kExperimentInstanceFieldSelf, 36 kExperimentStaticField, 37 kExperimentLocalType, 38 kExperimentReturn, 39 kExperimentSmallIf, 40 kExperimentString, 41 kExperimentSingleGetSet, 42 }; 43 44 // Maps from global index to local index. 45 struct TypeLinkage { 46 // Referenced types. 47 SafeMap<size_t, size_t> types_; 48 // Owned fields. 49 SafeMap<size_t, size_t> fields_; 50 // Owned methods. 51 SafeMap<size_t, size_t> methods_; 52 // Referenced strings. 53 SafeMap<size_t, size_t> strings_; 54 }; 55 56 class NewRegisterInstructions : public Experiment { 57 public: NewRegisterInstructions(uint64_t experiments)58 explicit NewRegisterInstructions(uint64_t experiments) 59 : experiments_(experiments), 60 move_result_reg_(256), 61 first_arg_reg_count_(256), 62 opcode_count_(256) {} 63 void ProcessDexFiles(const std::vector<std::unique_ptr<const DexFile>>& dex_files); 64 void Dump(std::ostream& os, uint64_t total_size) const; 65 66 void ProcessCodeItem(const DexFile& dex_file, 67 const CodeItemDataAccessor& code_item, 68 dex::TypeIndex current_class_type, 69 bool count_types, 70 std::map<size_t, TypeLinkage>& types); 71 void Add(Instruction::Code opcode, const Instruction& inst); 72 bool InstNibbles(uint8_t opcode, const std::vector<uint32_t>& args); 73 bool ExtendPrefix(uint32_t* value1, uint32_t* value2); Enabled(BytecodeExperiment experiment)74 bool Enabled(BytecodeExperiment experiment) const { 75 return experiments_ & (1u << static_cast<uint64_t>(experiment)); 76 } 77 78 private: 79 size_t alignment_ = 1u; 80 uint64_t output_size_ = 0u; 81 uint64_t deduped_size_ = 0u; 82 uint64_t dex_code_bytes_ = 0u; 83 uint64_t experiments_ = std::numeric_limits<uint64_t>::max(); 84 uint64_t extended_field_ = 0u; 85 uint64_t extended_method_ = 0u; 86 std::vector<size_t> move_result_reg_; 87 std::vector<size_t> first_arg_reg_count_; 88 std::vector<size_t> opcode_count_; 89 std::map<std::pair<uint32_t, uint32_t>, size_t> method_linkage_counts_; 90 std::map<std::pair<uint32_t, uint32_t>, size_t> field_linkage_counts_; 91 std::map<std::vector<uint8_t>, size_t> instruction_freq_; 92 // Output instruction buffer. 93 std::vector<uint8_t> buffer_; 94 }; 95 96 } // namespace dexanalyze 97 } // namespace art 98 99 #endif // ART_TOOLS_DEXANALYZE_DEXANALYZE_BYTECODE_H_ 100