• 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 open_mode)22 bool FileManager::LoadAbcFile(std::string_view location, panda_file::File::OpenMode open_mode)
23 {
24     auto pf = panda_file::OpenPandaFile(location, "", open_mode);
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()) {
31         TryLoadAnFileForLocation(location);
32         auto aot_file = runtime->GetClassLinker()->GetAotManager()->FindPandaFile(std::string(location));
33         if (aot_file != nullptr) {
34             pf->SetClassHashTable(aot_file->GetClassHashTable());
35         }
36     }
37     runtime->GetClassLinker()->AddPandaFile(std::move(pf));
38     return true;
39 }
40 
TryLoadAnFileForLocation(std::string_view panda_file_location)41 bool FileManager::TryLoadAnFileForLocation(std::string_view panda_file_location)
42 {
43     auto an_location = FileManager::ResolveAnFilePath(panda_file_location);
44     if (an_location.empty()) {
45         return true;
46     }
47     auto res = FileManager::LoadAnFile(an_location, false);
48     if (res && res.Value()) {
49         LOG(INFO, PANDAFILE) << "Successfully load .an file for '" << panda_file_location << "': '" << an_location
50                              << "'";
51     } else if (!res) {
52         LOG(INFO, PANDAFILE) << "Failed to load AOT file: '" << an_location << "': " << res.Error();
53     } else {
54         LOG(INFO, PANDAFILE) << "Failed to load '" << an_location << "' with unknown reason";
55     }
56     return true;
57 }
58 
LoadAnFile(std::string_view an_location,bool force)59 Expected<bool, std::string> FileManager::LoadAnFile(std::string_view an_location, bool force)
60 {
61     PandaRuntimeInterface runtime_iface;
62     auto runtime = Runtime::GetCurrent();
63     auto gc_type = Runtime::GetGCType(Runtime::GetOptions(), plugins::RuntimeTypeToLang(runtime->GetRuntimeType()));
64     ASSERT(gc_type != panda::mem::GCType::INVALID_GC);
65     auto real_an_file_path = os::GetAbsolutePath(an_location);
66     return runtime->GetClassLinker()->GetAotManager()->AddFile(real_an_file_path, &runtime_iface,
67                                                                static_cast<uint32_t>(gc_type), force);
68 }
69 
ResolveAnFilePath(std::string_view abc_path)70 PandaString FileManager::ResolveAnFilePath(std::string_view abc_path)
71 {
72     // check whether an aot version of this file already exist
73     // Todo(Wentao):
74     //   1. search ark native file file base on ARCH info from runtime.
75     //   2. allow searching an file out of same path of ark bytecode file.
76     const PandaString &an_path_suffix = ".an";
77     PandaString::size_type pos_start = abc_path.find_last_of('/');
78     PandaString::size_type pos_end = abc_path.find_last_of('.');
79     if (pos_start != std::string_view::npos && pos_end != std::string_view::npos) {
80         LOG(DEBUG, PANDAFILE) << "current abc file path: " << abc_path;
81         PandaString abc_path_prefix = PandaString(abc_path.substr(0, pos_start));
82         PandaString an_file_path =
83             abc_path_prefix + PandaString(abc_path.substr(pos_start, pos_end - pos_start)) + an_path_suffix;
84 
85         const char *filename = an_file_path.c_str();
86         if (access(filename, F_OK) == 0) {
87             return an_file_path;
88         }
89     }
90     LOG(DEBUG, PANDAFILE) << "There is no corresponding .an file for " << abc_path;
91     return "";
92 }
93 
94 }  // namespace panda
95