Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/update-v8.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Update V8

on:
schedule:
- cron: "1 10 * * *" # this is 1 hour after the autoroll in denoland/v8
- cron: "0 10 * * *"
workflow_dispatch:

permissions: write-all
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
From fe0790450d0c8668e859d125e952bd3687267adb Mon Sep 17 00:00:00 2001
From: Divy Srivastava <dj.srivastava23@gmail.com>
Date: Tue, 5 Dec 2023 09:35:57 +0530
Subject: [PATCH] Remove googletest visibility workaround in BUILD.gn

---
third_party/googletest/BUILD.gn | 18 ------------------
1 file changed, 18 deletions(-)

diff --git a/third_party/googletest/BUILD.gn b/third_party/googletest/BUILD.gn
index 1cf84b3..0918a49 100644
--- a/third_party/googletest/BUILD.gn
+++ b/third_party/googletest/BUILD.gn
@@ -2,8 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

-import("../../gni/v8.gni")
-
config("gtest_config") {
visibility = [ ":*" ] # gmock also shares this config.

@@ -91,14 +89,6 @@ source_set("gtest") {
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [ "//build/config/compiler:no_chromium_code" ]

- # V8-only workaround for http://crbug.com/chromium/1191946. Ensures that
- # googletest is compiled with the same visibility such as the rest of V8, see
- # https://source.chromium.org/chromium/chromium/src/+/master:v8/gni/v8.gni
- if ((is_posix || is_fuchsia) && (v8_enable_backtrace || v8_monolithic)) {
- configs -= [ "//build/config/gcc:symbol_visibility_hidden" ]
- configs += [ "//build/config/gcc:symbol_visibility_default" ]
- }
-
deps = []

if (is_fuchsia) {
@@ -143,14 +133,6 @@ source_set("gmock") {
"src/googlemock/src/gmock.cc",
]

- # V8-only workaround for http://crbug.com/chromium/1191946. Ensures that
- # googletest is compiled with the same visibility such as the rest of V8, see
- # https://source.chromium.org/chromium/chromium/src/+/master:v8/gni/v8.gni
- if ((is_posix || is_fuchsia) && (v8_enable_backtrace || v8_monolithic)) {
- configs -= [ "//build/config/gcc:symbol_visibility_hidden" ]
- configs += [ "//build/config/gcc:symbol_visibility_default" ]
- }
-
public_configs = [
":gmock_config",
":gtest_config",
--
2.37.1 (Apple Git-137.1)
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
From 183144148764c4288d63639ff0a7f46e18203fa7 Mon Sep 17 00:00:00 2001
From: Bert Belder <bertbelder@gmail.com>
Date: Wed, 25 May 2022 20:40:04 +0200
Subject: [PATCH 3/4] Fix crash on Apple Silicon when mprotect() fails
expectedly

---
src/base/platform/platform-posix.cc | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/base/platform/platform-posix.cc b/src/base/platform/platform-posix.cc
index da42cda6c4..f29d754e77 100644
--- a/src/base/platform/platform-posix.cc
+++ b/src/base/platform/platform-posix.cc
@@ -479,12 +479,6 @@ bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) {
int prot = GetProtectionFromMemoryPermission(access);
int ret = mprotect(address, size, prot);

- // Setting permissions can fail if the limit of VMAs is exceeded.
- // Any failure that's not OOM likely indicates a bug in the caller (e.g.
- // using an invalid mapping) so attempt to catch that here to facilitate
- // debugging of these failures.
- if (ret != 0) CHECK_EQ(ENOMEM, errno);
-
// MacOS 11.2 on Apple Silicon refuses to switch permissions from
// rwx to none. Just use madvise instead.
#if defined(V8_OS_DARWIN)
@@ -494,6 +488,12 @@ bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) {
}
#endif

+ // Setting permissions can fail if the limit of VMAs is exceeded.
+ // Any failure that's not OOM likely indicates a bug in the caller (e.g.
+ // using an invalid mapping) so attempt to catch that here to facilitate
+ // debugging of these failures.
+ if (ret != 0) CHECK_EQ(ENOMEM, errno);
+
if (ret == 0 && access == OS::MemoryPermission::kNoAccess) {
// This is advisory; ignore errors and continue execution.
USE(DiscardSystemPages(address, size));

--
2.37.3
133 changes: 100 additions & 33 deletions tools/auto_update_v8.ts
Original file line number Diff line number Diff line change
@@ -1,66 +1,133 @@
const V8_TRACKING_BRANCH = "14.7-lkgr-denoland";
// V8 version to track. Update this when bumping to a new major V8 version.
const V8_VERSION = "14.7";

const V8_UPSTREAM = "https://chromium.googlesource.com/v8/v8.git";
const V8_FORK = "https://github.com/denoland/v8.git";
const UPSTREAM_LKGR = `${V8_VERSION}-lkgr`;
const DENOLAND_LKGR = `${V8_VERSION}-lkgr-denoland`;
const AUTOROLL_BRANCH = "autoroll";

function extractVersion() {
async function run(
cmd: string,
args: string[],
cwd?: string,
): Promise<Uint8Array> {
console.log("$", cmd, ...args);
const proc = new Deno.Command(cmd, { args, cwd, stdout: "piped" });
const output = await proc.output();
if (!output.success) {
console.error(`Failed to run ${cmd} ${args.join(" ")}`);
Deno.exit(1);
}
return output.stdout;
}

function extractVersion(path = "./v8/include/v8-version.h"): string {
const MAJOR_PREFIX = "#define V8_MAJOR_VERSION ";
const MINOR_PREFIX = "#define V8_MINOR_VERSION ";
const BUILD_PREFIX = "#define V8_BUILD_NUMBER ";
const PATCH_PREFIX = "#define V8_PATCH_LEVEL ";

const versionDotH = Deno.readTextFileSync("./v8/include/v8-version.h");
const versionDotH = Deno.readTextFileSync(path);
const lines = versionDotH.split("\n");
const major = parseInt(lines.find((s) => s.startsWith(MAJOR_PREFIX))!
.substring(MAJOR_PREFIX.length));
const minor = parseInt(lines.find((s) => s.startsWith(MINOR_PREFIX))!
.substring(MINOR_PREFIX.length));
const build = parseInt(lines.find((s) => s.startsWith(BUILD_PREFIX))!
.substring(BUILD_PREFIX.length));
const patch = parseInt(lines.find((s) => s.startsWith(PATCH_PREFIX))!
.substring(PATCH_PREFIX.length));
const major = parseInt(
lines.find((s) => s.startsWith(MAJOR_PREFIX))!.substring(
MAJOR_PREFIX.length,
),
);
const minor = parseInt(
lines.find((s) => s.startsWith(MINOR_PREFIX))!.substring(
MINOR_PREFIX.length,
),
);
const build = parseInt(
lines.find((s) => s.startsWith(BUILD_PREFIX))!.substring(
BUILD_PREFIX.length,
),
);
const patch = parseInt(
lines.find((s) => s.startsWith(PATCH_PREFIX))!.substring(
PATCH_PREFIX.length,
),
);

return `${major}.${minor}.${build}.${patch}`;
}

// Start from origin/main
await run("git", ["checkout", "origin/main"]);
await run("git", ["submodule", "update", "--init", "--recursive", "v8"]);

const currentVersion = extractVersion();
console.log(`Starting auto update. Currently on ${currentVersion}`);

async function run(
cmd: string,
args: string[],
cwd?: string,
): Promise<Uint8Array> {
console.log("$", cmd, ...args);
const proc = new Deno.Command(cmd, { args, cwd });
const output = await proc.output();
if (!output.success) {
console.error(`Failed to run ${cmd} ${args.join(" ")}`);
Deno.exit(1);
}
return output.stdout;
// -- Step 1: Update the denoland/v8 fork --
// Ensure upstream remote exists in the v8 submodule
const remotes = new TextDecoder().decode(
await run("git", ["remote"], "./v8"),
);
if (!remotes.split("\n").includes("upstream")) {
await run("git", ["remote", "add", "upstream", V8_UPSTREAM], "./v8");
}
if (!remotes.split("\n").includes("denoland")) {
await run("git", ["remote", "add", "denoland", V8_FORK], "./v8");
}

// Update v8 submodule
await run("git", ["fetch", `origin`, V8_TRACKING_BRANCH], "./v8");
await run("git", ["checkout", `origin/${V8_TRACKING_BRANCH}`], "./v8");
// Fetch upstream lkgr branch
await run("git", ["fetch", "upstream", UPSTREAM_LKGR], "./v8");

// Create the denoland branch from upstream
await run(
"git",
["checkout", "-B", DENOLAND_LKGR, `upstream/${UPSTREAM_LKGR}`],
"./v8",
);

// Apply patches
const patches = [...Deno.readDirSync("./patches")]
.filter((e) => e.name.endsWith(".patch"))
.map((e) => e.name)
.sort();

for (const patch of patches) {
const patchPath = `${Deno.cwd()}/patches/${patch}`;
console.log(`Applying patch ${patch}`);
await run("git", ["am", "-3", patchPath], "./v8");
}

// Check if version changed
const newVersion = extractVersion();
if (currentVersion == newVersion) {
if (currentVersion === newVersion) {
console.log(`No new version available. Staying on ${newVersion}`);
Deno.exit(0);
}

console.log(`Updated to version ${newVersion}`);

// Push the patched branch to the denoland/v8 fork
console.log("Pushing patched V8 branch to denoland/v8 fork.");
await run(
"git",
["push", "--force", "denoland", DENOLAND_LKGR],
"./v8",
);

// Create and push a tag
const commit = new TextDecoder().decode(
await run("git", ["rev-parse", "HEAD"], "./v8"),
).trim();
const tag = `${newVersion}-denoland-${commit.slice(0, 20)}`;
console.log(`Creating tag ${tag}`);
await run("git", ["tag", tag], "./v8");
await run("git", ["push", "denoland", tag], "./v8");

// -- Step 2: Update rusty_v8 --

// Update V8 dependencies
const depsOutput = await run("python", ["tools/update_deps.py"]);
const depNames = new TextDecoder().decode(depsOutput).split("\n").filter((x) =>
x.length > 0
).at(-1)!.split(
",",
);
const depNames = new TextDecoder().decode(depsOutput).split("\n").filter((
x,
) => x.length > 0).at(-1)!.split(",");

// Update version in readme
let readme = Deno.readTextFileSync("README.md");
Expand Down
Loading