1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2011 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_DEX2OAT_DRIVER_COMPILED_METHOD_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_DEX2OAT_DRIVER_COMPILED_METHOD_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include <memory> 21*795d594fSAndroid Build Coastguard Worker #include <string> 22*795d594fSAndroid Build Coastguard Worker #include <vector> 23*795d594fSAndroid Build Coastguard Worker 24*795d594fSAndroid Build Coastguard Worker #include "arch/instruction_set.h" 25*795d594fSAndroid Build Coastguard Worker #include "base/bit_field.h" 26*795d594fSAndroid Build Coastguard Worker #include "base/bit_utils.h" 27*795d594fSAndroid Build Coastguard Worker 28*795d594fSAndroid Build Coastguard Worker namespace art { 29*795d594fSAndroid Build Coastguard Worker 30*795d594fSAndroid Build Coastguard Worker template <typename T> class ArrayRef; 31*795d594fSAndroid Build Coastguard Worker class CompiledMethodStorage; 32*795d594fSAndroid Build Coastguard Worker template<typename T> class LengthPrefixedArray; 33*795d594fSAndroid Build Coastguard Worker 34*795d594fSAndroid Build Coastguard Worker namespace linker { 35*795d594fSAndroid Build Coastguard Worker class LinkerPatch; 36*795d594fSAndroid Build Coastguard Worker } // namespace linker 37*795d594fSAndroid Build Coastguard Worker 38*795d594fSAndroid Build Coastguard Worker class CompiledCode { 39*795d594fSAndroid Build Coastguard Worker public: 40*795d594fSAndroid Build Coastguard Worker // For Quick to supply an code blob 41*795d594fSAndroid Build Coastguard Worker CompiledCode(CompiledMethodStorage* storage, 42*795d594fSAndroid Build Coastguard Worker InstructionSet instruction_set, 43*795d594fSAndroid Build Coastguard Worker const ArrayRef<const uint8_t>& quick_code); 44*795d594fSAndroid Build Coastguard Worker 45*795d594fSAndroid Build Coastguard Worker virtual ~CompiledCode(); 46*795d594fSAndroid Build Coastguard Worker GetInstructionSet()47*795d594fSAndroid Build Coastguard Worker InstructionSet GetInstructionSet() const { 48*795d594fSAndroid Build Coastguard Worker return GetPackedField<InstructionSetField>(); 49*795d594fSAndroid Build Coastguard Worker } 50*795d594fSAndroid Build Coastguard Worker 51*795d594fSAndroid Build Coastguard Worker ArrayRef<const uint8_t> GetQuickCode() const; 52*795d594fSAndroid Build Coastguard Worker 53*795d594fSAndroid Build Coastguard Worker bool operator==(const CompiledCode& rhs) const; 54*795d594fSAndroid Build Coastguard Worker 55*795d594fSAndroid Build Coastguard Worker // To align an offset from a page-aligned value to make it suitable 56*795d594fSAndroid Build Coastguard Worker // for code storage. For example on ARM, to ensure that PC relative 57*795d594fSAndroid Build Coastguard Worker // valu computations work out as expected. 58*795d594fSAndroid Build Coastguard Worker size_t AlignCode(size_t offset) const; 59*795d594fSAndroid Build Coastguard Worker static size_t AlignCode(size_t offset, InstructionSet instruction_set); 60*795d594fSAndroid Build Coastguard Worker 61*795d594fSAndroid Build Coastguard Worker // Returns the difference between the code address and a usable PC. 62*795d594fSAndroid Build Coastguard Worker // Mainly to cope with `kThumb2` where the lower bit must be set. 63*795d594fSAndroid Build Coastguard Worker size_t GetEntryPointAdjustment() const; 64*795d594fSAndroid Build Coastguard Worker 65*795d594fSAndroid Build Coastguard Worker protected: 66*795d594fSAndroid Build Coastguard Worker static constexpr size_t kInstructionSetFieldSize = 67*795d594fSAndroid Build Coastguard Worker MinimumBitsToStore(static_cast<size_t>(InstructionSet::kLast)); 68*795d594fSAndroid Build Coastguard Worker static constexpr size_t kNumberOfCompiledCodePackedBits = kInstructionSetFieldSize; 69*795d594fSAndroid Build Coastguard Worker static constexpr size_t kMaxNumberOfPackedBits = sizeof(uint32_t) * kBitsPerByte; 70*795d594fSAndroid Build Coastguard Worker 71*795d594fSAndroid Build Coastguard Worker template <typename T> 72*795d594fSAndroid Build Coastguard Worker static ArrayRef<const T> GetArray(const LengthPrefixedArray<T>* array); 73*795d594fSAndroid Build Coastguard Worker GetStorage()74*795d594fSAndroid Build Coastguard Worker CompiledMethodStorage* GetStorage() { 75*795d594fSAndroid Build Coastguard Worker return storage_; 76*795d594fSAndroid Build Coastguard Worker } 77*795d594fSAndroid Build Coastguard Worker 78*795d594fSAndroid Build Coastguard Worker template <typename BitFieldType> GetPackedField()79*795d594fSAndroid Build Coastguard Worker typename BitFieldType::value_type GetPackedField() const { 80*795d594fSAndroid Build Coastguard Worker return BitFieldType::Decode(packed_fields_); 81*795d594fSAndroid Build Coastguard Worker } 82*795d594fSAndroid Build Coastguard Worker 83*795d594fSAndroid Build Coastguard Worker template <typename BitFieldType> SetPackedField(typename BitFieldType::value_type value)84*795d594fSAndroid Build Coastguard Worker void SetPackedField(typename BitFieldType::value_type value) { 85*795d594fSAndroid Build Coastguard Worker DCHECK(IsUint<BitFieldType::size>(static_cast<uintptr_t>(value))); 86*795d594fSAndroid Build Coastguard Worker packed_fields_ = BitFieldType::Update(value, packed_fields_); 87*795d594fSAndroid Build Coastguard Worker } 88*795d594fSAndroid Build Coastguard Worker 89*795d594fSAndroid Build Coastguard Worker private: 90*795d594fSAndroid Build Coastguard Worker using InstructionSetField = BitField<InstructionSet, 0u, kInstructionSetFieldSize>; 91*795d594fSAndroid Build Coastguard Worker 92*795d594fSAndroid Build Coastguard Worker CompiledMethodStorage* const storage_; 93*795d594fSAndroid Build Coastguard Worker 94*795d594fSAndroid Build Coastguard Worker // Used to store the compiled code. 95*795d594fSAndroid Build Coastguard Worker const LengthPrefixedArray<uint8_t>* const quick_code_; 96*795d594fSAndroid Build Coastguard Worker 97*795d594fSAndroid Build Coastguard Worker uint32_t packed_fields_; 98*795d594fSAndroid Build Coastguard Worker }; 99*795d594fSAndroid Build Coastguard Worker 100*795d594fSAndroid Build Coastguard Worker class CompiledMethod final : public CompiledCode { 101*795d594fSAndroid Build Coastguard Worker public: 102*795d594fSAndroid Build Coastguard Worker // Constructs a CompiledMethod. 103*795d594fSAndroid Build Coastguard Worker // Note: Consider using the static allocation methods below that will allocate the CompiledMethod 104*795d594fSAndroid Build Coastguard Worker // in the swap space. 105*795d594fSAndroid Build Coastguard Worker CompiledMethod(CompiledMethodStorage* storage, 106*795d594fSAndroid Build Coastguard Worker InstructionSet instruction_set, 107*795d594fSAndroid Build Coastguard Worker const ArrayRef<const uint8_t>& quick_code, 108*795d594fSAndroid Build Coastguard Worker const ArrayRef<const uint8_t>& vmap_table, 109*795d594fSAndroid Build Coastguard Worker const ArrayRef<const uint8_t>& cfi_info, 110*795d594fSAndroid Build Coastguard Worker const ArrayRef<const linker::LinkerPatch>& patches); 111*795d594fSAndroid Build Coastguard Worker 112*795d594fSAndroid Build Coastguard Worker virtual ~CompiledMethod(); 113*795d594fSAndroid Build Coastguard Worker 114*795d594fSAndroid Build Coastguard Worker static CompiledMethod* SwapAllocCompiledMethod( 115*795d594fSAndroid Build Coastguard Worker CompiledMethodStorage* storage, 116*795d594fSAndroid Build Coastguard Worker InstructionSet instruction_set, 117*795d594fSAndroid Build Coastguard Worker const ArrayRef<const uint8_t>& quick_code, 118*795d594fSAndroid Build Coastguard Worker const ArrayRef<const uint8_t>& vmap_table, 119*795d594fSAndroid Build Coastguard Worker const ArrayRef<const uint8_t>& cfi_info, 120*795d594fSAndroid Build Coastguard Worker const ArrayRef<const linker::LinkerPatch>& patches); 121*795d594fSAndroid Build Coastguard Worker 122*795d594fSAndroid Build Coastguard Worker static void ReleaseSwapAllocatedCompiledMethod(CompiledMethodStorage* storage, CompiledMethod* m); 123*795d594fSAndroid Build Coastguard Worker IsIntrinsic()124*795d594fSAndroid Build Coastguard Worker bool IsIntrinsic() const { 125*795d594fSAndroid Build Coastguard Worker return GetPackedField<IsIntrinsicField>(); 126*795d594fSAndroid Build Coastguard Worker } 127*795d594fSAndroid Build Coastguard Worker 128*795d594fSAndroid Build Coastguard Worker // Marks the compiled method as being generated using an intrinsic codegen. 129*795d594fSAndroid Build Coastguard Worker // Such methods have no relationships to their code items. 130*795d594fSAndroid Build Coastguard Worker // This affects debug information generated at link time. MarkAsIntrinsic()131*795d594fSAndroid Build Coastguard Worker void MarkAsIntrinsic() { 132*795d594fSAndroid Build Coastguard Worker DCHECK(!IsIntrinsic()); 133*795d594fSAndroid Build Coastguard Worker SetPackedField<IsIntrinsicField>(/* value= */ true); 134*795d594fSAndroid Build Coastguard Worker } 135*795d594fSAndroid Build Coastguard Worker 136*795d594fSAndroid Build Coastguard Worker ArrayRef<const uint8_t> GetVmapTable() const; 137*795d594fSAndroid Build Coastguard Worker 138*795d594fSAndroid Build Coastguard Worker ArrayRef<const uint8_t> GetCFIInfo() const; 139*795d594fSAndroid Build Coastguard Worker 140*795d594fSAndroid Build Coastguard Worker ArrayRef<const linker::LinkerPatch> GetPatches() const; 141*795d594fSAndroid Build Coastguard Worker 142*795d594fSAndroid Build Coastguard Worker private: 143*795d594fSAndroid Build Coastguard Worker static constexpr size_t kIsIntrinsicLsb = kNumberOfCompiledCodePackedBits; 144*795d594fSAndroid Build Coastguard Worker static constexpr size_t kIsIntrinsicSize = 1u; 145*795d594fSAndroid Build Coastguard Worker static constexpr size_t kNumberOfCompiledMethodPackedBits = kIsIntrinsicLsb + kIsIntrinsicSize; 146*795d594fSAndroid Build Coastguard Worker static_assert(kNumberOfCompiledMethodPackedBits <= CompiledCode::kMaxNumberOfPackedBits, 147*795d594fSAndroid Build Coastguard Worker "Too many packed fields."); 148*795d594fSAndroid Build Coastguard Worker 149*795d594fSAndroid Build Coastguard Worker using IsIntrinsicField = BitField<bool, kIsIntrinsicLsb, kIsIntrinsicSize>; 150*795d594fSAndroid Build Coastguard Worker 151*795d594fSAndroid Build Coastguard Worker // For quick code, holds code infos which contain stack maps, inline information, and etc. 152*795d594fSAndroid Build Coastguard Worker const LengthPrefixedArray<uint8_t>* const vmap_table_; 153*795d594fSAndroid Build Coastguard Worker // For quick code, a FDE entry for the debug_frame section. 154*795d594fSAndroid Build Coastguard Worker const LengthPrefixedArray<uint8_t>* const cfi_info_; 155*795d594fSAndroid Build Coastguard Worker // For quick code, linker patches needed by the method. 156*795d594fSAndroid Build Coastguard Worker const LengthPrefixedArray<linker::LinkerPatch>* const patches_; 157*795d594fSAndroid Build Coastguard Worker }; 158*795d594fSAndroid Build Coastguard Worker 159*795d594fSAndroid Build Coastguard Worker } // namespace art 160*795d594fSAndroid Build Coastguard Worker 161*795d594fSAndroid Build Coastguard Worker #endif // ART_DEX2OAT_DRIVER_COMPILED_METHOD_H_ 162