File: code_cache_generator.cc

package info (click to toggle)
chromium 138.0.7204.157-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 6,071,864 kB
  • sloc: cpp: 34,936,859; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,967; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (111 lines) | stat: -rw-r--r-- 4,114 bytes parent folder | download | duplicates (2)
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);
}