1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2015 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 #include <algorithm>
18*795d594fSAndroid Build Coastguard Worker #include <ostream>
19*795d594fSAndroid Build Coastguard Worker
20*795d594fSAndroid Build Coastguard Worker #include "compiled_method_storage.h"
21*795d594fSAndroid Build Coastguard Worker
22*795d594fSAndroid Build Coastguard Worker #include <android-base/logging.h>
23*795d594fSAndroid Build Coastguard Worker
24*795d594fSAndroid Build Coastguard Worker #include "base/data_hash.h"
25*795d594fSAndroid Build Coastguard Worker #include "base/utils.h"
26*795d594fSAndroid Build Coastguard Worker #include "compiled_method.h"
27*795d594fSAndroid Build Coastguard Worker #include "linker/linker_patch.h"
28*795d594fSAndroid Build Coastguard Worker #include "thread-current-inl.h"
29*795d594fSAndroid Build Coastguard Worker #include "utils/dedupe_set-inl.h"
30*795d594fSAndroid Build Coastguard Worker #include "utils/swap_space.h"
31*795d594fSAndroid Build Coastguard Worker
32*795d594fSAndroid Build Coastguard Worker namespace art {
33*795d594fSAndroid Build Coastguard Worker
34*795d594fSAndroid Build Coastguard Worker namespace { // anonymous namespace
35*795d594fSAndroid Build Coastguard Worker
36*795d594fSAndroid Build Coastguard Worker template <typename T>
CopyArray(SwapSpace * swap_space,const ArrayRef<const T> & array)37*795d594fSAndroid Build Coastguard Worker const LengthPrefixedArray<T>* CopyArray(SwapSpace* swap_space, const ArrayRef<const T>& array) {
38*795d594fSAndroid Build Coastguard Worker DCHECK(!array.empty());
39*795d594fSAndroid Build Coastguard Worker SwapAllocator<uint8_t> allocator(swap_space);
40*795d594fSAndroid Build Coastguard Worker void* storage = allocator.allocate(LengthPrefixedArray<T>::ComputeSize(array.size()));
41*795d594fSAndroid Build Coastguard Worker LengthPrefixedArray<T>* array_copy = new(storage) LengthPrefixedArray<T>(array.size());
42*795d594fSAndroid Build Coastguard Worker std::copy(array.begin(), array.end(), array_copy->begin());
43*795d594fSAndroid Build Coastguard Worker return array_copy;
44*795d594fSAndroid Build Coastguard Worker }
45*795d594fSAndroid Build Coastguard Worker
46*795d594fSAndroid Build Coastguard Worker template <typename T>
ReleaseArray(SwapSpace * swap_space,const LengthPrefixedArray<T> * array)47*795d594fSAndroid Build Coastguard Worker void ReleaseArray(SwapSpace* swap_space, const LengthPrefixedArray<T>* array) {
48*795d594fSAndroid Build Coastguard Worker SwapAllocator<uint8_t> allocator(swap_space);
49*795d594fSAndroid Build Coastguard Worker size_t size = LengthPrefixedArray<T>::ComputeSize(array->size());
50*795d594fSAndroid Build Coastguard Worker array->~LengthPrefixedArray<T>();
51*795d594fSAndroid Build Coastguard Worker allocator.deallocate(const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(array)), size);
52*795d594fSAndroid Build Coastguard Worker }
53*795d594fSAndroid Build Coastguard Worker
54*795d594fSAndroid Build Coastguard Worker } // anonymous namespace
55*795d594fSAndroid Build Coastguard Worker
56*795d594fSAndroid Build Coastguard Worker template <typename T, typename DedupeSetType>
AllocateOrDeduplicateArray(const ArrayRef<const T> & data,DedupeSetType * dedupe_set)57*795d594fSAndroid Build Coastguard Worker inline const LengthPrefixedArray<T>* CompiledMethodStorage::AllocateOrDeduplicateArray(
58*795d594fSAndroid Build Coastguard Worker const ArrayRef<const T>& data,
59*795d594fSAndroid Build Coastguard Worker DedupeSetType* dedupe_set) {
60*795d594fSAndroid Build Coastguard Worker if (data.empty()) {
61*795d594fSAndroid Build Coastguard Worker return nullptr;
62*795d594fSAndroid Build Coastguard Worker } else if (!DedupeEnabled()) {
63*795d594fSAndroid Build Coastguard Worker return CopyArray(swap_space_.get(), data);
64*795d594fSAndroid Build Coastguard Worker } else {
65*795d594fSAndroid Build Coastguard Worker return dedupe_set->Add(Thread::Current(), data);
66*795d594fSAndroid Build Coastguard Worker }
67*795d594fSAndroid Build Coastguard Worker }
68*795d594fSAndroid Build Coastguard Worker
69*795d594fSAndroid Build Coastguard Worker template <typename T>
ReleaseArrayIfNotDeduplicated(const LengthPrefixedArray<T> * array)70*795d594fSAndroid Build Coastguard Worker inline void CompiledMethodStorage::ReleaseArrayIfNotDeduplicated(
71*795d594fSAndroid Build Coastguard Worker const LengthPrefixedArray<T>* array) {
72*795d594fSAndroid Build Coastguard Worker if (array != nullptr && !DedupeEnabled()) {
73*795d594fSAndroid Build Coastguard Worker ReleaseArray(swap_space_.get(), array);
74*795d594fSAndroid Build Coastguard Worker }
75*795d594fSAndroid Build Coastguard Worker }
76*795d594fSAndroid Build Coastguard Worker
77*795d594fSAndroid Build Coastguard Worker template <typename ContentType>
78*795d594fSAndroid Build Coastguard Worker class CompiledMethodStorage::DedupeHashFunc {
79*795d594fSAndroid Build Coastguard Worker private:
80*795d594fSAndroid Build Coastguard Worker static constexpr bool kUseMurmur3Hash = true;
81*795d594fSAndroid Build Coastguard Worker
82*795d594fSAndroid Build Coastguard Worker public:
operator ()(const ArrayRef<ContentType> & array) const83*795d594fSAndroid Build Coastguard Worker size_t operator()(const ArrayRef<ContentType>& array) const {
84*795d594fSAndroid Build Coastguard Worker return DataHash()(array);
85*795d594fSAndroid Build Coastguard Worker }
86*795d594fSAndroid Build Coastguard Worker };
87*795d594fSAndroid Build Coastguard Worker
88*795d594fSAndroid Build Coastguard Worker template <typename T>
89*795d594fSAndroid Build Coastguard Worker class CompiledMethodStorage::LengthPrefixedArrayAlloc {
90*795d594fSAndroid Build Coastguard Worker public:
LengthPrefixedArrayAlloc(SwapSpace * swap_space)91*795d594fSAndroid Build Coastguard Worker explicit LengthPrefixedArrayAlloc(SwapSpace* swap_space)
92*795d594fSAndroid Build Coastguard Worker : swap_space_(swap_space) {
93*795d594fSAndroid Build Coastguard Worker }
94*795d594fSAndroid Build Coastguard Worker
Copy(const ArrayRef<const T> & array)95*795d594fSAndroid Build Coastguard Worker const LengthPrefixedArray<T>* Copy(const ArrayRef<const T>& array) {
96*795d594fSAndroid Build Coastguard Worker return CopyArray(swap_space_, array);
97*795d594fSAndroid Build Coastguard Worker }
98*795d594fSAndroid Build Coastguard Worker
Destroy(const LengthPrefixedArray<T> * array)99*795d594fSAndroid Build Coastguard Worker void Destroy(const LengthPrefixedArray<T>* array) {
100*795d594fSAndroid Build Coastguard Worker ReleaseArray(swap_space_, array);
101*795d594fSAndroid Build Coastguard Worker }
102*795d594fSAndroid Build Coastguard Worker
103*795d594fSAndroid Build Coastguard Worker private:
104*795d594fSAndroid Build Coastguard Worker SwapSpace* const swap_space_;
105*795d594fSAndroid Build Coastguard Worker };
106*795d594fSAndroid Build Coastguard Worker
107*795d594fSAndroid Build Coastguard Worker class CompiledMethodStorage::ThunkMapKey {
108*795d594fSAndroid Build Coastguard Worker public:
ThunkMapKey(linker::LinkerPatch::Type type,uint32_t custom_value1,uint32_t custom_value2)109*795d594fSAndroid Build Coastguard Worker ThunkMapKey(linker::LinkerPatch::Type type, uint32_t custom_value1, uint32_t custom_value2)
110*795d594fSAndroid Build Coastguard Worker : type_(type), custom_value1_(custom_value1), custom_value2_(custom_value2) {}
111*795d594fSAndroid Build Coastguard Worker
operator <(const ThunkMapKey & other) const112*795d594fSAndroid Build Coastguard Worker bool operator<(const ThunkMapKey& other) const {
113*795d594fSAndroid Build Coastguard Worker if (custom_value1_ != other.custom_value1_) {
114*795d594fSAndroid Build Coastguard Worker return custom_value1_ < other.custom_value1_;
115*795d594fSAndroid Build Coastguard Worker }
116*795d594fSAndroid Build Coastguard Worker if (custom_value2_ != other.custom_value2_) {
117*795d594fSAndroid Build Coastguard Worker return custom_value2_ < other.custom_value2_;
118*795d594fSAndroid Build Coastguard Worker }
119*795d594fSAndroid Build Coastguard Worker return type_ < other.type_;
120*795d594fSAndroid Build Coastguard Worker }
121*795d594fSAndroid Build Coastguard Worker
122*795d594fSAndroid Build Coastguard Worker private:
123*795d594fSAndroid Build Coastguard Worker linker::LinkerPatch::Type type_;
124*795d594fSAndroid Build Coastguard Worker uint32_t custom_value1_;
125*795d594fSAndroid Build Coastguard Worker uint32_t custom_value2_;
126*795d594fSAndroid Build Coastguard Worker };
127*795d594fSAndroid Build Coastguard Worker
128*795d594fSAndroid Build Coastguard Worker class CompiledMethodStorage::ThunkMapValue {
129*795d594fSAndroid Build Coastguard Worker public:
ThunkMapValue(std::vector<uint8_t,SwapAllocator<uint8_t>> && code,const std::string & debug_name)130*795d594fSAndroid Build Coastguard Worker ThunkMapValue(std::vector<uint8_t, SwapAllocator<uint8_t>>&& code,
131*795d594fSAndroid Build Coastguard Worker const std::string& debug_name)
132*795d594fSAndroid Build Coastguard Worker : code_(std::move(code)), debug_name_(debug_name) {}
133*795d594fSAndroid Build Coastguard Worker
GetCode() const134*795d594fSAndroid Build Coastguard Worker ArrayRef<const uint8_t> GetCode() const {
135*795d594fSAndroid Build Coastguard Worker return ArrayRef<const uint8_t>(code_);
136*795d594fSAndroid Build Coastguard Worker }
137*795d594fSAndroid Build Coastguard Worker
GetDebugName() const138*795d594fSAndroid Build Coastguard Worker const std::string& GetDebugName() const {
139*795d594fSAndroid Build Coastguard Worker return debug_name_;
140*795d594fSAndroid Build Coastguard Worker }
141*795d594fSAndroid Build Coastguard Worker
142*795d594fSAndroid Build Coastguard Worker private:
143*795d594fSAndroid Build Coastguard Worker std::vector<uint8_t, SwapAllocator<uint8_t>> code_;
144*795d594fSAndroid Build Coastguard Worker std::string debug_name_;
145*795d594fSAndroid Build Coastguard Worker };
146*795d594fSAndroid Build Coastguard Worker
CompiledMethodStorage(int swap_fd)147*795d594fSAndroid Build Coastguard Worker CompiledMethodStorage::CompiledMethodStorage(int swap_fd)
148*795d594fSAndroid Build Coastguard Worker : swap_space_(swap_fd == -1 ? nullptr : new SwapSpace(swap_fd, 10 * MB)),
149*795d594fSAndroid Build Coastguard Worker dedupe_enabled_(true),
150*795d594fSAndroid Build Coastguard Worker dedupe_code_("dedupe code", LengthPrefixedArrayAlloc<uint8_t>(swap_space_.get())),
151*795d594fSAndroid Build Coastguard Worker dedupe_vmap_table_("dedupe vmap table",
152*795d594fSAndroid Build Coastguard Worker LengthPrefixedArrayAlloc<uint8_t>(swap_space_.get())),
153*795d594fSAndroid Build Coastguard Worker dedupe_cfi_info_("dedupe cfi info", LengthPrefixedArrayAlloc<uint8_t>(swap_space_.get())),
154*795d594fSAndroid Build Coastguard Worker dedupe_linker_patches_("dedupe cfi info",
155*795d594fSAndroid Build Coastguard Worker LengthPrefixedArrayAlloc<linker::LinkerPatch>(swap_space_.get())),
156*795d594fSAndroid Build Coastguard Worker thunk_map_lock_("thunk_map_lock"),
157*795d594fSAndroid Build Coastguard Worker thunk_map_(std::less<ThunkMapKey>(), SwapAllocator<ThunkMapValueType>(swap_space_.get())) {
158*795d594fSAndroid Build Coastguard Worker }
159*795d594fSAndroid Build Coastguard Worker
~CompiledMethodStorage()160*795d594fSAndroid Build Coastguard Worker CompiledMethodStorage::~CompiledMethodStorage() {
161*795d594fSAndroid Build Coastguard Worker // All done by member destructors.
162*795d594fSAndroid Build Coastguard Worker }
163*795d594fSAndroid Build Coastguard Worker
DumpMemoryUsage(std::ostream & os,bool extended) const164*795d594fSAndroid Build Coastguard Worker void CompiledMethodStorage::DumpMemoryUsage(std::ostream& os, bool extended) const {
165*795d594fSAndroid Build Coastguard Worker if (swap_space_.get() != nullptr) {
166*795d594fSAndroid Build Coastguard Worker const size_t swap_size = swap_space_->GetSize();
167*795d594fSAndroid Build Coastguard Worker os << " swap=" << PrettySize(swap_size) << " (" << swap_size << "B)";
168*795d594fSAndroid Build Coastguard Worker }
169*795d594fSAndroid Build Coastguard Worker if (extended) {
170*795d594fSAndroid Build Coastguard Worker Thread* self = Thread::Current();
171*795d594fSAndroid Build Coastguard Worker os << "\nCode dedupe: " << dedupe_code_.DumpStats(self);
172*795d594fSAndroid Build Coastguard Worker os << "\nVmap table dedupe: " << dedupe_vmap_table_.DumpStats(self);
173*795d594fSAndroid Build Coastguard Worker os << "\nCFI info dedupe: " << dedupe_cfi_info_.DumpStats(self);
174*795d594fSAndroid Build Coastguard Worker }
175*795d594fSAndroid Build Coastguard Worker }
176*795d594fSAndroid Build Coastguard Worker
DeduplicateCode(const ArrayRef<const uint8_t> & code)177*795d594fSAndroid Build Coastguard Worker const LengthPrefixedArray<uint8_t>* CompiledMethodStorage::DeduplicateCode(
178*795d594fSAndroid Build Coastguard Worker const ArrayRef<const uint8_t>& code) {
179*795d594fSAndroid Build Coastguard Worker return AllocateOrDeduplicateArray(code, &dedupe_code_);
180*795d594fSAndroid Build Coastguard Worker }
181*795d594fSAndroid Build Coastguard Worker
ReleaseCode(const LengthPrefixedArray<uint8_t> * code)182*795d594fSAndroid Build Coastguard Worker void CompiledMethodStorage::ReleaseCode(const LengthPrefixedArray<uint8_t>* code) {
183*795d594fSAndroid Build Coastguard Worker ReleaseArrayIfNotDeduplicated(code);
184*795d594fSAndroid Build Coastguard Worker }
185*795d594fSAndroid Build Coastguard Worker
UniqueCodeEntries() const186*795d594fSAndroid Build Coastguard Worker size_t CompiledMethodStorage::UniqueCodeEntries() const {
187*795d594fSAndroid Build Coastguard Worker DCHECK(DedupeEnabled());
188*795d594fSAndroid Build Coastguard Worker return dedupe_code_.Size(Thread::Current());
189*795d594fSAndroid Build Coastguard Worker }
190*795d594fSAndroid Build Coastguard Worker
DeduplicateVMapTable(const ArrayRef<const uint8_t> & table)191*795d594fSAndroid Build Coastguard Worker const LengthPrefixedArray<uint8_t>* CompiledMethodStorage::DeduplicateVMapTable(
192*795d594fSAndroid Build Coastguard Worker const ArrayRef<const uint8_t>& table) {
193*795d594fSAndroid Build Coastguard Worker return AllocateOrDeduplicateArray(table, &dedupe_vmap_table_);
194*795d594fSAndroid Build Coastguard Worker }
195*795d594fSAndroid Build Coastguard Worker
ReleaseVMapTable(const LengthPrefixedArray<uint8_t> * table)196*795d594fSAndroid Build Coastguard Worker void CompiledMethodStorage::ReleaseVMapTable(const LengthPrefixedArray<uint8_t>* table) {
197*795d594fSAndroid Build Coastguard Worker ReleaseArrayIfNotDeduplicated(table);
198*795d594fSAndroid Build Coastguard Worker }
199*795d594fSAndroid Build Coastguard Worker
UniqueVMapTableEntries() const200*795d594fSAndroid Build Coastguard Worker size_t CompiledMethodStorage::UniqueVMapTableEntries() const {
201*795d594fSAndroid Build Coastguard Worker DCHECK(DedupeEnabled());
202*795d594fSAndroid Build Coastguard Worker return dedupe_vmap_table_.Size(Thread::Current());
203*795d594fSAndroid Build Coastguard Worker }
204*795d594fSAndroid Build Coastguard Worker
DeduplicateCFIInfo(const ArrayRef<const uint8_t> & cfi_info)205*795d594fSAndroid Build Coastguard Worker const LengthPrefixedArray<uint8_t>* CompiledMethodStorage::DeduplicateCFIInfo(
206*795d594fSAndroid Build Coastguard Worker const ArrayRef<const uint8_t>& cfi_info) {
207*795d594fSAndroid Build Coastguard Worker return AllocateOrDeduplicateArray(cfi_info, &dedupe_cfi_info_);
208*795d594fSAndroid Build Coastguard Worker }
209*795d594fSAndroid Build Coastguard Worker
ReleaseCFIInfo(const LengthPrefixedArray<uint8_t> * cfi_info)210*795d594fSAndroid Build Coastguard Worker void CompiledMethodStorage::ReleaseCFIInfo(const LengthPrefixedArray<uint8_t>* cfi_info) {
211*795d594fSAndroid Build Coastguard Worker ReleaseArrayIfNotDeduplicated(cfi_info);
212*795d594fSAndroid Build Coastguard Worker }
213*795d594fSAndroid Build Coastguard Worker
UniqueCFIInfoEntries() const214*795d594fSAndroid Build Coastguard Worker size_t CompiledMethodStorage::UniqueCFIInfoEntries() const {
215*795d594fSAndroid Build Coastguard Worker DCHECK(DedupeEnabled());
216*795d594fSAndroid Build Coastguard Worker return dedupe_cfi_info_.Size(Thread::Current());
217*795d594fSAndroid Build Coastguard Worker }
218*795d594fSAndroid Build Coastguard Worker
DeduplicateLinkerPatches(const ArrayRef<const linker::LinkerPatch> & linker_patches)219*795d594fSAndroid Build Coastguard Worker const LengthPrefixedArray<linker::LinkerPatch>* CompiledMethodStorage::DeduplicateLinkerPatches(
220*795d594fSAndroid Build Coastguard Worker const ArrayRef<const linker::LinkerPatch>& linker_patches) {
221*795d594fSAndroid Build Coastguard Worker return AllocateOrDeduplicateArray(linker_patches, &dedupe_linker_patches_);
222*795d594fSAndroid Build Coastguard Worker }
223*795d594fSAndroid Build Coastguard Worker
ReleaseLinkerPatches(const LengthPrefixedArray<linker::LinkerPatch> * linker_patches)224*795d594fSAndroid Build Coastguard Worker void CompiledMethodStorage::ReleaseLinkerPatches(
225*795d594fSAndroid Build Coastguard Worker const LengthPrefixedArray<linker::LinkerPatch>* linker_patches) {
226*795d594fSAndroid Build Coastguard Worker ReleaseArrayIfNotDeduplicated(linker_patches);
227*795d594fSAndroid Build Coastguard Worker }
228*795d594fSAndroid Build Coastguard Worker
UniqueLinkerPatchesEntries() const229*795d594fSAndroid Build Coastguard Worker size_t CompiledMethodStorage::UniqueLinkerPatchesEntries() const {
230*795d594fSAndroid Build Coastguard Worker DCHECK(DedupeEnabled());
231*795d594fSAndroid Build Coastguard Worker return dedupe_linker_patches_.Size(Thread::Current());
232*795d594fSAndroid Build Coastguard Worker }
233*795d594fSAndroid Build Coastguard Worker
GetThunkMapKey(const linker::LinkerPatch & linker_patch)234*795d594fSAndroid Build Coastguard Worker CompiledMethodStorage::ThunkMapKey CompiledMethodStorage::GetThunkMapKey(
235*795d594fSAndroid Build Coastguard Worker const linker::LinkerPatch& linker_patch) {
236*795d594fSAndroid Build Coastguard Worker uint32_t custom_value1 = 0u;
237*795d594fSAndroid Build Coastguard Worker uint32_t custom_value2 = 0u;
238*795d594fSAndroid Build Coastguard Worker switch (linker_patch.GetType()) {
239*795d594fSAndroid Build Coastguard Worker case linker::LinkerPatch::Type::kCallEntrypoint:
240*795d594fSAndroid Build Coastguard Worker custom_value1 = linker_patch.EntrypointOffset();
241*795d594fSAndroid Build Coastguard Worker break;
242*795d594fSAndroid Build Coastguard Worker case linker::LinkerPatch::Type::kBakerReadBarrierBranch:
243*795d594fSAndroid Build Coastguard Worker custom_value1 = linker_patch.GetBakerCustomValue1();
244*795d594fSAndroid Build Coastguard Worker custom_value2 = linker_patch.GetBakerCustomValue2();
245*795d594fSAndroid Build Coastguard Worker break;
246*795d594fSAndroid Build Coastguard Worker case linker::LinkerPatch::Type::kCallRelative:
247*795d594fSAndroid Build Coastguard Worker // No custom values.
248*795d594fSAndroid Build Coastguard Worker break;
249*795d594fSAndroid Build Coastguard Worker default:
250*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Unexpected patch type: " << linker_patch.GetType();
251*795d594fSAndroid Build Coastguard Worker UNREACHABLE();
252*795d594fSAndroid Build Coastguard Worker }
253*795d594fSAndroid Build Coastguard Worker return ThunkMapKey(linker_patch.GetType(), custom_value1, custom_value2);
254*795d594fSAndroid Build Coastguard Worker }
255*795d594fSAndroid Build Coastguard Worker
CreateCompiledMethod(InstructionSet instruction_set,ArrayRef<const uint8_t> code,ArrayRef<const uint8_t> stack_map,ArrayRef<const uint8_t> cfi,ArrayRef<const linker::LinkerPatch> patches,bool is_intrinsic)256*795d594fSAndroid Build Coastguard Worker CompiledMethod* CompiledMethodStorage::CreateCompiledMethod(
257*795d594fSAndroid Build Coastguard Worker InstructionSet instruction_set,
258*795d594fSAndroid Build Coastguard Worker ArrayRef<const uint8_t> code,
259*795d594fSAndroid Build Coastguard Worker ArrayRef<const uint8_t> stack_map,
260*795d594fSAndroid Build Coastguard Worker ArrayRef<const uint8_t> cfi,
261*795d594fSAndroid Build Coastguard Worker ArrayRef<const linker::LinkerPatch> patches,
262*795d594fSAndroid Build Coastguard Worker bool is_intrinsic) {
263*795d594fSAndroid Build Coastguard Worker CompiledMethod* compiled_method = CompiledMethod::SwapAllocCompiledMethod(
264*795d594fSAndroid Build Coastguard Worker this, instruction_set, code, stack_map, cfi, patches);
265*795d594fSAndroid Build Coastguard Worker if (is_intrinsic) {
266*795d594fSAndroid Build Coastguard Worker compiled_method->MarkAsIntrinsic();
267*795d594fSAndroid Build Coastguard Worker }
268*795d594fSAndroid Build Coastguard Worker return compiled_method;
269*795d594fSAndroid Build Coastguard Worker }
270*795d594fSAndroid Build Coastguard Worker
GetThunkCode(const linker::LinkerPatch & linker_patch,std::string * debug_name)271*795d594fSAndroid Build Coastguard Worker ArrayRef<const uint8_t> CompiledMethodStorage::GetThunkCode(const linker::LinkerPatch& linker_patch,
272*795d594fSAndroid Build Coastguard Worker /*out*/ std::string* debug_name) {
273*795d594fSAndroid Build Coastguard Worker ThunkMapKey key = GetThunkMapKey(linker_patch);
274*795d594fSAndroid Build Coastguard Worker MutexLock lock(Thread::Current(), thunk_map_lock_);
275*795d594fSAndroid Build Coastguard Worker auto it = thunk_map_.find(key);
276*795d594fSAndroid Build Coastguard Worker if (it != thunk_map_.end()) {
277*795d594fSAndroid Build Coastguard Worker const ThunkMapValue& value = it->second;
278*795d594fSAndroid Build Coastguard Worker if (debug_name != nullptr) {
279*795d594fSAndroid Build Coastguard Worker *debug_name = value.GetDebugName();
280*795d594fSAndroid Build Coastguard Worker }
281*795d594fSAndroid Build Coastguard Worker return value.GetCode();
282*795d594fSAndroid Build Coastguard Worker } else {
283*795d594fSAndroid Build Coastguard Worker if (debug_name != nullptr) {
284*795d594fSAndroid Build Coastguard Worker *debug_name = std::string();
285*795d594fSAndroid Build Coastguard Worker }
286*795d594fSAndroid Build Coastguard Worker return ArrayRef<const uint8_t>();
287*795d594fSAndroid Build Coastguard Worker }
288*795d594fSAndroid Build Coastguard Worker }
289*795d594fSAndroid Build Coastguard Worker
SetThunkCode(const linker::LinkerPatch & linker_patch,ArrayRef<const uint8_t> code,const std::string & debug_name)290*795d594fSAndroid Build Coastguard Worker void CompiledMethodStorage::SetThunkCode(const linker::LinkerPatch& linker_patch,
291*795d594fSAndroid Build Coastguard Worker ArrayRef<const uint8_t> code,
292*795d594fSAndroid Build Coastguard Worker const std::string& debug_name) {
293*795d594fSAndroid Build Coastguard Worker DCHECK(!code.empty());
294*795d594fSAndroid Build Coastguard Worker ThunkMapKey key = GetThunkMapKey(linker_patch);
295*795d594fSAndroid Build Coastguard Worker std::vector<uint8_t, SwapAllocator<uint8_t>> code_copy(
296*795d594fSAndroid Build Coastguard Worker code.begin(), code.end(), SwapAllocator<uint8_t>(swap_space_.get()));
297*795d594fSAndroid Build Coastguard Worker ThunkMapValue value(std::move(code_copy), debug_name);
298*795d594fSAndroid Build Coastguard Worker MutexLock lock(Thread::Current(), thunk_map_lock_);
299*795d594fSAndroid Build Coastguard Worker // Note: Multiple threads can try and compile the same thunk, so this may not create a new entry.
300*795d594fSAndroid Build Coastguard Worker thunk_map_.emplace(key, std::move(value));
301*795d594fSAndroid Build Coastguard Worker }
302*795d594fSAndroid Build Coastguard Worker
303*795d594fSAndroid Build Coastguard Worker } // namespace art
304