1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/strings/strcat.h"
#include "base/strings/string_split.h"
#include "base/task/single_thread_task_executor.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "gin/v8_initializer.h"
#include "mojo/core/embedder/embedder.h"
#include "mojo/public/cpp/bindings/binder_map.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/web/blink.h"
#include "third_party/blink/public/web/web_bundled_code_cache_generator.h"
#include "tools/v8_context_snapshot/buildflags.h"
#include "v8/include/v8.h"
namespace {
class CodeCacheGenPlatform final : public blink::Platform {
public:
// blink::Platform:
bool DisallowV8FeatureFlagOverrides() const override { return true; }
};
// Returns true if the module code cache was generated and written successfully.
bool GenerateModuleCodeCache(v8::Isolate* isolate,
const base::FilePath& in_module_path,
const base::FilePath& out_code_cache_path) {
v8::TryCatch trycatch(isolate);
// Attempt to read the module file from disk.
std::string module_file_string;
if (!base::ReadFileToString(in_module_path, &module_file_string)) {
LOG(ERROR) << "Error reading file " << in_module_path;
return false;
}
const blink::WebBundledCodeCacheGenerator::SerializedCodeCacheData
serialized_code_cache_data = blink::WebBundledCodeCacheGenerator::
CreateSerializedCodeCacheForModule(
isolate, blink::WebString::FromUTF8(module_file_string));
// Attempt to write the cached metadata.
if (!base::WriteFile(out_code_cache_path, serialized_code_cache_data)) {
LOG(ERROR) << "Failed to write cached metadata to file.";
return false;
}
return true;
}
} // namespace
int main(int argc, char** argv) {
base::AtExitManager at_exit;
const bool kRemoveRecognizedFlags = true;
v8::V8::SetFlagsFromCommandLine(&argc, argv, kRemoveRecognizedFlags);
base::CommandLine::Init(argc, argv);
// Setup the Blink environment.
base::SingleThreadTaskExecutor main_thread_task_executor;
base::ThreadPoolInstance::CreateAndStartWithDefaultParams("CompileBytecode");
mojo::core::Init();
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
#if BUILDFLAG(USE_V8_CONTEXT_SNAPSHOT)
gin::V8Initializer::LoadV8Snapshot(
gin::V8SnapshotFileType::kWithAdditionalContext);
#else
gin::V8Initializer::LoadV8Snapshot(gin::V8SnapshotFileType::kDefault);
#endif // BUILDFLAG(USE_V8_CONTEXT_SNAPSHOT)
#endif // V8_USE_EXTERNAL_STARTUP_DATA
// Set predictable flag in V8 to generate consistent bytecode.
static constexpr char kPredictableFlag[] = "--predictable";
v8::V8::SetFlagsFromString(kPredictableFlag, sizeof(kPredictableFlag) - 1);
CodeCacheGenPlatform platform;
mojo::BinderMap binders;
blink::CreateMainThreadAndInitialize(&platform, &binders);
auto* isolate = blink::CreateMainThreadIsolate();
const base::FilePath in_folder =
base::CommandLine::ForCurrentProcess()->GetSwitchValuePath("in_folder");
CHECK(!in_folder.empty());
const std::vector<std::string> in_files = base::SplitString(
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII("in_files"),
",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
CHECK(!in_files.empty());
const base::FilePath out_folder =
base::CommandLine::ForCurrentProcess()->GetSwitchValuePath("out_folder");
CHECK(!out_folder.empty());
const std::string out_file_suffix =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
"out_file_suffix");
for (const std::string_view in_file : in_files) {
if (!GenerateModuleCodeCache(
isolate, in_folder.AppendASCII(in_file),
out_folder.AppendASCII(base::StrCat({in_file, out_file_suffix})))) {
_exit(1);
}
}
_exit(0);
}
|