1 /*
2 * Copyright (c) 2023-2024 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
16 #include "runtime/compiler.h"
17 #include "runtime/compiler_thread_pool_worker.h"
18 #include "runtime/compiler_queue_simple.h"
19 #include "runtime/compiler_queue_aged_counter_priority.h"
20 #include "compiler/inplace_task_runner.h"
21
22 namespace ark {
23
CompilerThreadPoolWorker(mem::InternalAllocatorPtr internalAllocator,Compiler * compiler,bool & noAsyncJit,const RuntimeOptions & options)24 CompilerThreadPoolWorker::CompilerThreadPoolWorker(mem::InternalAllocatorPtr internalAllocator, Compiler *compiler,
25 bool &noAsyncJit, const RuntimeOptions &options)
26 : CompilerWorker(internalAllocator, compiler)
27 {
28 queue_ = CreateJITTaskQueue(noAsyncJit ? "simple" : options.GetCompilerQueueType(),
29 options.GetCompilerQueueMaxLength(), options.GetCompilerTaskLifeSpan(),
30 options.GetCompilerDeathCounterValue(), options.GetCompilerEpochDuration());
31 if (queue_ == nullptr) {
32 // Because of problems (no memory) in allocator
33 LOG(ERROR, COMPILER) << "Cannot create a compiler queue";
34 noAsyncJit = true;
35 }
36 }
37
~CompilerThreadPoolWorker()38 CompilerThreadPoolWorker::~CompilerThreadPoolWorker()
39 {
40 if (queue_ != nullptr) {
41 queue_->Finalize();
42 internalAllocator_->Delete(queue_);
43 }
44 }
45
CreateJITTaskQueue(const std::string & queueType,uint64_t maxLength,uint64_t taskLife,uint64_t deathCounter,uint64_t epochDuration)46 CompilerQueueInterface *CompilerThreadPoolWorker::CreateJITTaskQueue(const std::string &queueType, uint64_t maxLength,
47 uint64_t taskLife, uint64_t deathCounter,
48 uint64_t epochDuration)
49 {
50 LOG(DEBUG, COMPILER) << "Creating " << queueType << " task queue";
51 if (queueType == "simple") {
52 return internalAllocator_->New<CompilerQueueSimple>(internalAllocator_);
53 }
54 if (queueType == "counter-priority") {
55 return internalAllocator_->New<CompilerPriorityCounterQueue>(internalAllocator_, maxLength, taskLife);
56 }
57 if (queueType == "aged-counter-priority") {
58 return internalAllocator_->New<CompilerPriorityAgedCounterQueue>(internalAllocator_, taskLife, deathCounter,
59 epochDuration);
60 }
61 LOG(FATAL, COMPILER) << "Unknown queue type";
62 return nullptr;
63 }
64
Process(CompilerTask && task)65 bool CompilerProcessor::Process(CompilerTask &&task)
66 {
67 InPlaceCompileMethod(std::move(task));
68 return true;
69 }
70
InPlaceCompileMethod(CompilerTask && ctx)71 void CompilerProcessor::InPlaceCompileMethod(CompilerTask &&ctx)
72 {
73 compiler::InPlaceCompilerTaskRunner taskRunner;
74 auto &compilerCtx = taskRunner.GetContext();
75 compilerCtx.SetMethod(ctx.GetMethod());
76 compilerCtx.SetOsr(ctx.IsOsr());
77 compilerCtx.SetVM(ctx.GetVM());
78
79 // Set current thread to have access to vm during compilation
80 Thread compilerThread(ctx.GetVM(), Thread::ThreadType::THREAD_TYPE_COMPILER);
81 ScopedCurrentThread sct(&compilerThread);
82
83 if (compilerCtx.GetMethod()->AtomicSetCompilationStatus(Method::WAITING, Method::COMPILATION)) {
84 compiler_->CompileMethodLocked<compiler::INPLACE_MODE>(std::move(taskRunner));
85 }
86 }
87
88 } // namespace ark
89