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 "ecmascript/jit/jit.h" 17#include "ecmascript/jit/jit_task.h" 18#include "ecmascript/dfx/vmstat/jit_warmup_profiler.h" 19#include "ecmascript/ohos/jit_tools.h" 20 21namespace panda::ecmascript { 22void (*Jit::initJitCompiler_)(JSRuntimeOptions options) = nullptr; 23bool(*Jit::jitCompile_)(void*, JitTask*) = nullptr; 24bool(*Jit::jitFinalize_)(void*, JitTask*) = nullptr; 25void*(*Jit::createJitCompilerTask_)(JitTask*) = nullptr; 26void(*Jit::deleteJitCompile_)(void*) = nullptr; 27void *Jit::libHandle_ = nullptr; 28 29Jit *Jit::GetInstance() 30{ 31 static Jit instance_; 32 return &instance_; 33} 34 35void Jit::SetJitEnablePostFork(EcmaVM *vm, const std::string &bundleName) 36{ 37 JSRuntimeOptions &options = vm->GetJSOptions(); 38 bool jitEnable = ohos::JitTools::GetJitEscapeDisable() || !AotCrashInfo::IsJitEscape(); 39 jitEnable &= ohos::EnableAotJitListHelper::GetInstance()->IsEnableJit(bundleName); 40 jitEnable &= !vm->GetJSOptions().GetAOTHasException(); 41 if (jitEnable) { 42 bool isEnableFastJit = options.IsEnableJIT() && options.GetEnableAsmInterpreter(); 43 bool isEnableBaselineJit = options.IsEnableBaselineJIT() && options.GetEnableAsmInterpreter(); 44 45 options.SetEnableJitFrame(ohos::JitTools::GetJitFrameEnable()); 46 options.SetEnableAPPJIT(true); 47 // for app threshold 48 uint32_t defaultSize = 3000; 49 uint32_t threshold = ohos::JitTools::GetJitHotnessThreshold(defaultSize); 50 options.SetJitHotnessThreshold(threshold); 51 bundleName_ = bundleName; 52 isEnableAppPGO_ = pgo::PGOProfilerManager::GetInstance()->IsEnable(); 53 54 SetEnableOrDisable(options, isEnableFastJit, isEnableBaselineJit); 55 if (fastJitEnable_ || baselineJitEnable_) { 56 ConfigJit(vm); 57 } 58 } 59} 60 61void Jit::SwitchProfileStubs(EcmaVM *vm) 62{ 63 JSThread *thread = vm->GetAssociatedJSThread(); 64 JSRuntimeOptions &options = vm->GetJSOptions(); 65 std::shared_ptr<PGOProfiler> pgoProfiler = vm->GetPGOProfiler(); 66 if (!options.IsEnableJITPGO() || pgoProfiler == nullptr || (isApp_ && !isEnableAppPGO_)) { 67 thread->SwitchJitProfileStubs(false); 68 options.SetEnableJITPGO(false); 69 } else { 70 // if not enable aot pgo 71 if (!pgo::PGOProfilerManager::GetInstance()->IsEnable()) { 72 // disable dump 73 options.SetEnableProfileDump(false); 74 SetProfileNeedDump(false); 75 // enable profiler 76 options.SetEnablePGOProfiler(true); 77 pgoProfiler->Reset(true); 78 // switch pgo stub 79 thread->SwitchJitProfileStubs(true); 80 } 81 pgoProfiler->InitJITProfiler(); 82 } 83} 84 85void Jit::ConfigOptions(EcmaVM *vm) const 86{ 87 JSRuntimeOptions &options = vm->GetJSOptions(); 88 89 options.SetEnableAPPJIT(isApp_); 90 options.SetEnableProfileDump(isProfileNeedDump_); 91 92 bool jitEnableLitecg = ohos::JitTools::IsJitEnableLitecg(options.IsCompilerEnableLiteCG()); 93 options.SetCompilerEnableLiteCG(jitEnableLitecg); 94 95 uint8_t jitCallThreshold = ohos::JitTools::GetJitCallThreshold(options.GetJitCallThreshold()); 96 options.SetJitCallThreshold(jitCallThreshold); 97 98 uint32_t jitHotnessThreshold = GetHotnessThreshold(); 99 options.SetJitHotnessThreshold(jitHotnessThreshold); 100 101 bool jitDisableCodeSign = ohos::JitTools::GetCodeSignDisable(options.GetDisableCodeSign()); 102 options.SetDisableCodeSign(jitDisableCodeSign); 103 104 bool jitEnableJitFort = ohos::JitTools::GetEnableJitFort(options.GetEnableJitFort()); 105 options.SetEnableJitFort(jitEnableJitFort); 106 107 bool jitEnableAsyncCopyToFort = ohos::JitTools::GetEnableAsyncCopyToFort(options.GetEnableAsyncCopyToFort()); 108 options.SetEnableAsyncCopyToFort(jitEnableAsyncCopyToFort); 109 110 vm->SetEnableJitLogSkip(ohos::JitTools::GetSkipJitLogEnable()); 111 112 LOG_JIT(INFO) << "enable jit bundle:" << bundleName_ << 113 ", litecg:" << jitEnableLitecg << 114 ", call threshold:" << static_cast<int>(jitCallThreshold) << 115 ", hotness threshold:" << jitHotnessThreshold << 116 ", disable codesigner:" << jitDisableCodeSign; 117} 118 119void Jit::ConfigJit(EcmaVM *vm) 120{ 121 SwitchProfileStubs(vm); 122 ConfigOptions(vm); 123 ConfigJitFortOptions(vm); 124} 125 126void Jit::ConfigJitFortOptions(EcmaVM *vm) 127{ 128 SetDisableCodeSign(vm->GetJSOptions().GetDisableCodeSign()); 129 SetEnableJitFort(vm->GetJSOptions().GetEnableJitFort()); 130 SetEnableAsyncCopyToFort(vm->GetJSOptions().GetEnableAsyncCopyToFort()); 131} 132 133void Jit::SetEnableOrDisable(const JSRuntimeOptions &options, bool isEnableFastJit, bool isEnableBaselineJit) 134{ 135 LockHolder holder(setEnableLock_); 136 137 bool needInitialize = false; 138 if (!isEnableFastJit) { 139 fastJitEnable_ = false; 140 } else { 141 needInitialize = true; 142 } 143 if (!isEnableBaselineJit) { 144 baselineJitEnable_ = false; 145 } else { 146 needInitialize = true; 147 } 148 if (!needInitialize) { 149 return; 150 } 151 if (!initialized_) { 152 Initialize(); 153 } 154 if (initialized_) { 155 bool jitEnable = false; 156 if (isEnableFastJit && !fastJitEnable_) { 157 fastJitEnable_ = true; 158 jitEnable = true; 159 } 160 if (isEnableBaselineJit && !baselineJitEnable_) { 161 baselineJitEnable_ = true; 162 jitEnable = true; 163 } 164 if (jitEnable) { 165 jitDfx_ = JitDfx::GetInstance(); 166 jitDfx_->Init(options, bundleName_); 167 168 isApp_ = options.IsEnableAPPJIT(); 169 hotnessThreshold_ = options.GetJitHotnessThreshold(); 170 initJitCompiler_(options); 171 bool enableCodeSign = !ohos::JitTools::GetCodeSignDisable(options.GetDisableCodeSign()); 172 bool shouldCompileMain = 173 options.IsEnableForceJitCompileMain() || options.IsEnableForceBaselineCompileMain(); 174 if (enableCodeSign && shouldCompileMain) { 175 JitFort::InitJitFortResource(); 176 } 177 JitTaskpool::GetCurrentTaskpool()->Initialize(enableCodeSign && !shouldCompileMain); 178 } 179 } 180} 181 182void Jit::Destroy() 183{ 184 if (!initialized_) { 185 return; 186 } 187 188 LockHolder holder(setEnableLock_); 189 190 JitTaskpool::GetCurrentTaskpool()->Destroy(); 191 initialized_ = false; 192 fastJitEnable_ = false; 193 baselineJitEnable_ = false; 194 if (libHandle_ != nullptr) { 195 CloseLib(libHandle_); 196 libHandle_ = nullptr; 197 } 198} 199 200bool Jit::IsEnableFastJit() const 201{ 202 return fastJitEnable_; 203} 204 205bool Jit::IsEnableBaselineJit() const 206{ 207 return baselineJitEnable_; 208} 209 210bool Jit::IsEnableJitFort() const 211{ 212 return isEnableJitFort_; 213} 214 215void Jit::SetEnableJitFort(bool isEnableJitFort) 216{ 217 isEnableJitFort_ = isEnableJitFort; 218} 219 220bool Jit::IsDisableCodeSign() const 221{ 222 return isDisableCodeSign_; 223} 224 225void Jit::SetDisableCodeSign(bool isDisableCodeSign) 226{ 227 isDisableCodeSign_ = isDisableCodeSign; 228} 229 230bool Jit::IsEnableAsyncCopyToFort() const 231{ 232 return isEnableAsyncCopyToFort_; 233} 234 235void Jit::SetEnableAsyncCopyToFort(bool isEnableAsyncCopyToFort) 236{ 237 isEnableAsyncCopyToFort_ = isEnableAsyncCopyToFort; 238} 239 240void Jit::Initialize() 241{ 242 static const std::string CREATEJITCOMPILETASK = "CreateJitCompilerTask"; 243 static const std::string JITCOMPILEINIT = "InitJitCompiler"; 244 static const std::string JITCOMPILE = "JitCompile"; 245 static const std::string JITFINALIZE = "JitFinalize"; 246 static const std::string DELETEJITCOMPILE = "DeleteJitCompile"; 247 static const std::string LIBARK_JSOPTIMIZER = "libark_jsoptimizer.so"; 248 249 libHandle_ = LoadLib(LIBARK_JSOPTIMIZER); 250 if (libHandle_ == nullptr) { 251 char *error = LoadLibError(); 252 LOG_JIT(ERROR) << "jit dlopen libark_jsoptimizer.so failed, as:" << 253 ((error == nullptr) ? "unknown error" : error); 254 return; 255 } 256 257 initJitCompiler_ = reinterpret_cast<void(*)(JSRuntimeOptions)>(FindSymbol(libHandle_, JITCOMPILEINIT.c_str())); 258 if (initJitCompiler_ == nullptr) { 259 LOG_JIT(ERROR) << "jit can't find symbol initJitCompiler"; 260 return; 261 } 262 jitCompile_ = reinterpret_cast<bool(*)(void*, JitTask*)>(FindSymbol(libHandle_, JITCOMPILE.c_str())); 263 if (jitCompile_ == nullptr) { 264 LOG_JIT(ERROR) << "jit can't find symbol jitCompile"; 265 return; 266 } 267 268 jitFinalize_ = reinterpret_cast<bool(*)(void*, JitTask*)>(FindSymbol(libHandle_, JITFINALIZE.c_str())); 269 if (jitFinalize_ == nullptr) { 270 LOG_JIT(ERROR) << "jit can't find symbol jitFinalize"; 271 return; 272 } 273 274 createJitCompilerTask_ = reinterpret_cast<void*(*)(JitTask*)>(FindSymbol(libHandle_, 275 CREATEJITCOMPILETASK.c_str())); 276 if (createJitCompilerTask_ == nullptr) { 277 LOG_JIT(ERROR) << "jit can't find symbol createJitCompilertask"; 278 return; 279 } 280 281 deleteJitCompile_ = reinterpret_cast<void(*)(void*)>(FindSymbol(libHandle_, DELETEJITCOMPILE.c_str())); 282 if (deleteJitCompile_ == nullptr) { 283 LOG_JIT(ERROR) << "jit can't find symbol deleteJitCompile"; 284 return; 285 } 286 initialized_= true; 287 return; 288} 289 290Jit::~Jit() 291{ 292} 293 294bool Jit::SupportJIT(JSHandle<JSFunction> &jsFunction, [[maybe_unused]] EcmaVM *vm, CompilerTier tier) const 295{ 296 Method *method = Method::Cast(jsFunction->GetMethod().GetTaggedObject()); 297 if (jsFunction.GetTaggedValue().IsJSSharedFunction()) { 298 LOG_JIT(DEBUG) << "method does not support compile shared function:" << 299 method->GetRecordNameStr() + "." + method->GetMethodName(); 300 return false; 301 } 302 303 FunctionKind kind = method->GetFunctionKind(); 304 switch (kind) { 305 case FunctionKind::NORMAL_FUNCTION: 306 case FunctionKind::GETTER_FUNCTION: 307 case FunctionKind::SETTER_FUNCTION: 308 case FunctionKind::ARROW_FUNCTION: 309 case FunctionKind::BASE_CONSTRUCTOR: 310 case FunctionKind::CLASS_CONSTRUCTOR: 311 case FunctionKind::DERIVED_CONSTRUCTOR: 312 case FunctionKind::NONE_FUNCTION: 313 return true; 314 default: 315 break; 316 } 317 std::stringstream msgStr; 318 msgStr << "method does not support jit:" << method->GetRecordNameStr() + "." + method->GetMethodName() << 319 ", kind:" << static_cast<int>(kind); 320 if (tier == CompilerTier::BASELINE) { 321 LOG_BASELINEJIT(DEBUG) << msgStr.str(); 322 } else { 323 LOG_JIT(DEBUG) << msgStr.str(); 324 } 325 return false; 326} 327 328void Jit::DeleteJitCompile(void *compiler) 329{ 330 deleteJitCompile_(compiler); 331} 332 333void Jit::CountInterpExecFuncs(JSHandle<JSFunction> &jsFunction) 334{ 335 Method *method = Method::Cast(jsFunction->GetMethod().GetTaggedObject()); 336 auto jSPandaFile = method->GetJSPandaFile(); 337 ASSERT(jSPandaFile != nullptr); 338 CString fileDesc = jSPandaFile->GetJSPandaFileDesc(); 339 CString methodInfo = fileDesc + ":" + method->GetRecordNameStr() + "." + CString(method->GetMethodName()); 340 auto &profMap = JitWarmupProfiler::GetInstance()->profMap_; 341 if (profMap.find(methodInfo) == profMap.end()) { 342 profMap.insert({methodInfo, false}); 343 } 344} 345 346void Jit::Compile(EcmaVM *vm, JSHandle<JSFunction> &jsFunction, CompilerTier tier, 347 int32_t offset, JitCompileMode mode) 348{ 349 auto jit = Jit::GetInstance(); 350 if ((!jit->IsEnableBaselineJit() && tier == CompilerTier::BASELINE) || 351 (!jit->IsEnableFastJit() && tier == CompilerTier::FAST)) { 352 return; 353 } 354 355 if (!vm->IsEnableOsr() && offset != MachineCode::INVALID_OSR_OFFSET) { 356 return; 357 } 358 359 Method *method = Method::Cast(jsFunction->GetMethod().GetTaggedObject()); 360 auto jSPandaFile = method->GetJSPandaFile(); 361 ASSERT(jSPandaFile != nullptr); 362 CString fileDesc = jSPandaFile->GetJSPandaFileDesc(); 363 CString methodName = fileDesc + ":" + method->GetRecordNameStr() + "." + CString(method->GetMethodName()); 364 uint32_t codeSize = method->GetCodeSize(); 365 CString methodInfo = methodName + ", bytecode size:" + ToCString(codeSize); 366 ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, ConvertToStdString("JIT::Compile:" + methodInfo)); 367 368 uint32_t maxSize = 9000; 369 if (vm->GetJSOptions().IsEnableJitFastCompile()) { 370 maxSize = 15; // 15 is method codesize threshold during fast compiling 371 } 372 if (codeSize > maxSize && !(vm->GetJSOptions().IsEnableForceJitCompileMain() && mode == SYNC)) { 373 if (tier == CompilerTier::BASELINE) { 374 LOG_BASELINEJIT(DEBUG) << "skip jit task, as too large:" << methodInfo; 375 } else { 376 LOG_JIT(DEBUG) << "skip jit task, as too large:" << methodInfo; 377 } 378 379 return; 380 } 381 if (vm->IsEnableOsr() && offset != MachineCode::INVALID_OSR_OFFSET && method->HasCatchBlock()) { 382 LOG_JIT(DEBUG) << "skip jit task, as osr does not support catch blocks: " << methodInfo; 383 return; 384 } 385 386 CString msg = "compile method:" + methodInfo + ", in work thread"; 387 TimeScope scope(vm, msg, tier, true, true); 388 if (vm->GetJSThread()->IsMachineCodeLowMemory()) { 389 if (tier == CompilerTier::BASELINE) { 390 LOG_BASELINEJIT(DEBUG) << "skip jit task, as low code memory:" << methodInfo; 391 } else { 392 LOG_JIT(DEBUG) << "skip jit task, as low code memory:" << methodInfo; 393 } 394 395 return; 396 } 397 if (!jit->SupportJIT(jsFunction, vm, tier)) { 398 return; 399 } 400 bool needCompile = jit->CheckJitCompileStatus(jsFunction, methodName, tier); 401 if (!needCompile) { 402 return; 403 } 404 405 // using hole value to indecate compiling. todo: reset when failed 406 if (tier == CompilerTier::FAST) { 407 jsFunction->SetMachineCode(vm->GetJSThread(), JSTaggedValue::Hole()); 408 jit->GetJitDfx()->SetTriggerCount(false); 409 } else { 410 ASSERT(tier == CompilerTier::BASELINE); 411 jsFunction->SetBaselineCode(vm->GetJSThread(), JSTaggedValue::Hole()); 412 jit->GetJitDfx()->SetTriggerCount(true); 413 } 414 415 { 416 JitTaskpool::GetCurrentTaskpool()->WaitForJitTaskPoolReady(); 417 EcmaVM *compilerVm = JitTaskpool::GetCurrentTaskpool()->GetCompilerVm(); 418 std::shared_ptr<JitTask> jitTask = std::make_shared<JitTask>(vm->GetJSThread(), 419 // avoid check fail when enable multi-thread check 420 compilerVm->GetJSThreadNoCheck(), 421 jit, jsFunction, tier, methodName, offset, vm->GetJSThread()->GetThreadId(), mode); 422 423 jitTask->PrepareCompile(); 424 JitTaskpool::GetCurrentTaskpool()->PostTask( 425 std::make_unique<JitTask::AsyncTask>(jitTask, vm->GetJSThread()->GetThreadId())); 426 if (mode == SYNC) { 427 // sync mode, also compile in taskpool as litecg unsupport parallel compile, 428 // wait task compile finish then install code 429 jitTask->WaitFinish(); 430 jitTask->InstallCode(); 431 } 432 int spendTime = scope.TotalSpentTimeInMicroseconds(); 433 jitTask->SetMainThreadCompilerTime(spendTime); 434 jit->GetJitDfx()->RecordSpentTimeAndPrintStatsLogInJsThread(spendTime); 435 } 436} 437 438void Jit::RequestInstallCode(std::shared_ptr<JitTask> jitTask) 439{ 440 LockHolder holder(threadTaskInfoLock_); 441 ThreadTaskInfo &info = threadTaskInfo_[jitTask->GetHostThread()]; 442 if (info.skipInstallTask_) { 443 return; 444 } 445 info.installJitTasks_.push_back(jitTask); 446 447 // set 448 jitTask->GetHostThread()->SetInstallMachineCode(true); 449 jitTask->GetHostThread()->SetCheckSafePointStatus(); 450} 451 452bool Jit::CheckJitCompileStatus(JSHandle<JSFunction> &jsFunction, 453 const CString &methodName, CompilerTier tier) 454{ 455 if (tier == CompilerTier::FAST && 456 jsFunction->GetMachineCode() == JSTaggedValue::Hole()) { 457 LOG_JIT(DEBUG) << "skip method, as it compiling:" << methodName; 458#if ECMASCRIPT_ENABLE_JIT_WARMUP_PROFILER 459 auto &profMap = JitWarmupProfiler::GetInstance()->profMap_; 460 if (profMap.find(methodName) != profMap.end()) { 461 profMap.erase(methodName); 462 } 463#endif 464 return false; 465 } 466 467 if (tier == CompilerTier::BASELINE && 468 jsFunction->GetBaselineCode() == JSTaggedValue::Hole()) { 469 LOG_BASELINEJIT(DEBUG) << "skip method, as it compiling:" << methodName; 470 return false; 471 } 472 473 if (tier == CompilerTier::FAST && jsFunction->IsCompiledCode()) { 474 JSTaggedValue machineCode = jsFunction->GetMachineCode(); 475 if (machineCode.IsMachineCodeObject() && 476 MachineCode::Cast(machineCode.GetTaggedObject())->GetOSROffset() == MachineCode::INVALID_OSR_OFFSET) { 477 LOG_JIT(DEBUG) << "skip method, as it has been jit compiled:" << methodName; 478 return false; 479 } 480 return true; 481 } 482 483 if (tier == CompilerTier::BASELINE && 484 jsFunction->GetBaselineCode() != JSTaggedValue::Undefined()) { 485 LOG_BASELINEJIT(DEBUG) << "skip method, as it has been jit compiled:" << methodName; 486 return false; 487 } 488 return true; 489} 490 491uint32_t Jit::GetRunningTaskCnt(EcmaVM *vm) 492{ 493 uint32_t cnt = 0; 494 JitTaskpool::GetCurrentTaskpool()->ForEachTask([&cnt, &vm](Task *task) { 495 JitTask::AsyncTask *asyncTask = static_cast<JitTask::AsyncTask*>(task); 496 if (asyncTask->GetHostVM() == vm) { 497 cnt ++; 498 } 499 }); 500 LockHolder holder(threadTaskInfoLock_); 501 ThreadTaskInfo &info = threadTaskInfo_[vm->GetJSThread()]; 502 auto &taskQueue = info.installJitTasks_; 503 return taskQueue.size() + cnt; 504} 505 506void Jit::InstallTasks(JSThread *jsThread) 507{ 508 LockHolder holder(threadTaskInfoLock_); 509 ThreadTaskInfo &info = threadTaskInfo_[jsThread]; 510 auto &taskQueue = info.installJitTasks_; 511 512 ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, ConvertToStdString("Jit::InstallTasks count:" + ToCString(taskQueue.size()))); 513 514 for (auto it = taskQueue.begin(); it != taskQueue.end(); it++) { 515 std::shared_ptr<JitTask> task = *it; 516 // check task state 517 task->InstallCode(); 518 } 519 taskQueue.clear(); 520} 521 522bool Jit::JitCompile(void *compiler, JitTask *jitTask) 523{ 524 ASSERT(jitCompile_ != nullptr); 525 return jitCompile_(compiler, jitTask); 526} 527 528bool Jit::JitFinalize(void *compiler, JitTask *jitTask) 529{ 530 ASSERT(jitFinalize_ != nullptr); 531 return jitFinalize_(compiler, jitTask); 532} 533 534void *Jit::CreateJitCompilerTask(JitTask *jitTask) 535{ 536 ASSERT(createJitCompilerTask_ != nullptr); 537 return createJitCompilerTask_(jitTask); 538} 539 540void Jit::ClearTask(const std::function<bool(Task *task)> &checkClear) 541{ 542 JitTaskpool::GetCurrentTaskpool()->ForEachTask([&checkClear](Task *task) { 543 JitTask::AsyncTask *asyncTask = static_cast<JitTask::AsyncTask*>(task); 544 if (checkClear(asyncTask)) { 545 asyncTask->Terminated(); 546 } 547 }); 548} 549 550void Jit::ClearTask(EcmaContext *ecmaContext) 551{ 552 ClearTask([ecmaContext](Task *task) { 553 JitTask::AsyncTask *asyncTask = static_cast<JitTask::AsyncTask*>(task); 554 return ecmaContext == asyncTask->GetEcmaContext(); 555 }); 556} 557 558void Jit::ClearTaskWithVm(EcmaVM *vm) 559{ 560 ClearTask([vm](Task *task) { 561 JitTask::AsyncTask *asyncTask = static_cast<JitTask::AsyncTask*>(task); 562 return vm == asyncTask->GetHostVM(); 563 }); 564 565 { 566 LockHolder holder(threadTaskInfoLock_); 567 ThreadTaskInfo &info = threadTaskInfo_[vm->GetJSThread()]; 568 info.skipInstallTask_ = true; 569 auto &taskQueue = info.installJitTasks_; 570 taskQueue.clear(); 571 572 if (info.jitTaskCnt_.load() != 0) { 573 info.jitTaskCntCv_.Wait(&threadTaskInfoLock_); 574 } 575 } 576} 577 578void Jit::IncJitTaskCnt(JSThread *thread) 579{ 580 LockHolder holder(threadTaskInfoLock_); 581 ThreadTaskInfo &info = threadTaskInfo_[thread]; 582 info.jitTaskCnt_.fetch_add(1); 583} 584 585void Jit::DecJitTaskCnt(JSThread *thread) 586{ 587 LockHolder holder(threadTaskInfoLock_); 588 ThreadTaskInfo &info = threadTaskInfo_[thread]; 589 uint32_t old = info.jitTaskCnt_.fetch_sub(1); 590 if (old == 1) { 591 info.jitTaskCntCv_.Signal(); 592 } 593} 594 595void Jit::CheckMechineCodeSpaceMemory(JSThread *thread, int remainSize) 596{ 597 if (!thread->IsMachineCodeLowMemory()) { 598 return; 599 } 600 if (remainSize > MIN_CODE_SPACE_SIZE) { 601 thread->SetMachineCodeLowMemory(false); 602 } 603} 604 605void Jit::ChangeTaskPoolState(bool inBackground) 606{ 607 if (fastJitEnable_ || baselineJitEnable_) { 608 if (inBackground) { 609 JitTaskpool::GetCurrentTaskpool()->SetThreadPriority(PriorityMode::BACKGROUND); 610 } else { 611 JitTaskpool::GetCurrentTaskpool()->SetThreadPriority(PriorityMode::FOREGROUND); 612 } 613 } 614} 615 616Jit::TimeScope::~TimeScope() 617{ 618 if (!outPutLog_) { 619 return; 620 } 621 if (isDebugLevel_) { 622 if (tier_ == CompilerTier::BASELINE) { 623 LOG_BASELINEJIT(DEBUG) << message_ << ": " << TotalSpentTime() << "ms"; 624 return; 625 } 626 ASSERT(tier_ == CompilerTier::FAST); 627 LOG_JIT(DEBUG) << message_ << ": " << TotalSpentTime() << "ms"; 628 } else { 629 if (tier_ == CompilerTier::BASELINE) { 630 LOG_BASELINEJIT(INFO) << message_ << ": " << TotalSpentTime() << "ms"; 631 return; 632 } 633 ASSERT(tier_ == CompilerTier::FAST); 634 auto bundleName = vm_->GetBundleName(); 635 if (vm_->GetEnableJitLogSkip() && bundleName != "" && message_.find(bundleName) == std::string::npos) { 636 return; 637 } 638 LOG_JIT(INFO) << message_ << ": " << TotalSpentTime() << "ms"; 639 } 640} 641} // namespace panda::ecmascript 642