• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #include "runtime/include/file_manager.h"
17 #include "runtime/include/runtime.h"
18 #include "libpandabase/os/filesystem.h"
19 
20 namespace panda {
21 
LoadAbcFile(std::string_view location,panda_file::File::OpenMode openMode)22 bool FileManager::LoadAbcFile(std::string_view location, panda_file::File::OpenMode openMode)
23 {
24     auto pf = panda_file::OpenPandaFile(location, "", openMode);
25     if (pf == nullptr) {
26         LOG(ERROR, PANDAFILE) << "Load panda file failed: " << location;
27         return false;
28     }
29     auto runtime = Runtime::GetCurrent();
30     if (Runtime::GetOptions().IsEnableAn() && !Runtime::GetOptions().IsArkAot()) {
31         TryLoadAnFileForLocation(location);
32         auto aotFile = runtime->GetClassLinker()->GetAotManager()->FindPandaFile(std::string(location));
33         if (aotFile != nullptr) {
34             pf->SetClassHashTable(aotFile->GetClassHashTable());
35         }
36     }
37     runtime->GetClassLinker()->AddPandaFile(std::move(pf));
38     return true;
39 }
40 
TryLoadAnFileForLocation(std::string_view pandaFileLocation)41 bool FileManager::TryLoadAnFileForLocation(std::string_view pandaFileLocation)
42 {
43     auto anLocation = FileManager::ResolveAnFilePath(pandaFileLocation);
44     if (anLocation.empty()) {
45         return true;
46     }
47     auto res = FileManager::LoadAnFile(anLocation, false);
48     if (res && res.Value()) {
49         LOG(INFO, PANDAFILE) << "Successfully load .an file for '" << pandaFileLocation << "': '" << anLocation << "'";
50     } else if (!res) {
51         LOG(INFO, PANDAFILE) << "Failed to load AOT file: '" << anLocation << "': " << res.Error();
52     } else {
53         LOG(INFO, PANDAFILE) << "Failed to load '" << anLocation << "' with unknown reason";
54     }
55     return true;
56 }
57 
LoadAnFile(std::string_view anLocation,bool force)58 Expected<bool, std::string> FileManager::LoadAnFile(std::string_view anLocation, bool force)
59 {
60     PandaRuntimeInterface runtimeIface;
61     auto runtime = Runtime::GetCurrent();
62     auto gcType = Runtime::GetGCType(Runtime::GetOptions(), plugins::RuntimeTypeToLang(runtime->GetRuntimeType()));
63     ASSERT(gcType != panda::mem::GCType::INVALID_GC);
64     auto realAnFilePath = os::GetAbsolutePath(anLocation);
65     return runtime->GetClassLinker()->GetAotManager()->AddFile(realAnFilePath, &runtimeIface,
66                                                                static_cast<uint32_t>(gcType), force);
67 }
68 
ResolveAnFilePath(std::string_view abcPath)69 PandaString FileManager::ResolveAnFilePath(std::string_view abcPath)
70 {
71     // check whether an aot version of this file already exist
72     // NOTE(Wentao):
73     //   1. search ark native file file base on ARCH info from runtime.
74     //   2. allow searching an file out of same path of ark bytecode file.
75     const PandaString &anPathSuffix = ".an";
76     PandaString::size_type posStart = abcPath.find_last_of('/');
77     PandaString::size_type posEnd = abcPath.find_last_of('.');
78     if (posStart != std::string_view::npos && posEnd != std::string_view::npos) {
79         LOG(DEBUG, PANDAFILE) << "current abc file path: " << abcPath;
80         PandaString abcPathPrefix = PandaString(abcPath.substr(0, posStart));
81         PandaString anFilePath =
82             abcPathPrefix + PandaString(abcPath.substr(posStart, posEnd - posStart)) + anPathSuffix;
83 
84         const char *filename = anFilePath.c_str();
85         if (access(filename, F_OK) == 0) {
86             return anFilePath;
87         }
88     }
89     LOG(DEBUG, PANDAFILE) << "There is no corresponding .an file for " << abcPath;
90     return "";
91 }
92 
93 }  // namespace panda
94