1 /** 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef PANDA_RUNTIME_COMPILER_QUEUE_AGED_COUNTER_PRIORITY_H_ 16 #define PANDA_RUNTIME_COMPILER_QUEUE_AGED_COUNTER_PRIORITY_H_ 17 18 #include "runtime/compiler_queue_counter_priority.h" 19 #include "runtime/include/mem/panda_containers.h" 20 #include "runtime/include/method-inl.h" 21 22 namespace panda { 23 24 /** The aged counter priority queue works mostly as counter priority queue (see description), 25 * but it sorts the methods by its aged hotness counters. 26 * If the aged counter is less then some death value, it is considered as expired and is removed. 27 * Epoch duration and death counter is configured. 28 * This queue is thread unsafe (should be used under lock). 29 */ 30 class CompilerPriorityAgedCounterQueue : public CompilerPriorityCounterQueue { 31 public: CompilerPriorityAgedCounterQueue(mem::InternalAllocatorPtr allocator,uint64_t max_length,uint64_t death_counter_value,uint64_t epoch_duration)32 explicit CompilerPriorityAgedCounterQueue(mem::InternalAllocatorPtr allocator, uint64_t max_length, 33 uint64_t death_counter_value, uint64_t epoch_duration) 34 : CompilerPriorityCounterQueue(allocator, max_length, 0 /* unused */) 35 { 36 death_counter_value_ = death_counter_value; 37 epoch_duration_ = epoch_duration; 38 if (epoch_duration_ <= 0) { 39 LOG(FATAL, COMPILATION_QUEUE) << "Incorrect value of epoch duration: " << epoch_duration_; 40 } 41 SetQueueName("priority aged counter compilation queue"); 42 } 43 44 protected: UpdateCounterAndCheck(CompilationQueueElement * element)45 bool UpdateCounterAndCheck(CompilationQueueElement *element) override 46 { 47 // Rounding 48 uint64_t current_time = time::GetCurrentTimeInMillis(); 49 ASSERT(current_time >= element->GetTimestamp()); 50 uint64_t duration = current_time - element->GetTimestamp(); 51 uint64_t shift = duration / epoch_duration_; 52 uint64_t aged_counter = 0; 53 constexpr int MAX_SHIFT = 16; 54 if (shift < MAX_SHIFT) { 55 // hotness_counter is uint16_t and shifts more that 16 are useless 56 // Moreover, shifts for 32 and more leads to strange failures 57 // For greater values just use preset 0 58 aged_counter = element->GetContext().GetMethod()->GetHotnessCounter() >> shift; 59 } 60 element->UpdateCounter(aged_counter); 61 return (aged_counter < death_counter_value_); 62 } 63 64 private: 65 uint64_t death_counter_value_; 66 uint64_t epoch_duration_; 67 }; 68 69 } // namespace panda 70 71 #endif // PANDA_RUNTIME_COMPILER_QUEUE_AGED_COUNTER_PRIORITY_H_ 72