1 /*
2 * Copyright (c) 2023 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 "ecmascript/jit/jit_task.h"
17 #include "ecmascript/object_factory.h"
18 #include "ecmascript/global_env.h"
19 #include "ecmascript/compiler/aot_file/func_entry_des.h"
20
21 namespace panda::ecmascript {
Optimize()22 void JitTask::Optimize()
23 {
24 bool res = jit_->JitCompile(compiler_, this);
25 if (!res) {
26 SetCompileFailed();
27 }
28 }
29
Finalize()30 void JitTask::Finalize()
31 {
32 if (!IsCompileSuccess()) {
33 return;
34 }
35
36 bool res = jit_->JitFinalize(compiler_, this);
37 if (!res) {
38 SetCompileFailed();
39 }
40 }
41
InstallCode()42 void JitTask::InstallCode()
43 {
44 if (!IsCompileSuccess()) {
45 return;
46 }
47 JSHandle<Method> methodHandle(vm_->GetJSThread(), Method::Cast(jsFunction_->GetMethod().GetTaggedObject()));
48
49 size_t funcEntryDesSizeAlign = AlignUp(codeDesc_.funcEntryDesSize, MachineCode::DATA_ALIGN);
50
51 size_t rodataSizeBeforeTextAlign = AlignUp(codeDesc_.rodataSizeBeforeText, MachineCode::TEXT_ALIGN);
52 size_t codeSizeAlign = AlignUp(codeDesc_.codeSize, MachineCode::DATA_ALIGN);
53 size_t rodataSizeAfterTextAlign = AlignUp(codeDesc_.rodataSizeAfterText, MachineCode::DATA_ALIGN);
54
55 size_t stackMapSizeAlign = AlignUp(codeDesc_.stackMapSize, MachineCode::DATA_ALIGN);
56
57 size_t size = funcEntryDesSizeAlign + rodataSizeBeforeTextAlign + codeSizeAlign + rodataSizeAfterTextAlign +
58 stackMapSizeAlign;
59
60 JSHandle<MachineCode> machineCodeObj = vm_->GetFactory()->NewMachineCodeObject(size, &codeDesc_, methodHandle);
61 // oom?
62 uintptr_t codeAddr = machineCodeObj->GetFuncAddr();
63 FuncEntryDes *funcEntryDes = reinterpret_cast<FuncEntryDes*>(machineCodeObj->GetFuncEntryDes());
64 methodHandle->SetCompiledFuncEntry(codeAddr, funcEntryDes->isFastCall_);
65 methodHandle->SetDeoptThreshold(vm_->GetJSOptions().GetDeoptThreshold());
66 methodHandle->SetMachineCode(vm_->GetJSThread(), machineCodeObj);
67
68 LOG_JIT(DEBUG) <<"Install machine code:" << GetMethodInfo();
69 }
70
PersistentHandle()71 void JitTask::PersistentHandle()
72 {
73 // transfer to global ref
74 GlobalHandleCollection globalHandleCollection(vm_->GetJSThread());
75 JSHandle<JSFunction> persistentHandle =
76 globalHandleCollection.NewHandle<JSFunction>(jsFunction_.GetTaggedType());
77 SetJsFunction(persistentHandle);
78 }
79
ReleasePersistentHandle()80 void JitTask::ReleasePersistentHandle()
81 {
82 GlobalHandleCollection globalHandleCollection(vm_->GetJSThread());
83 globalHandleCollection.Dispose(jsFunction_);
84 }
85
~JitTask()86 JitTask::~JitTask()
87 {
88 ReleasePersistentHandle();
89 jit_->DeleteJitCompile(compiler_);
90 }
91
Run(uint32_t threadIndex)92 bool JitTask::AsyncTask::Run([[maybe_unused]] uint32_t threadIndex)
93 {
94 CString info = jitTask_->GetMethodInfo() + ", in task pool, id:" + ToCString(threadIndex) + ", time:";
95 Jit::Scope scope(info);
96
97 jitTask_->Finalize();
98
99 // info main thread compile complete
100 jitTask_->RequestInstallCode();
101
102 // as now litecg has global value, so only compile one task at a time
103 jitTask_->GetJit()->RemoveAsyncCompileTask(jitTask_);
104 JitTask *jitTask = jitTask_->GetJit()->GetAsyncCompileTask();
105 if (jitTask != nullptr) {
106 Taskpool::GetCurrentTaskpool()->PostTask(
107 std::make_unique<JitTask::AsyncTask>(jitTask, jitTask->GetVM()->GetJSThread()->GetThreadId()));
108 }
109 return true;
110 }
111 } // namespace panda::ecmascript
112