mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-23 18:20:04 +00:00
!7552 create folder before file
Merge pull request !7552 from Lasting/fix/create-empty-file
This commit is contained in:
commit
30c657d5c0
1
BUILD.gn
1
BUILD.gn
@ -951,6 +951,7 @@ ecma_platform_source = []
|
||||
ecma_platform_source += [
|
||||
"ecmascript/platform/common/map.cpp",
|
||||
"ecmascript/platform/common/mutex.cpp",
|
||||
"ecmascript/platform/common/filesystem.cpp",
|
||||
]
|
||||
|
||||
config("include_llvm") {
|
||||
|
@ -19,10 +19,10 @@
|
||||
|
||||
#include "ecmascript/base/string_helper.h"
|
||||
#include "ecmascript/checkpoint/thread_state_transition.h"
|
||||
#include "ecmascript/compiler/aot_compilation_env.h"
|
||||
#include "ecmascript/compiler/aot_compiler_preprocessor.h"
|
||||
#include "ecmascript/compiler/aot_file/aot_file_manager.h"
|
||||
#include "ecmascript/compiler/pass_manager.h"
|
||||
#include "ecmascript/compiler/aot_compilation_env.h"
|
||||
#include "ecmascript/ecma_string.h"
|
||||
#include "ecmascript/js_runtime_options.h"
|
||||
#include "ecmascript/log.h"
|
||||
@ -31,6 +31,7 @@
|
||||
#include "ecmascript/ohos/enable_aot_list_helper.h"
|
||||
#include "ecmascript/ohos/ohos_pkg_args.h"
|
||||
#include "ecmascript/platform/file.h"
|
||||
#include "ecmascript/platform/filesystem.h"
|
||||
#include "ecmascript/platform/os.h"
|
||||
|
||||
#include "ecmascript/compiler/aot_compiler_stats.h"
|
||||
@ -42,6 +43,7 @@ enum ErrCode {
|
||||
ERR_FAIL = (-1),
|
||||
ERR_HELP = (1),
|
||||
ERR_NO_AP = (2),
|
||||
ERR_MERGE_AP = (3),
|
||||
};
|
||||
|
||||
void CompileValidFiles(PassManager &passManager, AOTFileGenerator &generator, bool &ret,
|
||||
@ -60,20 +62,19 @@ void CompileValidFiles(PassManager &passManager, AOTFileGenerator &generator, bo
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::pair<bool, int> CheckVersion(JSRuntimeOptions &runtimeOptions, bool result)
|
||||
bool CheckVersion(JSRuntimeOptions& runtimeOptions, AotCompilerStats& compilerStats, bool isPgoMerged)
|
||||
{
|
||||
if (runtimeOptions.IsCheckPgoVersion()) {
|
||||
if (result) {
|
||||
return std::pair(true, 0);
|
||||
} else {
|
||||
LOG_COMPILER(ERROR) << "CheckVersion ap and abc do not match";
|
||||
return std::pair(true, 1);
|
||||
if (!isPgoMerged) {
|
||||
LOG_COMPILER(ERROR) << "CheckVersion ap and abc may not match";
|
||||
compilerStats.SetPgoFileLegal(false);
|
||||
}
|
||||
if (runtimeOptions.IsTargetCompilerMode()) {
|
||||
compilerStats.PrintCompilerStatsLog();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (!result) {
|
||||
return std::pair(true, 1);
|
||||
}
|
||||
return std::pair(false, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsExistsPkgInfo(AotCompilerPreprocessor &cPreprocessor)
|
||||
@ -134,7 +135,7 @@ int Main(const int argc, const char **argv)
|
||||
return ERR_HELP;
|
||||
}
|
||||
if (IsExistsPkgInfo(cPreprocessor) && JSNApi::IsAotEscape(cPreprocessor.GetMainPkgArgs()->GetPgoDir())) {
|
||||
LOG_COMPILER(ERROR) << " Stop compile AOT because there are more crashes";
|
||||
LOG_COMPILER(ERROR) << "Stop compile AOT because there are multiple crashes";
|
||||
return ERR_FAIL;
|
||||
}
|
||||
if (runtimeOptions.IsPartialCompilerMode() && cOptions.profilerIn_.empty()) {
|
||||
@ -151,23 +152,20 @@ int Main(const int argc, const char **argv)
|
||||
compilerStats.SetAotFilePath(cOptions.outputFileName_);
|
||||
compilerStats.SetPgoPath(cOptions.profilerIn_);
|
||||
compilerStats.StartCompiler();
|
||||
cPreprocessor.CreateEmptyFile(cOptions.outputFileName_ + AOTFileManager::FILE_EXTENSION_AN);
|
||||
cPreprocessor.CreateEmptyFile(cOptions.outputFileName_ + AOTFileManager::FILE_EXTENSION_AI);
|
||||
profilerDecoder.SetHotnessThreshold(cOptions.hotnessThreshold_);
|
||||
profilerDecoder.SetInPath(cOptions.profilerIn_);
|
||||
cPreprocessor.AOTInitialize();
|
||||
uint32_t checksum = cPreprocessor.GenerateAbcFileInfos();
|
||||
// Notice: lx move load pandaFileHead and verify before GeneralAbcFileInfos.
|
||||
// need support muilt abc
|
||||
auto result = CheckVersion(runtimeOptions, cPreprocessor.HandleMergedPgoFile(checksum));
|
||||
if (result.first) {
|
||||
if (result.second != 0) {
|
||||
compilerStats.SetPgoFileLegal(false);
|
||||
}
|
||||
if (runtimeOptions.IsTargetCompilerMode()) {
|
||||
compilerStats.PrintCompilerStatsLog();
|
||||
}
|
||||
return result.second;
|
||||
// need support multiple abc
|
||||
auto isPgoMerged = cPreprocessor.HandleMergedPgoFile(checksum);
|
||||
if (CheckVersion(runtimeOptions, compilerStats, isPgoMerged)) {
|
||||
return ERR_OK;
|
||||
}
|
||||
if (!isPgoMerged) {
|
||||
filesystem::CreateEmptyFile(cOptions.outputFileName_ + AOTFileManager::FILE_EXTENSION_AN);
|
||||
filesystem::CreateEmptyFile(cOptions.outputFileName_ + AOTFileManager::FILE_EXTENSION_AI);
|
||||
return ERR_MERGE_AP;
|
||||
}
|
||||
cPreprocessor.GeneratePGOTypes(cOptions);
|
||||
cPreprocessor.SnapshotInitialize();
|
||||
|
@ -393,20 +393,4 @@ std::string AotCompilerPreprocessor::GetMainPkgArgsAppSignature() const
|
||||
{
|
||||
return GetMainPkgArgs() == nullptr ? "" : GetMainPkgArgs()->GetAppSignature();
|
||||
}
|
||||
|
||||
void AotCompilerPreprocessor::CreateEmptyFile(const std::string& fileName)
|
||||
{
|
||||
std::string realPath;
|
||||
if (!RealPath(fileName, realPath, false)) {
|
||||
LOG_COMPILER(ERROR) << "failed to create empty file: " << fileName;
|
||||
return;
|
||||
}
|
||||
const char* filePath = realPath.c_str();
|
||||
if (FileExist(filePath)) {
|
||||
LOG_COMPILER(DEBUG) << fileName << " file already exist, skip creating empty file";
|
||||
return;
|
||||
}
|
||||
std::ofstream file(filePath);
|
||||
file.close();
|
||||
}
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
|
@ -186,8 +186,6 @@ public:
|
||||
return str;
|
||||
}
|
||||
|
||||
void CreateEmptyFile(const std::string& fileName);
|
||||
|
||||
private:
|
||||
NO_COPY_SEMANTIC(AotCompilerPreprocessor);
|
||||
NO_MOVE_SEMANTIC(AotCompilerPreprocessor);
|
||||
|
@ -578,7 +578,7 @@ bool AOTFileGenerator::CreateDirIfNotExist(const std::string &filename)
|
||||
}
|
||||
std::string path = realPath.substr(0, index);
|
||||
if (!panda::ecmascript::ForceCreateDirectory(path)) {
|
||||
LOG_COMPILER(ERROR) << "Fail to make dir:" << path;
|
||||
LOG_COMPILER(ERROR) << "Fail to make dir: " << path;
|
||||
return false;
|
||||
}
|
||||
return panda::ecmascript::SetDirModeAsDefault(path);
|
||||
@ -591,7 +591,7 @@ void AOTFileGenerator::SaveAOTFile(const std::string &filename, const std::strin
|
||||
return;
|
||||
}
|
||||
if (!CreateDirIfNotExist(filename)) {
|
||||
LOG_COMPILER(ERROR) << "Fail to access dir:" << filename;
|
||||
LOG_COMPILER(ERROR) << "Fail to access dir: " << filename;
|
||||
return;
|
||||
}
|
||||
PrintMergedCodeComment();
|
||||
@ -679,6 +679,10 @@ void AOTFileGenerator::SaveSnapshotFile()
|
||||
ptManager->GetAOTSnapshot().ResolveSnapshotData(methodToEntryIndexMap);
|
||||
|
||||
CString aiPath = snapshotPath + AOTFileManager::FILE_EXTENSION_AI;
|
||||
if (!CreateDirIfNotExist(aiPath.c_str())) {
|
||||
LOG_COMPILER(ERROR) << "Fail to access dir: " << aiPath;
|
||||
return;
|
||||
}
|
||||
snapshot.Serialize(aiPath);
|
||||
if (!panda::ecmascript::SetFileModeAsDefault(aiPath.c_str())) {
|
||||
LOG_COMPILER(ERROR) << "Fail to set ai file mode:" << aiPath;
|
||||
|
@ -155,6 +155,23 @@ host_unittest_action("InstructionCombineTest") {
|
||||
external_deps = [ "zlib:libz" ]
|
||||
}
|
||||
|
||||
host_unittest_action("CreateEmptyFileTest") {
|
||||
module_out_path = module_output_path
|
||||
|
||||
sources = [
|
||||
# test file
|
||||
"create_empty_file_test.cpp",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"$ark_root/libpandafile:libarkfile_static",
|
||||
"$js_root:libark_jsruntime_test_set",
|
||||
"$js_root/ecmascript/compiler:libark_jsoptimizer_set",
|
||||
sdk_libc_secshared_dep,
|
||||
]
|
||||
external_deps = [ "zlib:libz" ]
|
||||
}
|
||||
|
||||
group("host_unittest") {
|
||||
testonly = true
|
||||
|
||||
@ -162,6 +179,7 @@ group("host_unittest") {
|
||||
deps = [
|
||||
":AssemblerTestAction",
|
||||
":ConstantFoldingTestAction",
|
||||
":CreateEmptyFileTestAction",
|
||||
":GlobalValueNumberingTestAction",
|
||||
":InstructionCombineTestAction",
|
||||
":LoopOptimizationTestAction",
|
||||
|
88
ecmascript/compiler/tests/create_empty_file_test.cpp
Normal file
88
ecmascript/compiler/tests/create_empty_file_test.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ecmascript/compiler/aot_compiler_preprocessor.h"
|
||||
#include "ecmascript/platform/filesystem.h"
|
||||
#include "ecmascript/tests/test_helper.h"
|
||||
|
||||
namespace panda::test {
|
||||
using namespace panda;
|
||||
using namespace panda::ecmascript;
|
||||
using namespace panda::ecmascript::kungfu;
|
||||
class CreateEmptyFileTest : public testing::Test {
|
||||
public:
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
GTEST_LOG_(INFO) << "SetUpTestCase";
|
||||
}
|
||||
|
||||
static void TearDownTestCase()
|
||||
{
|
||||
GTEST_LOG_(INFO) << "TearDownCase";
|
||||
}
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
temp_dir = filesystem::TempDirectoryPath() + "/create_empty_file_test";
|
||||
filesystem::CreateDirectory(temp_dir);
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
filesystem::RemoveAll(temp_dir);
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string temp_dir;
|
||||
};
|
||||
|
||||
HWTEST_F_L0(CreateEmptyFileTest, FileDoesNotExist)
|
||||
{
|
||||
std::string file_path = temp_dir + "/dir1/dir2/entry.an";
|
||||
filesystem::CreateEmptyFile(file_path);
|
||||
|
||||
EXPECT_TRUE(filesystem::Exists(file_path));
|
||||
}
|
||||
|
||||
HWTEST_F_L0(CreateEmptyFileTest, FileExists)
|
||||
{
|
||||
std::string file_path = temp_dir + "/entry.an";
|
||||
|
||||
std::ofstream ofs(file_path);
|
||||
ofs << "test data";
|
||||
ofs.close();
|
||||
|
||||
auto old_size = filesystem::FileSize(file_path);
|
||||
EXPECT_GT(old_size, 0);
|
||||
|
||||
filesystem::CreateEmptyFile(file_path);
|
||||
|
||||
auto new_size = filesystem::FileSize(file_path);
|
||||
|
||||
EXPECT_TRUE(filesystem::Exists(file_path));
|
||||
EXPECT_GT(old_size, 0);
|
||||
EXPECT_GT(new_size, 0);
|
||||
}
|
||||
|
||||
HWTEST_F_L0(CreateEmptyFileTest, DirectoryDoesNotExist)
|
||||
{
|
||||
std::string dir_path = temp_dir + "/dir4/com.hm.app";
|
||||
std::string file_path = dir_path + "/entry.an";
|
||||
filesystem::CreateEmptyFile(file_path);
|
||||
|
||||
EXPECT_TRUE(filesystem::Exists(dir_path));
|
||||
EXPECT_TRUE(filesystem::Exists(file_path));
|
||||
}
|
||||
} // namespace panda::test
|
@ -21,7 +21,7 @@
|
||||
// NO_TAG means not print any tag
|
||||
#define LOG_NO_TAG(level) ARK_LOG(level, Component::NO_TAG)
|
||||
#define LOG_ECMA(level) ARK_LOG(level, Component::ECMASCRIPT)
|
||||
#define LOG_FULL(level) ARK_LOG(level, Component::ALL) << __func__ << ":" << __LINE__ << " "
|
||||
#define LOG_FULL(level) ARK_LOG(level, Component::ALL) << "[" << __func__ << ":" << __LINE__ << "] "
|
||||
#define LOG_GC(level) ARK_LOG(level, Component::GC)
|
||||
#define LOG_INTERPRETER(level) ARK_LOG(level, Component::INTERPRETER)
|
||||
#define LOG_COMPILER(level) ARK_LOG(level, Component::COMPILER)
|
||||
|
132
ecmascript/platform/common/filesystem.cpp
Normal file
132
ecmascript/platform/common/filesystem.cpp
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ecmascript/platform/filesystem.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "ecmascript/platform/directory.h"
|
||||
#include "ecmascript/platform/file.h"
|
||||
|
||||
#include "os/filesystem.h"
|
||||
|
||||
namespace panda::ecmascript::filesystem {
|
||||
bool CreateDirectory(const std::string& path)
|
||||
{
|
||||
if (path.empty()) {
|
||||
return true;
|
||||
}
|
||||
auto pos = path.find_last_of('/');
|
||||
if (pos != std::string::npos) {
|
||||
if (!CreateDirectory(path.substr(0, pos))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
panda::os::CreateDirectories(path);
|
||||
if (!Exists(path)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Exists(const std::string& path)
|
||||
{
|
||||
return panda::ecmascript::FileExist(path.c_str());
|
||||
}
|
||||
|
||||
std::string TempDirectoryPath()
|
||||
{
|
||||
const char* temp = getenv("TMPDIR");
|
||||
if (temp) {
|
||||
return std::string(temp);
|
||||
}
|
||||
return "/tmp";
|
||||
}
|
||||
|
||||
std::size_t FileSize(const std::string& path)
|
||||
{
|
||||
struct stat info;
|
||||
stat(path.c_str(), &info);
|
||||
return info.st_size;
|
||||
}
|
||||
|
||||
bool RemoveAll(const std::string& path)
|
||||
{
|
||||
struct stat info;
|
||||
if (stat(path.c_str(), &info) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (S_ISDIR(info.st_mode)) {
|
||||
DIR* dir = opendir(path.c_str());
|
||||
if (!dir) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct dirent* entry;
|
||||
while ((entry = readdir(dir)) != nullptr) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
|
||||
continue;
|
||||
}
|
||||
std::string entryPath = path + "/" + entry->d_name;
|
||||
if (!RemoveAll(entryPath)) {
|
||||
closedir(dir);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
return rmdir(path.c_str()) == 0;
|
||||
} else {
|
||||
return unlink(path.c_str()) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CreateEmptyFile(const std::string& fileName)
|
||||
{
|
||||
std::string realPath;
|
||||
if (!panda::ecmascript::RealPath(fileName, realPath, false)) {
|
||||
LOG_FULL(ERROR) << "failed to create empty file: " << fileName << ", error: " << std::strerror(errno);
|
||||
return;
|
||||
}
|
||||
if (Exists(realPath)) {
|
||||
LOG_FULL(INFO) << realPath << " exists, skip creation";
|
||||
return;
|
||||
}
|
||||
|
||||
auto index = realPath.find_last_of('/');
|
||||
if (index != std::string::npos) {
|
||||
std::string dir = realPath.substr(0, index);
|
||||
if (Exists(dir)) {
|
||||
LOG_FULL(INFO) << dir << " exists, skip creation";
|
||||
} else {
|
||||
LOG_FULL(INFO) << "creating folder " << dir;
|
||||
if (!CreateDirectory(dir)) {
|
||||
LOG_FULL(ERROR) << "failed to create folder " << dir << ", error: " << std::strerror(errno);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::ofstream file(realPath);
|
||||
if (!file.good()) {
|
||||
LOG_FULL(ERROR) << "failed to create empty file: " << realPath << ", error: " << std::strerror(errno);
|
||||
} else {
|
||||
LOG_FULL(INFO) << "created empty file: " << realPath;
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
} // namespace panda::ecmascript::kungfu::filesystem
|
32
ecmascript/platform/filesystem.h
Normal file
32
ecmascript/platform/filesystem.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ECMASCRIPT_BASE_FILESYSTEM_H
|
||||
#define ECMASCRIPT_BASE_FILESYSTEM_H
|
||||
|
||||
#include <string>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "ecmascript/common.h"
|
||||
|
||||
namespace panda::ecmascript::filesystem {
|
||||
bool CreateDirectory(const std::string& path);
|
||||
bool Exists(const std::string& path);
|
||||
std::string TempDirectoryPath();
|
||||
std::size_t FileSize(const std::string& path);
|
||||
bool RemoveAll(const std::string& path);
|
||||
PUBLIC_API void CreateEmptyFile(const std::string& fileName);
|
||||
} // namespace panda::ecmascript::base
|
||||
#endif // ECMASCRIPT_BASE_FILESYSTEM_H
|
@ -41,7 +41,7 @@ std::string GetPathSeparator()
|
||||
bool RealPath(const std::string &path, std::string &realPath, bool readOnly)
|
||||
{
|
||||
if (path.empty() || path.size() > PATH_MAX) {
|
||||
LOG_ECMA(WARN) << "File path is illeage";
|
||||
LOG_ECMA(WARN) << "File path is illegal";
|
||||
return false;
|
||||
}
|
||||
char buffer[PATH_MAX] = { '\0' };
|
||||
@ -51,7 +51,7 @@ bool RealPath(const std::string &path, std::string &realPath, bool readOnly)
|
||||
realPath = path;
|
||||
return true;
|
||||
}
|
||||
LOG_ECMA(ERROR) << "File path:" << path << " realpath failure. errno: " << errno;
|
||||
LOG_ECMA(ERROR) << "File path: " << path << " realpath failure. errno: " << errno;
|
||||
return false;
|
||||
}
|
||||
realPath = std::string(buffer);
|
||||
@ -161,7 +161,7 @@ JSHandle<EcmaString> ResolveFilenameFromNative(JSThread *thread, JSTaggedValue d
|
||||
|
||||
bool FileExist(const char *filename)
|
||||
{
|
||||
return (access(filename, 0) != -1);
|
||||
return (access(filename, F_OK) != -1);
|
||||
}
|
||||
|
||||
int Unlink(const char *filename)
|
||||
|
@ -283,6 +283,7 @@
|
||||
panda::ecmascript::SubtypingOperator::FillTSInheritInfo*;
|
||||
panda::ecmascript::SubtypingOperator::MergeClassField*;
|
||||
panda::ecmascript::Unlink*;
|
||||
panda::ecmascript::filesystem::CreateEmptyFile*;
|
||||
panda::ecmascript::base::ArrayHelper::GetLength*;
|
||||
panda::ecmascript::base::utf_helper::ConvertRegionUtf16ToUtf8*;
|
||||
panda::ecmascript::base::NumberHelper::DoubleInRangeInt32*;
|
||||
|
Loading…
Reference in New Issue
Block a user