• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 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 #include "jit_code_cache.h"
18 
19 #include <sstream>
20 
21 #include "arch/context.h"
22 #include "art_method-inl.h"
23 #include "base/enums.h"
24 #include "base/logging.h"  // For VLOG.
25 #include "base/quasi_atomic.h"
26 #include "base/stl_util.h"
27 #include "base/systrace.h"
28 #include "base/time_utils.h"
29 #include "cha.h"
30 #include "debugger_interface.h"
31 #include "dex/dex_file_loader.h"
32 #include "entrypoints/runtime_asm_entrypoints.h"
33 #include "gc/accounting/bitmap-inl.h"
34 #include "gc/scoped_gc_critical_section.h"
35 #include "handle.h"
36 #include "intern_table.h"
37 #include "jit/jit.h"
38 #include "jit/profiling_info.h"
39 #include "linear_alloc.h"
40 #include "mem_map.h"
41 #include "oat_file-inl.h"
42 #include "oat_quick_method_header.h"
43 #include "object_callbacks.h"
44 #include "profile_compilation_info.h"
45 #include "scoped_thread_state_change-inl.h"
46 #include "stack.h"
47 #include "thread-current-inl.h"
48 #include "thread_list.h"
49 
50 namespace art {
51 namespace jit {
52 
53 static constexpr int kProtData = PROT_READ | PROT_WRITE;
54 static constexpr int kProtCode = PROT_READ | PROT_EXEC;
55 
56 static constexpr size_t kCodeSizeLogThreshold = 50 * KB;
57 static constexpr size_t kStackMapSizeLogThreshold = 50 * KB;
58 
59 class JitCodeCache::JniStubKey {
60  public:
REQUIRES_SHARED(Locks::mutator_lock_)61   explicit JniStubKey(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_)
62       : shorty_(method->GetShorty()),
63         is_static_(method->IsStatic()),
64         is_fast_native_(method->IsFastNative()),
65         is_critical_native_(method->IsCriticalNative()),
66         is_synchronized_(method->IsSynchronized()) {
67     DCHECK(!(is_fast_native_ && is_critical_native_));
68   }
69 
operator <(const JniStubKey & rhs) const70   bool operator<(const JniStubKey& rhs) const {
71     if (is_static_ != rhs.is_static_) {
72       return rhs.is_static_;
73     }
74     if (is_synchronized_ != rhs.is_synchronized_) {
75       return rhs.is_synchronized_;
76     }
77     if (is_fast_native_ != rhs.is_fast_native_) {
78       return rhs.is_fast_native_;
79     }
80     if (is_critical_native_ != rhs.is_critical_native_) {
81       return rhs.is_critical_native_;
82     }
83     return strcmp(shorty_, rhs.shorty_) < 0;
84   }
85 
86   // Update the shorty to point to another method's shorty. Call this function when removing
87   // the method that references the old shorty from JniCodeData and not removing the entire
88   // JniCodeData; the old shorty may become a dangling pointer when that method is unloaded.
UpdateShorty(ArtMethod * method) const89   void UpdateShorty(ArtMethod* method) const REQUIRES_SHARED(Locks::mutator_lock_) {
90     const char* shorty = method->GetShorty();
91     DCHECK_STREQ(shorty_, shorty);
92     shorty_ = shorty;
93   }
94 
95  private:
96   // The shorty points to a DexFile data and may need to change
97   // to point to the same shorty in a different DexFile.
98   mutable const char* shorty_;
99 
100   const bool is_static_;
101   const bool is_fast_native_;
102   const bool is_critical_native_;
103   const bool is_synchronized_;
104 };
105 
106 class JitCodeCache::JniStubData {
107  public:
JniStubData()108   JniStubData() : code_(nullptr), methods_() {}
109 
SetCode(const void * code)110   void SetCode(const void* code) {
111     DCHECK(code != nullptr);
112     code_ = code;
113   }
114 
GetCode() const115   const void* GetCode() const {
116     return code_;
117   }
118 
IsCompiled() const119   bool IsCompiled() const {
120     return GetCode() != nullptr;
121   }
122 
AddMethod(ArtMethod * method)123   void AddMethod(ArtMethod* method) {
124     if (!ContainsElement(methods_, method)) {
125       methods_.push_back(method);
126     }
127   }
128 
GetMethods() const129   const std::vector<ArtMethod*>& GetMethods() const {
130     return methods_;
131   }
132 
RemoveMethodsIn(const LinearAlloc & alloc)133   void RemoveMethodsIn(const LinearAlloc& alloc) {
134     auto kept_end = std::remove_if(
135         methods_.begin(),
136         methods_.end(),
137         [&alloc](ArtMethod* method) { return alloc.ContainsUnsafe(method); });
138     methods_.erase(kept_end, methods_.end());
139   }
140 
RemoveMethod(ArtMethod * method)141   bool RemoveMethod(ArtMethod* method) {
142     auto it = std::find(methods_.begin(), methods_.end(), method);
143     if (it != methods_.end()) {
144       methods_.erase(it);
145       return true;
146     } else {
147       return false;
148     }
149   }
150 
MoveObsoleteMethod(ArtMethod * old_method,ArtMethod * new_method)151   void MoveObsoleteMethod(ArtMethod* old_method, ArtMethod* new_method) {
152     std::replace(methods_.begin(), methods_.end(), old_method, new_method);
153   }
154 
155  private:
156   const void* code_;
157   std::vector<ArtMethod*> methods_;
158 };
159 
Create(size_t initial_capacity,size_t max_capacity,bool generate_debug_info,bool used_only_for_profile_data,std::string * error_msg)160 JitCodeCache* JitCodeCache::Create(size_t initial_capacity,
161                                    size_t max_capacity,
162                                    bool generate_debug_info,
163                                    bool used_only_for_profile_data,
164                                    std::string* error_msg) {
165   ScopedTrace trace(__PRETTY_FUNCTION__);
166   CHECK_GE(max_capacity, initial_capacity);
167 
168   // Generating debug information is for using the Linux perf tool on
169   // host which does not work with ashmem.
170   // Also, target linux does not support ashmem.
171   bool use_ashmem = !generate_debug_info && !kIsTargetLinux;
172 
173   // With 'perf', we want a 1-1 mapping between an address and a method.
174   bool garbage_collect_code = !generate_debug_info;
175 
176   // We need to have 32 bit offsets from method headers in code cache which point to things
177   // in the data cache. If the maps are more than 4G apart, having multiple maps wouldn't work.
178   // Ensure we're below 1 GB to be safe.
179   if (max_capacity > 1 * GB) {
180     std::ostringstream oss;
181     oss << "Maxium code cache capacity is limited to 1 GB, "
182         << PrettySize(max_capacity) << " is too big";
183     *error_msg = oss.str();
184     return nullptr;
185   }
186 
187   // Decide how we should map the code and data sections.
188   // If we use the code cache just for profiling we do not need to map the code section as
189   // executable.
190   // NOTE 1: this is yet another workaround to bypass strict SElinux policies in order to be able
191   //         to profile system server.
192   // NOTE 2: We could just not create the code section at all but we will need to
193   //         special case too many cases.
194   int memmap_flags_prot_code = used_only_for_profile_data ? (kProtCode & ~PROT_EXEC) : kProtCode;
195 
196   std::string error_str;
197   // Map name specific for android_os_Debug.cpp accounting.
198   // Map in low 4gb to simplify accessing root tables for x86_64.
199   // We could do PC-relative addressing to avoid this problem, but that
200   // would require reserving code and data area before submitting, which
201   // means more windows for the code memory to be RWX.
202   std::unique_ptr<MemMap> data_map(MemMap::MapAnonymous(
203       "data-code-cache", nullptr,
204       max_capacity,
205       kProtData,
206       /* low_4gb */ true,
207       /* reuse */ false,
208       &error_str,
209       use_ashmem));
210   if (data_map == nullptr) {
211     std::ostringstream oss;
212     oss << "Failed to create read write cache: " << error_str << " size=" << max_capacity;
213     *error_msg = oss.str();
214     return nullptr;
215   }
216 
217   // Align both capacities to page size, as that's the unit mspaces use.
218   initial_capacity = RoundDown(initial_capacity, 2 * kPageSize);
219   max_capacity = RoundDown(max_capacity, 2 * kPageSize);
220 
221   // Data cache is 1 / 2 of the map.
222   // TODO: Make this variable?
223   size_t data_size = max_capacity / 2;
224   size_t code_size = max_capacity - data_size;
225   DCHECK_EQ(code_size + data_size, max_capacity);
226   uint8_t* divider = data_map->Begin() + data_size;
227 
228   MemMap* code_map = data_map->RemapAtEnd(
229       divider,
230       "jit-code-cache",
231       memmap_flags_prot_code | PROT_WRITE,
232       &error_str, use_ashmem);
233   if (code_map == nullptr) {
234     std::ostringstream oss;
235     oss << "Failed to create read write execute cache: " << error_str << " size=" << max_capacity;
236     *error_msg = oss.str();
237     return nullptr;
238   }
239   DCHECK_EQ(code_map->Begin(), divider);
240   data_size = initial_capacity / 2;
241   code_size = initial_capacity - data_size;
242   DCHECK_EQ(code_size + data_size, initial_capacity);
243   return new JitCodeCache(
244       code_map,
245       data_map.release(),
246       code_size,
247       data_size,
248       max_capacity,
249       garbage_collect_code,
250       memmap_flags_prot_code);
251 }
252 
JitCodeCache(MemMap * code_map,MemMap * data_map,size_t initial_code_capacity,size_t initial_data_capacity,size_t max_capacity,bool garbage_collect_code,int memmap_flags_prot_code)253 JitCodeCache::JitCodeCache(MemMap* code_map,
254                            MemMap* data_map,
255                            size_t initial_code_capacity,
256                            size_t initial_data_capacity,
257                            size_t max_capacity,
258                            bool garbage_collect_code,
259                            int memmap_flags_prot_code)
260     : lock_("Jit code cache", kJitCodeCacheLock),
261       lock_cond_("Jit code cache condition variable", lock_),
262       collection_in_progress_(false),
263       code_map_(code_map),
264       data_map_(data_map),
265       max_capacity_(max_capacity),
266       current_capacity_(initial_code_capacity + initial_data_capacity),
267       code_end_(initial_code_capacity),
268       data_end_(initial_data_capacity),
269       last_collection_increased_code_cache_(false),
270       last_update_time_ns_(0),
271       garbage_collect_code_(garbage_collect_code),
272       used_memory_for_data_(0),
273       used_memory_for_code_(0),
274       number_of_compilations_(0),
275       number_of_osr_compilations_(0),
276       number_of_collections_(0),
277       histogram_stack_map_memory_use_("Memory used for stack maps", 16),
278       histogram_code_memory_use_("Memory used for compiled code", 16),
279       histogram_profiling_info_memory_use_("Memory used for profiling info", 16),
280       is_weak_access_enabled_(true),
281       inline_cache_cond_("Jit inline cache condition variable", lock_),
282       memmap_flags_prot_code_(memmap_flags_prot_code) {
283 
284   DCHECK_GE(max_capacity, initial_code_capacity + initial_data_capacity);
285   code_mspace_ = create_mspace_with_base(code_map_->Begin(), code_end_, false /*locked*/);
286   data_mspace_ = create_mspace_with_base(data_map_->Begin(), data_end_, false /*locked*/);
287 
288   if (code_mspace_ == nullptr || data_mspace_ == nullptr) {
289     PLOG(FATAL) << "create_mspace_with_base failed";
290   }
291 
292   SetFootprintLimit(current_capacity_);
293 
294   CheckedCall(mprotect,
295               "mprotect jit code cache",
296               code_map_->Begin(),
297               code_map_->Size(),
298               memmap_flags_prot_code_);
299   CheckedCall(mprotect,
300               "mprotect jit data cache",
301               data_map_->Begin(),
302               data_map_->Size(),
303               kProtData);
304 
305   VLOG(jit) << "Created jit code cache: initial data size="
306             << PrettySize(initial_data_capacity)
307             << ", initial code size="
308             << PrettySize(initial_code_capacity);
309 }
310 
~JitCodeCache()311 JitCodeCache::~JitCodeCache() {}
312 
ContainsPc(const void * ptr) const313 bool JitCodeCache::ContainsPc(const void* ptr) const {
314   return code_map_->Begin() <= ptr && ptr < code_map_->End();
315 }
316 
ContainsMethod(ArtMethod * method)317 bool JitCodeCache::ContainsMethod(ArtMethod* method) {
318   MutexLock mu(Thread::Current(), lock_);
319   if (UNLIKELY(method->IsNative())) {
320     auto it = jni_stubs_map_.find(JniStubKey(method));
321     if (it != jni_stubs_map_.end() &&
322         it->second.IsCompiled() &&
323         ContainsElement(it->second.GetMethods(), method)) {
324       return true;
325     }
326   } else {
327     for (const auto& it : method_code_map_) {
328       if (it.second == method) {
329         return true;
330       }
331     }
332   }
333   return false;
334 }
335 
GetJniStubCode(ArtMethod * method)336 const void* JitCodeCache::GetJniStubCode(ArtMethod* method) {
337   DCHECK(method->IsNative());
338   MutexLock mu(Thread::Current(), lock_);
339   auto it = jni_stubs_map_.find(JniStubKey(method));
340   if (it != jni_stubs_map_.end()) {
341     JniStubData& data = it->second;
342     if (data.IsCompiled() && ContainsElement(data.GetMethods(), method)) {
343       return data.GetCode();
344     }
345   }
346   return nullptr;
347 }
348 
349 class ScopedCodeCacheWrite : ScopedTrace {
350  public:
ScopedCodeCacheWrite(const JitCodeCache * const code_cache,bool only_for_tlb_shootdown=false)351   explicit ScopedCodeCacheWrite(const JitCodeCache* const code_cache,
352                                 bool only_for_tlb_shootdown = false)
353       : ScopedTrace("ScopedCodeCacheWrite"),
354         code_cache_(code_cache),
355         only_for_tlb_shootdown_(only_for_tlb_shootdown) {
356     ScopedTrace trace("mprotect all");
357     CheckedCall(
358         mprotect,
359         "make code writable",
360         code_cache_->code_map_->Begin(),
361         only_for_tlb_shootdown_ ? kPageSize : code_cache_->code_map_->Size(),
362         code_cache_->memmap_flags_prot_code_ | PROT_WRITE);
363   }
364 
~ScopedCodeCacheWrite()365   ~ScopedCodeCacheWrite() {
366     ScopedTrace trace("mprotect code");
367     CheckedCall(
368         mprotect,
369         "make code protected",
370         code_cache_->code_map_->Begin(),
371         only_for_tlb_shootdown_ ? kPageSize : code_cache_->code_map_->Size(),
372         code_cache_->memmap_flags_prot_code_);
373   }
374 
375  private:
376   const JitCodeCache* const code_cache_;
377 
378   // If we're using ScopedCacheWrite only for TLB shootdown, we limit the scope of mprotect to
379   // one page.
380   const bool only_for_tlb_shootdown_;
381 
382   DISALLOW_COPY_AND_ASSIGN(ScopedCodeCacheWrite);
383 };
384 
CommitCode(Thread * self,ArtMethod * method,uint8_t * stack_map,uint8_t * method_info,uint8_t * roots_data,size_t frame_size_in_bytes,size_t core_spill_mask,size_t fp_spill_mask,const uint8_t * code,size_t code_size,size_t data_size,bool osr,Handle<mirror::ObjectArray<mirror::Object>> roots,bool has_should_deoptimize_flag,const ArenaSet<ArtMethod * > & cha_single_implementation_list)385 uint8_t* JitCodeCache::CommitCode(Thread* self,
386                                   ArtMethod* method,
387                                   uint8_t* stack_map,
388                                   uint8_t* method_info,
389                                   uint8_t* roots_data,
390                                   size_t frame_size_in_bytes,
391                                   size_t core_spill_mask,
392                                   size_t fp_spill_mask,
393                                   const uint8_t* code,
394                                   size_t code_size,
395                                   size_t data_size,
396                                   bool osr,
397                                   Handle<mirror::ObjectArray<mirror::Object>> roots,
398                                   bool has_should_deoptimize_flag,
399                                   const ArenaSet<ArtMethod*>& cha_single_implementation_list) {
400   uint8_t* result = CommitCodeInternal(self,
401                                        method,
402                                        stack_map,
403                                        method_info,
404                                        roots_data,
405                                        frame_size_in_bytes,
406                                        core_spill_mask,
407                                        fp_spill_mask,
408                                        code,
409                                        code_size,
410                                        data_size,
411                                        osr,
412                                        roots,
413                                        has_should_deoptimize_flag,
414                                        cha_single_implementation_list);
415   if (result == nullptr) {
416     // Retry.
417     GarbageCollectCache(self);
418     result = CommitCodeInternal(self,
419                                 method,
420                                 stack_map,
421                                 method_info,
422                                 roots_data,
423                                 frame_size_in_bytes,
424                                 core_spill_mask,
425                                 fp_spill_mask,
426                                 code,
427                                 code_size,
428                                 data_size,
429                                 osr,
430                                 roots,
431                                 has_should_deoptimize_flag,
432                                 cha_single_implementation_list);
433   }
434   return result;
435 }
436 
WaitForPotentialCollectionToComplete(Thread * self)437 bool JitCodeCache::WaitForPotentialCollectionToComplete(Thread* self) {
438   bool in_collection = false;
439   while (collection_in_progress_) {
440     in_collection = true;
441     lock_cond_.Wait(self);
442   }
443   return in_collection;
444 }
445 
FromCodeToAllocation(const void * code)446 static uintptr_t FromCodeToAllocation(const void* code) {
447   size_t alignment = GetInstructionSetAlignment(kRuntimeISA);
448   return reinterpret_cast<uintptr_t>(code) - RoundUp(sizeof(OatQuickMethodHeader), alignment);
449 }
450 
ComputeRootTableSize(uint32_t number_of_roots)451 static uint32_t ComputeRootTableSize(uint32_t number_of_roots) {
452   return sizeof(uint32_t) + number_of_roots * sizeof(GcRoot<mirror::Object>);
453 }
454 
GetNumberOfRoots(const uint8_t * stack_map)455 static uint32_t GetNumberOfRoots(const uint8_t* stack_map) {
456   // The length of the table is stored just before the stack map (and therefore at the end of
457   // the table itself), in order to be able to fetch it from a `stack_map` pointer.
458   return reinterpret_cast<const uint32_t*>(stack_map)[-1];
459 }
460 
FillRootTableLength(uint8_t * roots_data,uint32_t length)461 static void FillRootTableLength(uint8_t* roots_data, uint32_t length) {
462   // Store the length of the table at the end. This will allow fetching it from a `stack_map`
463   // pointer.
464   reinterpret_cast<uint32_t*>(roots_data)[length] = length;
465 }
466 
FromStackMapToRoots(const uint8_t * stack_map_data)467 static const uint8_t* FromStackMapToRoots(const uint8_t* stack_map_data) {
468   return stack_map_data - ComputeRootTableSize(GetNumberOfRoots(stack_map_data));
469 }
470 
FillRootTable(uint8_t * roots_data,Handle<mirror::ObjectArray<mirror::Object>> roots)471 static void FillRootTable(uint8_t* roots_data, Handle<mirror::ObjectArray<mirror::Object>> roots)
472     REQUIRES_SHARED(Locks::mutator_lock_) {
473   GcRoot<mirror::Object>* gc_roots = reinterpret_cast<GcRoot<mirror::Object>*>(roots_data);
474   const uint32_t length = roots->GetLength();
475   // Put all roots in `roots_data`.
476   for (uint32_t i = 0; i < length; ++i) {
477     ObjPtr<mirror::Object> object = roots->Get(i);
478     if (kIsDebugBuild) {
479       // Ensure the string is strongly interned. b/32995596
480       if (object->IsString()) {
481         ObjPtr<mirror::String> str = reinterpret_cast<mirror::String*>(object.Ptr());
482         ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
483         CHECK(class_linker->GetInternTable()->LookupStrong(Thread::Current(), str) != nullptr);
484       }
485     }
486     gc_roots[i] = GcRoot<mirror::Object>(object);
487   }
488 }
489 
GetRootTable(const void * code_ptr,uint32_t * number_of_roots=nullptr)490 static uint8_t* GetRootTable(const void* code_ptr, uint32_t* number_of_roots = nullptr) {
491   OatQuickMethodHeader* method_header = OatQuickMethodHeader::FromCodePointer(code_ptr);
492   uint8_t* data = method_header->GetOptimizedCodeInfoPtr();
493   uint32_t roots = GetNumberOfRoots(data);
494   if (number_of_roots != nullptr) {
495     *number_of_roots = roots;
496   }
497   return data - ComputeRootTableSize(roots);
498 }
499 
500 // Use a sentinel for marking entries in the JIT table that have been cleared.
501 // This helps diagnosing in case the compiled code tries to wrongly access such
502 // entries.
503 static mirror::Class* const weak_sentinel =
504     reinterpret_cast<mirror::Class*>(Context::kBadGprBase + 0xff);
505 
506 // Helper for the GC to process a weak class in a JIT root table.
ProcessWeakClass(GcRoot<mirror::Class> * root_ptr,IsMarkedVisitor * visitor,mirror::Class * update)507 static inline void ProcessWeakClass(GcRoot<mirror::Class>* root_ptr,
508                                     IsMarkedVisitor* visitor,
509                                     mirror::Class* update)
510     REQUIRES_SHARED(Locks::mutator_lock_) {
511   // This does not need a read barrier because this is called by GC.
512   mirror::Class* cls = root_ptr->Read<kWithoutReadBarrier>();
513   if (cls != nullptr && cls != weak_sentinel) {
514     DCHECK((cls->IsClass<kDefaultVerifyFlags, kWithoutReadBarrier>()));
515     // Look at the classloader of the class to know if it has been unloaded.
516     // This does not need a read barrier because this is called by GC.
517     mirror::Object* class_loader =
518         cls->GetClassLoader<kDefaultVerifyFlags, kWithoutReadBarrier>();
519     if (class_loader == nullptr || visitor->IsMarked(class_loader) != nullptr) {
520       // The class loader is live, update the entry if the class has moved.
521       mirror::Class* new_cls = down_cast<mirror::Class*>(visitor->IsMarked(cls));
522       // Note that new_object can be null for CMS and newly allocated objects.
523       if (new_cls != nullptr && new_cls != cls) {
524         *root_ptr = GcRoot<mirror::Class>(new_cls);
525       }
526     } else {
527       // The class loader is not live, clear the entry.
528       *root_ptr = GcRoot<mirror::Class>(update);
529     }
530   }
531 }
532 
SweepRootTables(IsMarkedVisitor * visitor)533 void JitCodeCache::SweepRootTables(IsMarkedVisitor* visitor) {
534   MutexLock mu(Thread::Current(), lock_);
535   for (const auto& entry : method_code_map_) {
536     uint32_t number_of_roots = 0;
537     uint8_t* roots_data = GetRootTable(entry.first, &number_of_roots);
538     GcRoot<mirror::Object>* roots = reinterpret_cast<GcRoot<mirror::Object>*>(roots_data);
539     for (uint32_t i = 0; i < number_of_roots; ++i) {
540       // This does not need a read barrier because this is called by GC.
541       mirror::Object* object = roots[i].Read<kWithoutReadBarrier>();
542       if (object == nullptr || object == weak_sentinel) {
543         // entry got deleted in a previous sweep.
544       } else if (object->IsString<kDefaultVerifyFlags, kWithoutReadBarrier>()) {
545         mirror::Object* new_object = visitor->IsMarked(object);
546         // We know the string is marked because it's a strongly-interned string that
547         // is always alive. The IsMarked implementation of the CMS collector returns
548         // null for newly allocated objects, but we know those haven't moved. Therefore,
549         // only update the entry if we get a different non-null string.
550         // TODO: Do not use IsMarked for j.l.Class, and adjust once we move this method
551         // out of the weak access/creation pause. b/32167580
552         if (new_object != nullptr && new_object != object) {
553           DCHECK(new_object->IsString());
554           roots[i] = GcRoot<mirror::Object>(new_object);
555         }
556       } else {
557         ProcessWeakClass(
558             reinterpret_cast<GcRoot<mirror::Class>*>(&roots[i]), visitor, weak_sentinel);
559       }
560     }
561   }
562   // Walk over inline caches to clear entries containing unloaded classes.
563   for (ProfilingInfo* info : profiling_infos_) {
564     for (size_t i = 0; i < info->number_of_inline_caches_; ++i) {
565       InlineCache* cache = &info->cache_[i];
566       for (size_t j = 0; j < InlineCache::kIndividualCacheSize; ++j) {
567         ProcessWeakClass(&cache->classes_[j], visitor, nullptr);
568       }
569     }
570   }
571 }
572 
FreeCode(const void * code_ptr)573 void JitCodeCache::FreeCode(const void* code_ptr) {
574   uintptr_t allocation = FromCodeToAllocation(code_ptr);
575   // Notify native debugger that we are about to remove the code.
576   // It does nothing if we are not using native debugger.
577   MutexLock mu(Thread::Current(), *Locks::native_debug_interface_lock_);
578   RemoveNativeDebugInfoForJit(code_ptr);
579   if (OatQuickMethodHeader::FromCodePointer(code_ptr)->IsOptimized()) {
580     FreeData(GetRootTable(code_ptr));
581   }  // else this is a JNI stub without any data.
582   FreeCode(reinterpret_cast<uint8_t*>(allocation));
583 }
584 
FreeAllMethodHeaders(const std::unordered_set<OatQuickMethodHeader * > & method_headers)585 void JitCodeCache::FreeAllMethodHeaders(
586     const std::unordered_set<OatQuickMethodHeader*>& method_headers) {
587   {
588     MutexLock mu(Thread::Current(), *Locks::cha_lock_);
589     Runtime::Current()->GetClassLinker()->GetClassHierarchyAnalysis()
590         ->RemoveDependentsWithMethodHeaders(method_headers);
591   }
592 
593   // We need to remove entries in method_headers from CHA dependencies
594   // first since once we do FreeCode() below, the memory can be reused
595   // so it's possible for the same method_header to start representing
596   // different compile code.
597   MutexLock mu(Thread::Current(), lock_);
598   ScopedCodeCacheWrite scc(this);
599   for (const OatQuickMethodHeader* method_header : method_headers) {
600     FreeCode(method_header->GetCode());
601   }
602 }
603 
RemoveMethodsIn(Thread * self,const LinearAlloc & alloc)604 void JitCodeCache::RemoveMethodsIn(Thread* self, const LinearAlloc& alloc) {
605   ScopedTrace trace(__PRETTY_FUNCTION__);
606   // We use a set to first collect all method_headers whose code need to be
607   // removed. We need to free the underlying code after we remove CHA dependencies
608   // for entries in this set. And it's more efficient to iterate through
609   // the CHA dependency map just once with an unordered_set.
610   std::unordered_set<OatQuickMethodHeader*> method_headers;
611   {
612     MutexLock mu(self, lock_);
613     // We do not check if a code cache GC is in progress, as this method comes
614     // with the classlinker_classes_lock_ held, and suspending ourselves could
615     // lead to a deadlock.
616     {
617       ScopedCodeCacheWrite scc(this);
618       for (auto it = jni_stubs_map_.begin(); it != jni_stubs_map_.end();) {
619         it->second.RemoveMethodsIn(alloc);
620         if (it->second.GetMethods().empty()) {
621           method_headers.insert(OatQuickMethodHeader::FromCodePointer(it->second.GetCode()));
622           it = jni_stubs_map_.erase(it);
623         } else {
624           it->first.UpdateShorty(it->second.GetMethods().front());
625           ++it;
626         }
627       }
628       for (auto it = method_code_map_.begin(); it != method_code_map_.end();) {
629         if (alloc.ContainsUnsafe(it->second)) {
630           method_headers.insert(OatQuickMethodHeader::FromCodePointer(it->first));
631           it = method_code_map_.erase(it);
632         } else {
633           ++it;
634         }
635       }
636     }
637     for (auto it = osr_code_map_.begin(); it != osr_code_map_.end();) {
638       if (alloc.ContainsUnsafe(it->first)) {
639         // Note that the code has already been pushed to method_headers in the loop
640         // above and is going to be removed in FreeCode() below.
641         it = osr_code_map_.erase(it);
642       } else {
643         ++it;
644       }
645     }
646     for (auto it = profiling_infos_.begin(); it != profiling_infos_.end();) {
647       ProfilingInfo* info = *it;
648       if (alloc.ContainsUnsafe(info->GetMethod())) {
649         info->GetMethod()->SetProfilingInfo(nullptr);
650         FreeData(reinterpret_cast<uint8_t*>(info));
651         it = profiling_infos_.erase(it);
652       } else {
653         ++it;
654       }
655     }
656   }
657   FreeAllMethodHeaders(method_headers);
658 }
659 
IsWeakAccessEnabled(Thread * self) const660 bool JitCodeCache::IsWeakAccessEnabled(Thread* self) const {
661   return kUseReadBarrier
662       ? self->GetWeakRefAccessEnabled()
663       : is_weak_access_enabled_.LoadSequentiallyConsistent();
664 }
665 
WaitUntilInlineCacheAccessible(Thread * self)666 void JitCodeCache::WaitUntilInlineCacheAccessible(Thread* self) {
667   if (IsWeakAccessEnabled(self)) {
668     return;
669   }
670   ScopedThreadSuspension sts(self, kWaitingWeakGcRootRead);
671   MutexLock mu(self, lock_);
672   while (!IsWeakAccessEnabled(self)) {
673     inline_cache_cond_.Wait(self);
674   }
675 }
676 
BroadcastForInlineCacheAccess()677 void JitCodeCache::BroadcastForInlineCacheAccess() {
678   Thread* self = Thread::Current();
679   MutexLock mu(self, lock_);
680   inline_cache_cond_.Broadcast(self);
681 }
682 
AllowInlineCacheAccess()683 void JitCodeCache::AllowInlineCacheAccess() {
684   DCHECK(!kUseReadBarrier);
685   is_weak_access_enabled_.StoreSequentiallyConsistent(true);
686   BroadcastForInlineCacheAccess();
687 }
688 
DisallowInlineCacheAccess()689 void JitCodeCache::DisallowInlineCacheAccess() {
690   DCHECK(!kUseReadBarrier);
691   is_weak_access_enabled_.StoreSequentiallyConsistent(false);
692 }
693 
CopyInlineCacheInto(const InlineCache & ic,Handle<mirror::ObjectArray<mirror::Class>> array)694 void JitCodeCache::CopyInlineCacheInto(const InlineCache& ic,
695                                        Handle<mirror::ObjectArray<mirror::Class>> array) {
696   WaitUntilInlineCacheAccessible(Thread::Current());
697   // Note that we don't need to lock `lock_` here, the compiler calling
698   // this method has already ensured the inline cache will not be deleted.
699   for (size_t in_cache = 0, in_array = 0;
700        in_cache < InlineCache::kIndividualCacheSize;
701        ++in_cache) {
702     mirror::Class* object = ic.classes_[in_cache].Read();
703     if (object != nullptr) {
704       array->Set(in_array++, object);
705     }
706   }
707 }
708 
ClearMethodCounter(ArtMethod * method,bool was_warm)709 static void ClearMethodCounter(ArtMethod* method, bool was_warm) {
710   if (was_warm) {
711     // Don't do any read barrier, as the declaring class of `method` may
712     // be in the process of being GC'ed (reading the declaring class is done
713     // when DCHECKing the declaring class is resolved, which we know it is
714     // at this point).
715     method->SetPreviouslyWarm<kWithoutReadBarrier>();
716   }
717   // We reset the counter to 1 so that the profile knows that the method was executed at least once.
718   // This is required for layout purposes.
719   // We also need to make sure we'll pass the warmup threshold again, so we set to 0 if
720   // the warmup threshold is 1.
721   uint16_t jit_warmup_threshold = Runtime::Current()->GetJITOptions()->GetWarmupThreshold();
722   method->SetCounter(std::min(jit_warmup_threshold - 1, 1));
723 }
724 
CommitCodeInternal(Thread * self,ArtMethod * method,uint8_t * stack_map,uint8_t * method_info,uint8_t * roots_data,size_t frame_size_in_bytes,size_t core_spill_mask,size_t fp_spill_mask,const uint8_t * code,size_t code_size,size_t data_size,bool osr,Handle<mirror::ObjectArray<mirror::Object>> roots,bool has_should_deoptimize_flag,const ArenaSet<ArtMethod * > & cha_single_implementation_list)725 uint8_t* JitCodeCache::CommitCodeInternal(Thread* self,
726                                           ArtMethod* method,
727                                           uint8_t* stack_map,
728                                           uint8_t* method_info,
729                                           uint8_t* roots_data,
730                                           size_t frame_size_in_bytes,
731                                           size_t core_spill_mask,
732                                           size_t fp_spill_mask,
733                                           const uint8_t* code,
734                                           size_t code_size,
735                                           size_t data_size,
736                                           bool osr,
737                                           Handle<mirror::ObjectArray<mirror::Object>> roots,
738                                           bool has_should_deoptimize_flag,
739                                           const ArenaSet<ArtMethod*>&
740                                               cha_single_implementation_list) {
741   DCHECK_NE(stack_map != nullptr, method->IsNative());
742   DCHECK(!method->IsNative() || !osr);
743   size_t alignment = GetInstructionSetAlignment(kRuntimeISA);
744   // Ensure the header ends up at expected instruction alignment.
745   size_t header_size = RoundUp(sizeof(OatQuickMethodHeader), alignment);
746   size_t total_size = header_size + code_size;
747 
748   OatQuickMethodHeader* method_header = nullptr;
749   uint8_t* code_ptr = nullptr;
750   uint8_t* memory = nullptr;
751   {
752     ScopedThreadSuspension sts(self, kSuspended);
753     MutexLock mu(self, lock_);
754     WaitForPotentialCollectionToComplete(self);
755     {
756       ScopedCodeCacheWrite scc(this);
757       memory = AllocateCode(total_size);
758       if (memory == nullptr) {
759         return nullptr;
760       }
761       code_ptr = memory + header_size;
762 
763       std::copy(code, code + code_size, code_ptr);
764       method_header = OatQuickMethodHeader::FromCodePointer(code_ptr);
765       new (method_header) OatQuickMethodHeader(
766           (stack_map != nullptr) ? code_ptr - stack_map : 0u,
767           (method_info != nullptr) ? code_ptr - method_info : 0u,
768           frame_size_in_bytes,
769           core_spill_mask,
770           fp_spill_mask,
771           code_size);
772       // Flush caches before we remove write permission because some ARMv8 Qualcomm kernels may
773       // trigger a segfault if a page fault occurs when requesting a cache maintenance operation.
774       // This is a kernel bug that we need to work around until affected devices (e.g. Nexus 5X and
775       // 6P) stop being supported or their kernels are fixed.
776       //
777       // For reference, this behavior is caused by this commit:
778       // https://android.googlesource.com/kernel/msm/+/3fbe6bc28a6b9939d0650f2f17eb5216c719950c
779       FlushInstructionCache(reinterpret_cast<char*>(code_ptr),
780                             reinterpret_cast<char*>(code_ptr + code_size));
781       DCHECK(!Runtime::Current()->IsAotCompiler());
782       if (has_should_deoptimize_flag) {
783         method_header->SetHasShouldDeoptimizeFlag();
784       }
785     }
786 
787     number_of_compilations_++;
788   }
789   // We need to update the entry point in the runnable state for the instrumentation.
790   {
791     // Need cha_lock_ for checking all single-implementation flags and register
792     // dependencies.
793     MutexLock cha_mu(self, *Locks::cha_lock_);
794     bool single_impl_still_valid = true;
795     for (ArtMethod* single_impl : cha_single_implementation_list) {
796       if (!single_impl->HasSingleImplementation()) {
797         // Simply discard the compiled code. Clear the counter so that it may be recompiled later.
798         // Hopefully the class hierarchy will be more stable when compilation is retried.
799         single_impl_still_valid = false;
800         ClearMethodCounter(method, /*was_warm*/ false);
801         break;
802       }
803     }
804 
805     // Discard the code if any single-implementation assumptions are now invalid.
806     if (!single_impl_still_valid) {
807       VLOG(jit) << "JIT discarded jitted code due to invalid single-implementation assumptions.";
808       return nullptr;
809     }
810     DCHECK(cha_single_implementation_list.empty() || !Runtime::Current()->IsJavaDebuggable())
811         << "Should not be using cha on debuggable apps/runs!";
812 
813     for (ArtMethod* single_impl : cha_single_implementation_list) {
814       Runtime::Current()->GetClassLinker()->GetClassHierarchyAnalysis()->AddDependency(
815           single_impl, method, method_header);
816     }
817 
818     // The following needs to be guarded by cha_lock_ also. Otherwise it's
819     // possible that the compiled code is considered invalidated by some class linking,
820     // but below we still make the compiled code valid for the method.
821     MutexLock mu(self, lock_);
822     if (UNLIKELY(method->IsNative())) {
823       DCHECK(stack_map == nullptr);
824       DCHECK(roots_data == nullptr);
825       auto it = jni_stubs_map_.find(JniStubKey(method));
826       DCHECK(it != jni_stubs_map_.end())
827           << "Entry inserted in NotifyCompilationOf() should be alive.";
828       JniStubData* data = &it->second;
829       DCHECK(ContainsElement(data->GetMethods(), method))
830           << "Entry inserted in NotifyCompilationOf() should contain this method.";
831       data->SetCode(code_ptr);
832       instrumentation::Instrumentation* instrum = Runtime::Current()->GetInstrumentation();
833       for (ArtMethod* m : data->GetMethods()) {
834         instrum->UpdateMethodsCode(m, method_header->GetEntryPoint());
835       }
836     } else {
837       // Fill the root table before updating the entry point.
838       DCHECK_EQ(FromStackMapToRoots(stack_map), roots_data);
839       DCHECK_LE(roots_data, stack_map);
840       FillRootTable(roots_data, roots);
841       {
842         // Flush data cache, as compiled code references literals in it.
843         // We also need a TLB shootdown to act as memory barrier across cores.
844         ScopedCodeCacheWrite ccw(this, /* only_for_tlb_shootdown */ true);
845         FlushDataCache(reinterpret_cast<char*>(roots_data),
846                        reinterpret_cast<char*>(roots_data + data_size));
847       }
848       method_code_map_.Put(code_ptr, method);
849       if (osr) {
850         number_of_osr_compilations_++;
851         osr_code_map_.Put(method, code_ptr);
852       } else {
853         Runtime::Current()->GetInstrumentation()->UpdateMethodsCode(
854             method, method_header->GetEntryPoint());
855       }
856     }
857     if (collection_in_progress_) {
858       // We need to update the live bitmap if there is a GC to ensure it sees this new
859       // code.
860       GetLiveBitmap()->AtomicTestAndSet(FromCodeToAllocation(code_ptr));
861     }
862     last_update_time_ns_.StoreRelease(NanoTime());
863     VLOG(jit)
864         << "JIT added (osr=" << std::boolalpha << osr << std::noboolalpha << ") "
865         << ArtMethod::PrettyMethod(method) << "@" << method
866         << " ccache_size=" << PrettySize(CodeCacheSizeLocked()) << ": "
867         << " dcache_size=" << PrettySize(DataCacheSizeLocked()) << ": "
868         << reinterpret_cast<const void*>(method_header->GetEntryPoint()) << ","
869         << reinterpret_cast<const void*>(method_header->GetEntryPoint() +
870                                          method_header->GetCodeSize());
871     histogram_code_memory_use_.AddValue(code_size);
872     if (code_size > kCodeSizeLogThreshold) {
873       LOG(INFO) << "JIT allocated "
874                 << PrettySize(code_size)
875                 << " for compiled code of "
876                 << ArtMethod::PrettyMethod(method);
877     }
878   }
879 
880   return reinterpret_cast<uint8_t*>(method_header);
881 }
882 
CodeCacheSize()883 size_t JitCodeCache::CodeCacheSize() {
884   MutexLock mu(Thread::Current(), lock_);
885   return CodeCacheSizeLocked();
886 }
887 
RemoveMethod(ArtMethod * method,bool release_memory)888 bool JitCodeCache::RemoveMethod(ArtMethod* method, bool release_memory) {
889   // This function is used only for testing and only with non-native methods.
890   CHECK(!method->IsNative());
891 
892   MutexLock mu(Thread::Current(), lock_);
893 
894   bool osr = osr_code_map_.find(method) != osr_code_map_.end();
895   bool in_cache = RemoveMethodLocked(method, release_memory);
896 
897   if (!in_cache) {
898     return false;
899   }
900 
901   method->ClearCounter();
902   Runtime::Current()->GetInstrumentation()->UpdateMethodsCode(
903       method, GetQuickToInterpreterBridge());
904   VLOG(jit)
905       << "JIT removed (osr=" << std::boolalpha << osr << std::noboolalpha << ") "
906       << ArtMethod::PrettyMethod(method) << "@" << method
907       << " ccache_size=" << PrettySize(CodeCacheSizeLocked()) << ": "
908       << " dcache_size=" << PrettySize(DataCacheSizeLocked());
909   return true;
910 }
911 
RemoveMethodLocked(ArtMethod * method,bool release_memory)912 bool JitCodeCache::RemoveMethodLocked(ArtMethod* method, bool release_memory) {
913   if (LIKELY(!method->IsNative())) {
914     ProfilingInfo* info = method->GetProfilingInfo(kRuntimePointerSize);
915     if (info != nullptr) {
916       RemoveElement(profiling_infos_, info);
917     }
918     method->SetProfilingInfo(nullptr);
919   }
920 
921   bool in_cache = false;
922   ScopedCodeCacheWrite ccw(this);
923   if (UNLIKELY(method->IsNative())) {
924     auto it = jni_stubs_map_.find(JniStubKey(method));
925     if (it != jni_stubs_map_.end() && it->second.RemoveMethod(method)) {
926       in_cache = true;
927       if (it->second.GetMethods().empty()) {
928         if (release_memory) {
929           FreeCode(it->second.GetCode());
930         }
931         jni_stubs_map_.erase(it);
932       } else {
933         it->first.UpdateShorty(it->second.GetMethods().front());
934       }
935     }
936   } else {
937     for (auto it = method_code_map_.begin(); it != method_code_map_.end();) {
938       if (it->second == method) {
939         in_cache = true;
940         if (release_memory) {
941           FreeCode(it->first);
942         }
943         it = method_code_map_.erase(it);
944       } else {
945         ++it;
946       }
947     }
948 
949     auto osr_it = osr_code_map_.find(method);
950     if (osr_it != osr_code_map_.end()) {
951       osr_code_map_.erase(osr_it);
952     }
953   }
954 
955   return in_cache;
956 }
957 
958 // This notifies the code cache that the given method has been redefined and that it should remove
959 // any cached information it has on the method. All threads must be suspended before calling this
960 // method. The compiled code for the method (if there is any) must not be in any threads call stack.
NotifyMethodRedefined(ArtMethod * method)961 void JitCodeCache::NotifyMethodRedefined(ArtMethod* method) {
962   MutexLock mu(Thread::Current(), lock_);
963   RemoveMethodLocked(method, /* release_memory */ true);
964 }
965 
966 // This invalidates old_method. Once this function returns one can no longer use old_method to
967 // execute code unless it is fixed up. This fixup will happen later in the process of installing a
968 // class redefinition.
969 // TODO We should add some info to ArtMethod to note that 'old_method' has been invalidated and
970 // shouldn't be used since it is no longer logically in the jit code cache.
971 // TODO We should add DCHECKS that validate that the JIT is paused when this method is entered.
MoveObsoleteMethod(ArtMethod * old_method,ArtMethod * new_method)972 void JitCodeCache::MoveObsoleteMethod(ArtMethod* old_method, ArtMethod* new_method) {
973   MutexLock mu(Thread::Current(), lock_);
974   if (old_method->IsNative()) {
975     // Update methods in jni_stubs_map_.
976     for (auto& entry : jni_stubs_map_) {
977       JniStubData& data = entry.second;
978       data.MoveObsoleteMethod(old_method, new_method);
979     }
980     return;
981   }
982   // Update ProfilingInfo to the new one and remove it from the old_method.
983   if (old_method->GetProfilingInfo(kRuntimePointerSize) != nullptr) {
984     DCHECK_EQ(old_method->GetProfilingInfo(kRuntimePointerSize)->GetMethod(), old_method);
985     ProfilingInfo* info = old_method->GetProfilingInfo(kRuntimePointerSize);
986     old_method->SetProfilingInfo(nullptr);
987     // Since the JIT should be paused and all threads suspended by the time this is called these
988     // checks should always pass.
989     DCHECK(!info->IsInUseByCompiler());
990     new_method->SetProfilingInfo(info);
991     info->method_ = new_method;
992   }
993   // Update method_code_map_ to point to the new method.
994   for (auto& it : method_code_map_) {
995     if (it.second == old_method) {
996       it.second = new_method;
997     }
998   }
999   // Update osr_code_map_ to point to the new method.
1000   auto code_map = osr_code_map_.find(old_method);
1001   if (code_map != osr_code_map_.end()) {
1002     osr_code_map_.Put(new_method, code_map->second);
1003     osr_code_map_.erase(old_method);
1004   }
1005 }
1006 
CodeCacheSizeLocked()1007 size_t JitCodeCache::CodeCacheSizeLocked() {
1008   return used_memory_for_code_;
1009 }
1010 
DataCacheSize()1011 size_t JitCodeCache::DataCacheSize() {
1012   MutexLock mu(Thread::Current(), lock_);
1013   return DataCacheSizeLocked();
1014 }
1015 
DataCacheSizeLocked()1016 size_t JitCodeCache::DataCacheSizeLocked() {
1017   return used_memory_for_data_;
1018 }
1019 
ClearData(Thread * self,uint8_t * stack_map_data,uint8_t * roots_data)1020 void JitCodeCache::ClearData(Thread* self,
1021                              uint8_t* stack_map_data,
1022                              uint8_t* roots_data) {
1023   DCHECK_EQ(FromStackMapToRoots(stack_map_data), roots_data);
1024   MutexLock mu(self, lock_);
1025   FreeData(reinterpret_cast<uint8_t*>(roots_data));
1026 }
1027 
ReserveData(Thread * self,size_t stack_map_size,size_t method_info_size,size_t number_of_roots,ArtMethod * method,uint8_t ** stack_map_data,uint8_t ** method_info_data,uint8_t ** roots_data)1028 size_t JitCodeCache::ReserveData(Thread* self,
1029                                  size_t stack_map_size,
1030                                  size_t method_info_size,
1031                                  size_t number_of_roots,
1032                                  ArtMethod* method,
1033                                  uint8_t** stack_map_data,
1034                                  uint8_t** method_info_data,
1035                                  uint8_t** roots_data) {
1036   size_t table_size = ComputeRootTableSize(number_of_roots);
1037   size_t size = RoundUp(stack_map_size + method_info_size + table_size, sizeof(void*));
1038   uint8_t* result = nullptr;
1039 
1040   {
1041     ScopedThreadSuspension sts(self, kSuspended);
1042     MutexLock mu(self, lock_);
1043     WaitForPotentialCollectionToComplete(self);
1044     result = AllocateData(size);
1045   }
1046 
1047   if (result == nullptr) {
1048     // Retry.
1049     GarbageCollectCache(self);
1050     ScopedThreadSuspension sts(self, kSuspended);
1051     MutexLock mu(self, lock_);
1052     WaitForPotentialCollectionToComplete(self);
1053     result = AllocateData(size);
1054   }
1055 
1056   MutexLock mu(self, lock_);
1057   histogram_stack_map_memory_use_.AddValue(size);
1058   if (size > kStackMapSizeLogThreshold) {
1059     LOG(INFO) << "JIT allocated "
1060               << PrettySize(size)
1061               << " for stack maps of "
1062               << ArtMethod::PrettyMethod(method);
1063   }
1064   if (result != nullptr) {
1065     *roots_data = result;
1066     *stack_map_data = result + table_size;
1067     *method_info_data = *stack_map_data + stack_map_size;
1068     FillRootTableLength(*roots_data, number_of_roots);
1069     return size;
1070   } else {
1071     *roots_data = nullptr;
1072     *stack_map_data = nullptr;
1073     *method_info_data = nullptr;
1074     return 0;
1075   }
1076 }
1077 
1078 class MarkCodeVisitor FINAL : public StackVisitor {
1079  public:
MarkCodeVisitor(Thread * thread_in,JitCodeCache * code_cache_in)1080   MarkCodeVisitor(Thread* thread_in, JitCodeCache* code_cache_in)
1081       : StackVisitor(thread_in, nullptr, StackVisitor::StackWalkKind::kSkipInlinedFrames),
1082         code_cache_(code_cache_in),
1083         bitmap_(code_cache_->GetLiveBitmap()) {}
1084 
VisitFrame()1085   bool VisitFrame() OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
1086     const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader();
1087     if (method_header == nullptr) {
1088       return true;
1089     }
1090     const void* code = method_header->GetCode();
1091     if (code_cache_->ContainsPc(code)) {
1092       // Use the atomic set version, as multiple threads are executing this code.
1093       bitmap_->AtomicTestAndSet(FromCodeToAllocation(code));
1094     }
1095     return true;
1096   }
1097 
1098  private:
1099   JitCodeCache* const code_cache_;
1100   CodeCacheBitmap* const bitmap_;
1101 };
1102 
1103 class MarkCodeClosure FINAL : public Closure {
1104  public:
MarkCodeClosure(JitCodeCache * code_cache,Barrier * barrier)1105   MarkCodeClosure(JitCodeCache* code_cache, Barrier* barrier)
1106       : code_cache_(code_cache), barrier_(barrier) {}
1107 
Run(Thread * thread)1108   void Run(Thread* thread) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
1109     ScopedTrace trace(__PRETTY_FUNCTION__);
1110     DCHECK(thread == Thread::Current() || thread->IsSuspended());
1111     MarkCodeVisitor visitor(thread, code_cache_);
1112     visitor.WalkStack();
1113     if (kIsDebugBuild) {
1114       // The stack walking code queries the side instrumentation stack if it
1115       // sees an instrumentation exit pc, so the JIT code of methods in that stack
1116       // must have been seen. We sanity check this below.
1117       for (const instrumentation::InstrumentationStackFrame& frame
1118               : *thread->GetInstrumentationStack()) {
1119         // The 'method_' in InstrumentationStackFrame is the one that has return_pc_ in
1120         // its stack frame, it is not the method owning return_pc_. We just pass null to
1121         // LookupMethodHeader: the method is only checked against in debug builds.
1122         OatQuickMethodHeader* method_header =
1123             code_cache_->LookupMethodHeader(frame.return_pc_, /* method */ nullptr);
1124         if (method_header != nullptr) {
1125           const void* code = method_header->GetCode();
1126           CHECK(code_cache_->GetLiveBitmap()->Test(FromCodeToAllocation(code)));
1127         }
1128       }
1129     }
1130     barrier_->Pass(Thread::Current());
1131   }
1132 
1133  private:
1134   JitCodeCache* const code_cache_;
1135   Barrier* const barrier_;
1136 };
1137 
NotifyCollectionDone(Thread * self)1138 void JitCodeCache::NotifyCollectionDone(Thread* self) {
1139   collection_in_progress_ = false;
1140   lock_cond_.Broadcast(self);
1141 }
1142 
SetFootprintLimit(size_t new_footprint)1143 void JitCodeCache::SetFootprintLimit(size_t new_footprint) {
1144   size_t per_space_footprint = new_footprint / 2;
1145   DCHECK(IsAlignedParam(per_space_footprint, kPageSize));
1146   DCHECK_EQ(per_space_footprint * 2, new_footprint);
1147   mspace_set_footprint_limit(data_mspace_, per_space_footprint);
1148   {
1149     ScopedCodeCacheWrite scc(this);
1150     mspace_set_footprint_limit(code_mspace_, per_space_footprint);
1151   }
1152 }
1153 
IncreaseCodeCacheCapacity()1154 bool JitCodeCache::IncreaseCodeCacheCapacity() {
1155   if (current_capacity_ == max_capacity_) {
1156     return false;
1157   }
1158 
1159   // Double the capacity if we're below 1MB, or increase it by 1MB if
1160   // we're above.
1161   if (current_capacity_ < 1 * MB) {
1162     current_capacity_ *= 2;
1163   } else {
1164     current_capacity_ += 1 * MB;
1165   }
1166   if (current_capacity_ > max_capacity_) {
1167     current_capacity_ = max_capacity_;
1168   }
1169 
1170   VLOG(jit) << "Increasing code cache capacity to " << PrettySize(current_capacity_);
1171 
1172   SetFootprintLimit(current_capacity_);
1173 
1174   return true;
1175 }
1176 
MarkCompiledCodeOnThreadStacks(Thread * self)1177 void JitCodeCache::MarkCompiledCodeOnThreadStacks(Thread* self) {
1178   Barrier barrier(0);
1179   size_t threads_running_checkpoint = 0;
1180   MarkCodeClosure closure(this, &barrier);
1181   threads_running_checkpoint = Runtime::Current()->GetThreadList()->RunCheckpoint(&closure);
1182   // Now that we have run our checkpoint, move to a suspended state and wait
1183   // for other threads to run the checkpoint.
1184   ScopedThreadSuspension sts(self, kSuspended);
1185   if (threads_running_checkpoint != 0) {
1186     barrier.Increment(self, threads_running_checkpoint);
1187   }
1188 }
1189 
ShouldDoFullCollection()1190 bool JitCodeCache::ShouldDoFullCollection() {
1191   if (current_capacity_ == max_capacity_) {
1192     // Always do a full collection when the code cache is full.
1193     return true;
1194   } else if (current_capacity_ < kReservedCapacity) {
1195     // Always do partial collection when the code cache size is below the reserved
1196     // capacity.
1197     return false;
1198   } else if (last_collection_increased_code_cache_) {
1199     // This time do a full collection.
1200     return true;
1201   } else {
1202     // This time do a partial collection.
1203     return false;
1204   }
1205 }
1206 
GarbageCollectCache(Thread * self)1207 void JitCodeCache::GarbageCollectCache(Thread* self) {
1208   ScopedTrace trace(__FUNCTION__);
1209   if (!garbage_collect_code_) {
1210     MutexLock mu(self, lock_);
1211     IncreaseCodeCacheCapacity();
1212     return;
1213   }
1214 
1215   // Wait for an existing collection, or let everyone know we are starting one.
1216   {
1217     ScopedThreadSuspension sts(self, kSuspended);
1218     MutexLock mu(self, lock_);
1219     if (WaitForPotentialCollectionToComplete(self)) {
1220       return;
1221     } else {
1222       number_of_collections_++;
1223       live_bitmap_.reset(CodeCacheBitmap::Create(
1224           "code-cache-bitmap",
1225           reinterpret_cast<uintptr_t>(code_map_->Begin()),
1226           reinterpret_cast<uintptr_t>(code_map_->Begin() + current_capacity_ / 2)));
1227       collection_in_progress_ = true;
1228     }
1229   }
1230 
1231   TimingLogger logger("JIT code cache timing logger", true, VLOG_IS_ON(jit));
1232   {
1233     TimingLogger::ScopedTiming st("Code cache collection", &logger);
1234 
1235     bool do_full_collection = false;
1236     {
1237       MutexLock mu(self, lock_);
1238       do_full_collection = ShouldDoFullCollection();
1239     }
1240 
1241     VLOG(jit) << "Do "
1242               << (do_full_collection ? "full" : "partial")
1243               << " code cache collection, code="
1244               << PrettySize(CodeCacheSize())
1245               << ", data=" << PrettySize(DataCacheSize());
1246 
1247     DoCollection(self, /* collect_profiling_info */ do_full_collection);
1248 
1249     VLOG(jit) << "After code cache collection, code="
1250               << PrettySize(CodeCacheSize())
1251               << ", data=" << PrettySize(DataCacheSize());
1252 
1253     {
1254       MutexLock mu(self, lock_);
1255 
1256       // Increase the code cache only when we do partial collections.
1257       // TODO: base this strategy on how full the code cache is?
1258       if (do_full_collection) {
1259         last_collection_increased_code_cache_ = false;
1260       } else {
1261         last_collection_increased_code_cache_ = true;
1262         IncreaseCodeCacheCapacity();
1263       }
1264 
1265       bool next_collection_will_be_full = ShouldDoFullCollection();
1266 
1267       // Start polling the liveness of compiled code to prepare for the next full collection.
1268       if (next_collection_will_be_full) {
1269         // Save the entry point of methods we have compiled, and update the entry
1270         // point of those methods to the interpreter. If the method is invoked, the
1271         // interpreter will update its entry point to the compiled code and call it.
1272         for (ProfilingInfo* info : profiling_infos_) {
1273           const void* entry_point = info->GetMethod()->GetEntryPointFromQuickCompiledCode();
1274           if (ContainsPc(entry_point)) {
1275             info->SetSavedEntryPoint(entry_point);
1276             // Don't call Instrumentation::UpdateMethodsCode(), as it can check the declaring
1277             // class of the method. We may be concurrently running a GC which makes accessing
1278             // the class unsafe. We know it is OK to bypass the instrumentation as we've just
1279             // checked that the current entry point is JIT compiled code.
1280             info->GetMethod()->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge());
1281           }
1282         }
1283 
1284         DCHECK(CheckLiveCompiledCodeHasProfilingInfo());
1285 
1286         // Change entry points of native methods back to the GenericJNI entrypoint.
1287         for (const auto& entry : jni_stubs_map_) {
1288           const JniStubData& data = entry.second;
1289           if (!data.IsCompiled()) {
1290             continue;
1291           }
1292           // Make sure a single invocation of the GenericJNI trampoline tries to recompile.
1293           uint16_t new_counter = Runtime::Current()->GetJit()->HotMethodThreshold() - 1u;
1294           const OatQuickMethodHeader* method_header =
1295               OatQuickMethodHeader::FromCodePointer(data.GetCode());
1296           for (ArtMethod* method : data.GetMethods()) {
1297             if (method->GetEntryPointFromQuickCompiledCode() == method_header->GetEntryPoint()) {
1298               // Don't call Instrumentation::UpdateMethodsCode(), same as for normal methods above.
1299               method->SetCounter(new_counter);
1300               method->SetEntryPointFromQuickCompiledCode(GetQuickGenericJniStub());
1301             }
1302           }
1303         }
1304       }
1305       live_bitmap_.reset(nullptr);
1306       NotifyCollectionDone(self);
1307     }
1308   }
1309   Runtime::Current()->GetJit()->AddTimingLogger(logger);
1310 }
1311 
RemoveUnmarkedCode(Thread * self)1312 void JitCodeCache::RemoveUnmarkedCode(Thread* self) {
1313   ScopedTrace trace(__FUNCTION__);
1314   std::unordered_set<OatQuickMethodHeader*> method_headers;
1315   {
1316     MutexLock mu(self, lock_);
1317     ScopedCodeCacheWrite scc(this);
1318     // Iterate over all compiled code and remove entries that are not marked.
1319     for (auto it = jni_stubs_map_.begin(); it != jni_stubs_map_.end();) {
1320       JniStubData* data = &it->second;
1321       if (!data->IsCompiled() || GetLiveBitmap()->Test(FromCodeToAllocation(data->GetCode()))) {
1322         ++it;
1323       } else {
1324         method_headers.insert(OatQuickMethodHeader::FromCodePointer(data->GetCode()));
1325         it = jni_stubs_map_.erase(it);
1326       }
1327     }
1328     for (auto it = method_code_map_.begin(); it != method_code_map_.end();) {
1329       const void* code_ptr = it->first;
1330       uintptr_t allocation = FromCodeToAllocation(code_ptr);
1331       if (GetLiveBitmap()->Test(allocation)) {
1332         ++it;
1333       } else {
1334         method_headers.insert(OatQuickMethodHeader::FromCodePointer(code_ptr));
1335         it = method_code_map_.erase(it);
1336       }
1337     }
1338   }
1339   FreeAllMethodHeaders(method_headers);
1340 }
1341 
DoCollection(Thread * self,bool collect_profiling_info)1342 void JitCodeCache::DoCollection(Thread* self, bool collect_profiling_info) {
1343   ScopedTrace trace(__FUNCTION__);
1344   {
1345     MutexLock mu(self, lock_);
1346     if (collect_profiling_info) {
1347       // Clear the profiling info of methods that do not have compiled code as entrypoint.
1348       // Also remove the saved entry point from the ProfilingInfo objects.
1349       for (ProfilingInfo* info : profiling_infos_) {
1350         const void* ptr = info->GetMethod()->GetEntryPointFromQuickCompiledCode();
1351         if (!ContainsPc(ptr) && !info->IsInUseByCompiler()) {
1352           info->GetMethod()->SetProfilingInfo(nullptr);
1353         }
1354 
1355         if (info->GetSavedEntryPoint() != nullptr) {
1356           info->SetSavedEntryPoint(nullptr);
1357           // We are going to move this method back to interpreter. Clear the counter now to
1358           // give it a chance to be hot again.
1359           ClearMethodCounter(info->GetMethod(), /*was_warm*/ true);
1360         }
1361       }
1362     } else if (kIsDebugBuild) {
1363       // Sanity check that the profiling infos do not have a dangling entry point.
1364       for (ProfilingInfo* info : profiling_infos_) {
1365         DCHECK(info->GetSavedEntryPoint() == nullptr);
1366       }
1367     }
1368 
1369     // Mark compiled code that are entrypoints of ArtMethods. Compiled code that is not
1370     // an entry point is either:
1371     // - an osr compiled code, that will be removed if not in a thread call stack.
1372     // - discarded compiled code, that will be removed if not in a thread call stack.
1373     for (const auto& entry : jni_stubs_map_) {
1374       const JniStubData& data = entry.second;
1375       const void* code_ptr = data.GetCode();
1376       const OatQuickMethodHeader* method_header = OatQuickMethodHeader::FromCodePointer(code_ptr);
1377       for (ArtMethod* method : data.GetMethods()) {
1378         if (method_header->GetEntryPoint() == method->GetEntryPointFromQuickCompiledCode()) {
1379           GetLiveBitmap()->AtomicTestAndSet(FromCodeToAllocation(code_ptr));
1380           break;
1381         }
1382       }
1383     }
1384     for (const auto& it : method_code_map_) {
1385       ArtMethod* method = it.second;
1386       const void* code_ptr = it.first;
1387       const OatQuickMethodHeader* method_header = OatQuickMethodHeader::FromCodePointer(code_ptr);
1388       if (method_header->GetEntryPoint() == method->GetEntryPointFromQuickCompiledCode()) {
1389         GetLiveBitmap()->AtomicTestAndSet(FromCodeToAllocation(code_ptr));
1390       }
1391     }
1392 
1393     // Empty osr method map, as osr compiled code will be deleted (except the ones
1394     // on thread stacks).
1395     osr_code_map_.clear();
1396   }
1397 
1398   // Run a checkpoint on all threads to mark the JIT compiled code they are running.
1399   MarkCompiledCodeOnThreadStacks(self);
1400 
1401   // At this point, mutator threads are still running, and entrypoints of methods can
1402   // change. We do know they cannot change to a code cache entry that is not marked,
1403   // therefore we can safely remove those entries.
1404   RemoveUnmarkedCode(self);
1405 
1406   if (collect_profiling_info) {
1407     MutexLock mu(self, lock_);
1408     // Free all profiling infos of methods not compiled nor being compiled.
1409     auto profiling_kept_end = std::remove_if(profiling_infos_.begin(), profiling_infos_.end(),
1410       [this] (ProfilingInfo* info) NO_THREAD_SAFETY_ANALYSIS {
1411         const void* ptr = info->GetMethod()->GetEntryPointFromQuickCompiledCode();
1412         // We have previously cleared the ProfilingInfo pointer in the ArtMethod in the hope
1413         // that the compiled code would not get revived. As mutator threads run concurrently,
1414         // they may have revived the compiled code, and now we are in the situation where
1415         // a method has compiled code but no ProfilingInfo.
1416         // We make sure compiled methods have a ProfilingInfo object. It is needed for
1417         // code cache collection.
1418         if (ContainsPc(ptr) &&
1419             info->GetMethod()->GetProfilingInfo(kRuntimePointerSize) == nullptr) {
1420           info->GetMethod()->SetProfilingInfo(info);
1421         } else if (info->GetMethod()->GetProfilingInfo(kRuntimePointerSize) != info) {
1422           // No need for this ProfilingInfo object anymore.
1423           FreeData(reinterpret_cast<uint8_t*>(info));
1424           return true;
1425         }
1426         return false;
1427       });
1428     profiling_infos_.erase(profiling_kept_end, profiling_infos_.end());
1429     DCHECK(CheckLiveCompiledCodeHasProfilingInfo());
1430   }
1431 }
1432 
CheckLiveCompiledCodeHasProfilingInfo()1433 bool JitCodeCache::CheckLiveCompiledCodeHasProfilingInfo() {
1434   ScopedTrace trace(__FUNCTION__);
1435   // Check that methods we have compiled do have a ProfilingInfo object. We would
1436   // have memory leaks of compiled code otherwise.
1437   for (const auto& it : method_code_map_) {
1438     ArtMethod* method = it.second;
1439     if (method->GetProfilingInfo(kRuntimePointerSize) == nullptr) {
1440       const void* code_ptr = it.first;
1441       const OatQuickMethodHeader* method_header = OatQuickMethodHeader::FromCodePointer(code_ptr);
1442       if (method_header->GetEntryPoint() == method->GetEntryPointFromQuickCompiledCode()) {
1443         // If the code is not dead, then we have a problem. Note that this can even
1444         // happen just after a collection, as mutator threads are running in parallel
1445         // and could deoptimize an existing compiled code.
1446         return false;
1447       }
1448     }
1449   }
1450   return true;
1451 }
1452 
LookupMethodHeader(uintptr_t pc,ArtMethod * method)1453 OatQuickMethodHeader* JitCodeCache::LookupMethodHeader(uintptr_t pc, ArtMethod* method) {
1454   static_assert(kRuntimeISA != InstructionSet::kThumb2, "kThumb2 cannot be a runtime ISA");
1455   if (kRuntimeISA == InstructionSet::kArm) {
1456     // On Thumb-2, the pc is offset by one.
1457     --pc;
1458   }
1459   if (!ContainsPc(reinterpret_cast<const void*>(pc))) {
1460     return nullptr;
1461   }
1462 
1463   if (!kIsDebugBuild) {
1464     // Called with null `method` only from MarkCodeClosure::Run() in debug build.
1465     CHECK(method != nullptr);
1466   }
1467 
1468   MutexLock mu(Thread::Current(), lock_);
1469   OatQuickMethodHeader* method_header = nullptr;
1470   ArtMethod* found_method = nullptr;  // Only for DCHECK(), not for JNI stubs.
1471   if (method != nullptr && UNLIKELY(method->IsNative())) {
1472     auto it = jni_stubs_map_.find(JniStubKey(method));
1473     if (it == jni_stubs_map_.end() || !ContainsElement(it->second.GetMethods(), method)) {
1474       return nullptr;
1475     }
1476     const void* code_ptr = it->second.GetCode();
1477     method_header = OatQuickMethodHeader::FromCodePointer(code_ptr);
1478     if (!method_header->Contains(pc)) {
1479       return nullptr;
1480     }
1481   } else {
1482     auto it = method_code_map_.lower_bound(reinterpret_cast<const void*>(pc));
1483     if (it != method_code_map_.begin()) {
1484       --it;
1485       const void* code_ptr = it->first;
1486       if (OatQuickMethodHeader::FromCodePointer(code_ptr)->Contains(pc)) {
1487         method_header = OatQuickMethodHeader::FromCodePointer(code_ptr);
1488         found_method = it->second;
1489       }
1490     }
1491     if (method_header == nullptr && method == nullptr) {
1492       // Scan all compiled JNI stubs as well. This slow search is used only
1493       // for checks in debug build, for release builds the `method` is not null.
1494       for (auto&& entry : jni_stubs_map_) {
1495         const JniStubData& data = entry.second;
1496         if (data.IsCompiled() &&
1497             OatQuickMethodHeader::FromCodePointer(data.GetCode())->Contains(pc)) {
1498           method_header = OatQuickMethodHeader::FromCodePointer(data.GetCode());
1499         }
1500       }
1501     }
1502     if (method_header == nullptr) {
1503       return nullptr;
1504     }
1505   }
1506 
1507   if (kIsDebugBuild && method != nullptr && !method->IsNative()) {
1508     // When we are walking the stack to redefine classes and creating obsolete methods it is
1509     // possible that we might have updated the method_code_map by making this method obsolete in a
1510     // previous frame. Therefore we should just check that the non-obsolete version of this method
1511     // is the one we expect. We change to the non-obsolete versions in the error message since the
1512     // obsolete version of the method might not be fully initialized yet. This situation can only
1513     // occur when we are in the process of allocating and setting up obsolete methods. Otherwise
1514     // method and it->second should be identical. (See openjdkjvmti/ti_redefine.cc for more
1515     // information.)
1516     DCHECK_EQ(found_method->GetNonObsoleteMethod(), method->GetNonObsoleteMethod())
1517         << ArtMethod::PrettyMethod(method->GetNonObsoleteMethod()) << " "
1518         << ArtMethod::PrettyMethod(found_method->GetNonObsoleteMethod()) << " "
1519         << std::hex << pc;
1520   }
1521   return method_header;
1522 }
1523 
LookupOsrMethodHeader(ArtMethod * method)1524 OatQuickMethodHeader* JitCodeCache::LookupOsrMethodHeader(ArtMethod* method) {
1525   MutexLock mu(Thread::Current(), lock_);
1526   auto it = osr_code_map_.find(method);
1527   if (it == osr_code_map_.end()) {
1528     return nullptr;
1529   }
1530   return OatQuickMethodHeader::FromCodePointer(it->second);
1531 }
1532 
AddProfilingInfo(Thread * self,ArtMethod * method,const std::vector<uint32_t> & entries,bool retry_allocation)1533 ProfilingInfo* JitCodeCache::AddProfilingInfo(Thread* self,
1534                                               ArtMethod* method,
1535                                               const std::vector<uint32_t>& entries,
1536                                               bool retry_allocation)
1537     // No thread safety analysis as we are using TryLock/Unlock explicitly.
1538     NO_THREAD_SAFETY_ANALYSIS {
1539   ProfilingInfo* info = nullptr;
1540   if (!retry_allocation) {
1541     // If we are allocating for the interpreter, just try to lock, to avoid
1542     // lock contention with the JIT.
1543     if (lock_.ExclusiveTryLock(self)) {
1544       info = AddProfilingInfoInternal(self, method, entries);
1545       lock_.ExclusiveUnlock(self);
1546     }
1547   } else {
1548     {
1549       MutexLock mu(self, lock_);
1550       info = AddProfilingInfoInternal(self, method, entries);
1551     }
1552 
1553     if (info == nullptr) {
1554       GarbageCollectCache(self);
1555       MutexLock mu(self, lock_);
1556       info = AddProfilingInfoInternal(self, method, entries);
1557     }
1558   }
1559   return info;
1560 }
1561 
AddProfilingInfoInternal(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method,const std::vector<uint32_t> & entries)1562 ProfilingInfo* JitCodeCache::AddProfilingInfoInternal(Thread* self ATTRIBUTE_UNUSED,
1563                                                       ArtMethod* method,
1564                                                       const std::vector<uint32_t>& entries) {
1565   size_t profile_info_size = RoundUp(
1566       sizeof(ProfilingInfo) + sizeof(InlineCache) * entries.size(),
1567       sizeof(void*));
1568 
1569   // Check whether some other thread has concurrently created it.
1570   ProfilingInfo* info = method->GetProfilingInfo(kRuntimePointerSize);
1571   if (info != nullptr) {
1572     return info;
1573   }
1574 
1575   uint8_t* data = AllocateData(profile_info_size);
1576   if (data == nullptr) {
1577     return nullptr;
1578   }
1579   info = new (data) ProfilingInfo(method, entries);
1580 
1581   // Make sure other threads see the data in the profiling info object before the
1582   // store in the ArtMethod's ProfilingInfo pointer.
1583   QuasiAtomic::ThreadFenceRelease();
1584 
1585   method->SetProfilingInfo(info);
1586   profiling_infos_.push_back(info);
1587   histogram_profiling_info_memory_use_.AddValue(profile_info_size);
1588   return info;
1589 }
1590 
1591 // NO_THREAD_SAFETY_ANALYSIS as this is called from mspace code, at which point the lock
1592 // is already held.
MoreCore(const void * mspace,intptr_t increment)1593 void* JitCodeCache::MoreCore(const void* mspace, intptr_t increment) NO_THREAD_SAFETY_ANALYSIS {
1594   if (code_mspace_ == mspace) {
1595     size_t result = code_end_;
1596     code_end_ += increment;
1597     return reinterpret_cast<void*>(result + code_map_->Begin());
1598   } else {
1599     DCHECK_EQ(data_mspace_, mspace);
1600     size_t result = data_end_;
1601     data_end_ += increment;
1602     return reinterpret_cast<void*>(result + data_map_->Begin());
1603   }
1604 }
1605 
GetProfiledMethods(const std::set<std::string> & dex_base_locations,std::vector<ProfileMethodInfo> & methods)1606 void JitCodeCache::GetProfiledMethods(const std::set<std::string>& dex_base_locations,
1607                                       std::vector<ProfileMethodInfo>& methods) {
1608   ScopedTrace trace(__FUNCTION__);
1609   MutexLock mu(Thread::Current(), lock_);
1610   uint16_t jit_compile_threshold = Runtime::Current()->GetJITOptions()->GetCompileThreshold();
1611   for (const ProfilingInfo* info : profiling_infos_) {
1612     ArtMethod* method = info->GetMethod();
1613     const DexFile* dex_file = method->GetDexFile();
1614     const std::string base_location = DexFileLoader::GetBaseLocation(dex_file->GetLocation());
1615     if (!ContainsElement(dex_base_locations, base_location)) {
1616       // Skip dex files which are not profiled.
1617       continue;
1618     }
1619     std::vector<ProfileMethodInfo::ProfileInlineCache> inline_caches;
1620 
1621     // If the method didn't reach the compilation threshold don't save the inline caches.
1622     // They might be incomplete and cause unnecessary deoptimizations.
1623     // If the inline cache is empty the compiler will generate a regular invoke virtual/interface.
1624     if (method->GetCounter() < jit_compile_threshold) {
1625       methods.emplace_back(/*ProfileMethodInfo*/
1626           MethodReference(dex_file, method->GetDexMethodIndex()), inline_caches);
1627       continue;
1628     }
1629 
1630     for (size_t i = 0; i < info->number_of_inline_caches_; ++i) {
1631       std::vector<TypeReference> profile_classes;
1632       const InlineCache& cache = info->cache_[i];
1633       ArtMethod* caller = info->GetMethod();
1634       bool is_missing_types = false;
1635       for (size_t k = 0; k < InlineCache::kIndividualCacheSize; k++) {
1636         mirror::Class* cls = cache.classes_[k].Read();
1637         if (cls == nullptr) {
1638           break;
1639         }
1640 
1641         // Check if the receiver is in the boot class path or if it's in the
1642         // same class loader as the caller. If not, skip it, as there is not
1643         // much we can do during AOT.
1644         if (!cls->IsBootStrapClassLoaded() &&
1645             caller->GetClassLoader() != cls->GetClassLoader()) {
1646           is_missing_types = true;
1647           continue;
1648         }
1649 
1650         const DexFile* class_dex_file = nullptr;
1651         dex::TypeIndex type_index;
1652 
1653         if (cls->GetDexCache() == nullptr) {
1654           DCHECK(cls->IsArrayClass()) << cls->PrettyClass();
1655           // Make a best effort to find the type index in the method's dex file.
1656           // We could search all open dex files but that might turn expensive
1657           // and probably not worth it.
1658           class_dex_file = dex_file;
1659           type_index = cls->FindTypeIndexInOtherDexFile(*dex_file);
1660         } else {
1661           class_dex_file = &(cls->GetDexFile());
1662           type_index = cls->GetDexTypeIndex();
1663         }
1664         if (!type_index.IsValid()) {
1665           // Could be a proxy class or an array for which we couldn't find the type index.
1666           is_missing_types = true;
1667           continue;
1668         }
1669         if (ContainsElement(dex_base_locations,
1670                             DexFileLoader::GetBaseLocation(class_dex_file->GetLocation()))) {
1671           // Only consider classes from the same apk (including multidex).
1672           profile_classes.emplace_back(/*ProfileMethodInfo::ProfileClassReference*/
1673               class_dex_file, type_index);
1674         } else {
1675           is_missing_types = true;
1676         }
1677       }
1678       if (!profile_classes.empty()) {
1679         inline_caches.emplace_back(/*ProfileMethodInfo::ProfileInlineCache*/
1680             cache.dex_pc_, is_missing_types, profile_classes);
1681       }
1682     }
1683     methods.emplace_back(/*ProfileMethodInfo*/
1684         MethodReference(dex_file, method->GetDexMethodIndex()), inline_caches);
1685   }
1686 }
1687 
GetLastUpdateTimeNs() const1688 uint64_t JitCodeCache::GetLastUpdateTimeNs() const {
1689   return last_update_time_ns_.LoadAcquire();
1690 }
1691 
IsOsrCompiled(ArtMethod * method)1692 bool JitCodeCache::IsOsrCompiled(ArtMethod* method) {
1693   MutexLock mu(Thread::Current(), lock_);
1694   return osr_code_map_.find(method) != osr_code_map_.end();
1695 }
1696 
NotifyCompilationOf(ArtMethod * method,Thread * self,bool osr)1697 bool JitCodeCache::NotifyCompilationOf(ArtMethod* method, Thread* self, bool osr) {
1698   if (!osr && ContainsPc(method->GetEntryPointFromQuickCompiledCode())) {
1699     return false;
1700   }
1701 
1702   MutexLock mu(self, lock_);
1703   if (osr && (osr_code_map_.find(method) != osr_code_map_.end())) {
1704     return false;
1705   }
1706 
1707   if (UNLIKELY(method->IsNative())) {
1708     JniStubKey key(method);
1709     auto it = jni_stubs_map_.find(key);
1710     bool new_compilation = false;
1711     if (it == jni_stubs_map_.end()) {
1712       // Create a new entry to mark the stub as being compiled.
1713       it = jni_stubs_map_.Put(key, JniStubData{});
1714       new_compilation = true;
1715     }
1716     JniStubData* data = &it->second;
1717     data->AddMethod(method);
1718     if (data->IsCompiled()) {
1719       OatQuickMethodHeader* method_header = OatQuickMethodHeader::FromCodePointer(data->GetCode());
1720       const void* entrypoint = method_header->GetEntryPoint();
1721       // Update also entrypoints of other methods held by the JniStubData.
1722       // We could simply update the entrypoint of `method` but if the last JIT GC has
1723       // changed these entrypoints to GenericJNI in preparation for a full GC, we may
1724       // as well change them back as this stub shall not be collected anyway and this
1725       // can avoid a few expensive GenericJNI calls.
1726       instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
1727       for (ArtMethod* m : data->GetMethods()) {
1728         // Call the dedicated method instead of the more generic UpdateMethodsCode, because
1729         // `m` might be in the process of being deleted.
1730         instrumentation->UpdateNativeMethodsCodeToJitCode(m, entrypoint);
1731       }
1732       if (collection_in_progress_) {
1733         GetLiveBitmap()->AtomicTestAndSet(FromCodeToAllocation(data->GetCode()));
1734       }
1735     }
1736     return new_compilation;
1737   } else {
1738     ProfilingInfo* info = method->GetProfilingInfo(kRuntimePointerSize);
1739     if (info == nullptr) {
1740       VLOG(jit) << method->PrettyMethod() << " needs a ProfilingInfo to be compiled";
1741       // Because the counter is not atomic, there are some rare cases where we may not hit the
1742       // threshold for creating the ProfilingInfo. Reset the counter now to "correct" this.
1743       ClearMethodCounter(method, /*was_warm*/ false);
1744       return false;
1745     }
1746 
1747     if (info->IsMethodBeingCompiled(osr)) {
1748       return false;
1749     }
1750 
1751     info->SetIsMethodBeingCompiled(true, osr);
1752     return true;
1753   }
1754 }
1755 
NotifyCompilerUse(ArtMethod * method,Thread * self)1756 ProfilingInfo* JitCodeCache::NotifyCompilerUse(ArtMethod* method, Thread* self) {
1757   MutexLock mu(self, lock_);
1758   ProfilingInfo* info = method->GetProfilingInfo(kRuntimePointerSize);
1759   if (info != nullptr) {
1760     if (!info->IncrementInlineUse()) {
1761       // Overflow of inlining uses, just bail.
1762       return nullptr;
1763     }
1764   }
1765   return info;
1766 }
1767 
DoneCompilerUse(ArtMethod * method,Thread * self)1768 void JitCodeCache::DoneCompilerUse(ArtMethod* method, Thread* self) {
1769   MutexLock mu(self, lock_);
1770   ProfilingInfo* info = method->GetProfilingInfo(kRuntimePointerSize);
1771   DCHECK(info != nullptr);
1772   info->DecrementInlineUse();
1773 }
1774 
DoneCompiling(ArtMethod * method,Thread * self,bool osr)1775 void JitCodeCache::DoneCompiling(ArtMethod* method, Thread* self, bool osr) {
1776   DCHECK_EQ(Thread::Current(), self);
1777   MutexLock mu(self, lock_);
1778   if (UNLIKELY(method->IsNative())) {
1779     auto it = jni_stubs_map_.find(JniStubKey(method));
1780     DCHECK(it != jni_stubs_map_.end());
1781     JniStubData* data = &it->second;
1782     DCHECK(ContainsElement(data->GetMethods(), method));
1783     if (UNLIKELY(!data->IsCompiled())) {
1784       // Failed to compile; the JNI compiler never fails, but the cache may be full.
1785       jni_stubs_map_.erase(it);  // Remove the entry added in NotifyCompilationOf().
1786     }  // else CommitCodeInternal() updated entrypoints of all methods in the JniStubData.
1787   } else {
1788     ProfilingInfo* info = method->GetProfilingInfo(kRuntimePointerSize);
1789     DCHECK(info->IsMethodBeingCompiled(osr));
1790     info->SetIsMethodBeingCompiled(false, osr);
1791   }
1792 }
1793 
GetMemorySizeOfCodePointer(const void * ptr)1794 size_t JitCodeCache::GetMemorySizeOfCodePointer(const void* ptr) {
1795   MutexLock mu(Thread::Current(), lock_);
1796   return mspace_usable_size(reinterpret_cast<const void*>(FromCodeToAllocation(ptr)));
1797 }
1798 
InvalidateCompiledCodeFor(ArtMethod * method,const OatQuickMethodHeader * header)1799 void JitCodeCache::InvalidateCompiledCodeFor(ArtMethod* method,
1800                                              const OatQuickMethodHeader* header) {
1801   DCHECK(!method->IsNative());
1802   ProfilingInfo* profiling_info = method->GetProfilingInfo(kRuntimePointerSize);
1803   if ((profiling_info != nullptr) &&
1804       (profiling_info->GetSavedEntryPoint() == header->GetEntryPoint())) {
1805     // Prevent future uses of the compiled code.
1806     profiling_info->SetSavedEntryPoint(nullptr);
1807   }
1808 
1809   if (method->GetEntryPointFromQuickCompiledCode() == header->GetEntryPoint()) {
1810     // The entrypoint is the one to invalidate, so we just update it to the interpreter entry point
1811     // and clear the counter to get the method Jitted again.
1812     Runtime::Current()->GetInstrumentation()->UpdateMethodsCode(
1813         method, GetQuickToInterpreterBridge());
1814     ClearMethodCounter(method, /*was_warm*/ profiling_info != nullptr);
1815   } else {
1816     MutexLock mu(Thread::Current(), lock_);
1817     auto it = osr_code_map_.find(method);
1818     if (it != osr_code_map_.end() && OatQuickMethodHeader::FromCodePointer(it->second) == header) {
1819       // Remove the OSR method, to avoid using it again.
1820       osr_code_map_.erase(it);
1821     }
1822   }
1823 }
1824 
AllocateCode(size_t code_size)1825 uint8_t* JitCodeCache::AllocateCode(size_t code_size) {
1826   size_t alignment = GetInstructionSetAlignment(kRuntimeISA);
1827   uint8_t* result = reinterpret_cast<uint8_t*>(
1828       mspace_memalign(code_mspace_, alignment, code_size));
1829   size_t header_size = RoundUp(sizeof(OatQuickMethodHeader), alignment);
1830   // Ensure the header ends up at expected instruction alignment.
1831   DCHECK_ALIGNED_PARAM(reinterpret_cast<uintptr_t>(result + header_size), alignment);
1832   used_memory_for_code_ += mspace_usable_size(result);
1833   return result;
1834 }
1835 
FreeCode(uint8_t * code)1836 void JitCodeCache::FreeCode(uint8_t* code) {
1837   used_memory_for_code_ -= mspace_usable_size(code);
1838   mspace_free(code_mspace_, code);
1839 }
1840 
AllocateData(size_t data_size)1841 uint8_t* JitCodeCache::AllocateData(size_t data_size) {
1842   void* result = mspace_malloc(data_mspace_, data_size);
1843   used_memory_for_data_ += mspace_usable_size(result);
1844   return reinterpret_cast<uint8_t*>(result);
1845 }
1846 
FreeData(uint8_t * data)1847 void JitCodeCache::FreeData(uint8_t* data) {
1848   used_memory_for_data_ -= mspace_usable_size(data);
1849   mspace_free(data_mspace_, data);
1850 }
1851 
Dump(std::ostream & os)1852 void JitCodeCache::Dump(std::ostream& os) {
1853   MutexLock mu(Thread::Current(), lock_);
1854   MutexLock mu2(Thread::Current(), *Locks::native_debug_interface_lock_);
1855   os << "Current JIT code cache size: " << PrettySize(used_memory_for_code_) << "\n"
1856      << "Current JIT data cache size: " << PrettySize(used_memory_for_data_) << "\n"
1857      << "Current JIT mini-debug-info size: " << PrettySize(GetJitNativeDebugInfoMemUsage()) << "\n"
1858      << "Current JIT capacity: " << PrettySize(current_capacity_) << "\n"
1859      << "Current number of JIT JNI stub entries: " << jni_stubs_map_.size() << "\n"
1860      << "Current number of JIT code cache entries: " << method_code_map_.size() << "\n"
1861      << "Total number of JIT compilations: " << number_of_compilations_ << "\n"
1862      << "Total number of JIT compilations for on stack replacement: "
1863         << number_of_osr_compilations_ << "\n"
1864      << "Total number of JIT code cache collections: " << number_of_collections_ << std::endl;
1865   histogram_stack_map_memory_use_.PrintMemoryUse(os);
1866   histogram_code_memory_use_.PrintMemoryUse(os);
1867   histogram_profiling_info_memory_use_.PrintMemoryUse(os);
1868 }
1869 
1870 }  // namespace jit
1871 }  // namespace art
1872