-
Notifications
You must be signed in to change notification settings - Fork 253
/
0007-Add-an-API-to-capture-and-restore-the-cage-base-poin.patch
105 lines (95 loc) · 3.49 KB
/
0007-Add-an-API-to-capture-and-restore-the-cage-base-poin.patch
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
From 7ffee5a4b6c0cf7b144616a1023a074c71335333 Mon Sep 17 00:00:00 2001
From: Kenton Varda <kenton@cloudflare.com>
Date: Tue, 23 May 2023 09:24:11 -0500
Subject: Add an API to capture and restore the cage base pointers.
This will be used in workerd to ensure that the cage pointers propagate to background thread tasks/jobs correctly.
This is not the right solution. Instead, each background task/job implementation should be updated to propagate the pointers itself. However, that seems to require searching all of V8 for such implementations, with a potential crash if one is missed. Under the current time pressure I'd rather take the catch-all approach.
diff --git a/include/v8-locker.h b/include/v8-locker.h
index 22b7a8767a83a702a2601bdfd4c0f71206df0ad5..fee48faffe82400595dca17197c5bbee680a6137 100644
--- a/include/v8-locker.h
+++ b/include/v8-locker.h
@@ -6,6 +6,7 @@
#define INCLUDE_V8_LOCKER_H_
#include "v8config.h" // NOLINT(build/include_directory)
+#include "v8-internal.h"
namespace v8 {
@@ -133,6 +134,35 @@ class V8_EXPORT Locker {
internal::Isolate* isolate_;
};
+/**
+ * Captures the thread-local pointer cage base pointers, so that they can be
+ * applied in a different thread.
+ */
+class PointerCageContext {
+ public:
+ // Get the current thread's context.
+ static PointerCageContext GetCurrent();
+
+ class Scope;
+
+ private:
+ internal::Address cage;
+ internal::Address code_cage;
+
+ void Apply() const;
+};
+
+class PointerCageContext::Scope {
+ public:
+ // Apply the given context to the current thread. Restores the previous
+ // context on destruction. This should always be allocated on the stack.
+ explicit Scope(const PointerCageContext& ctx): saved(GetCurrent()) { ctx.Apply(); }
+ ~Scope() { saved.Apply(); }
+
+ private:
+ PointerCageContext saved;
+};
+
} // namespace v8
#endif // INCLUDE_V8_LOCKER_H_
diff --git a/src/execution/v8threads.cc b/src/execution/v8threads.cc
index 91e1a43d305d06fdf07fccdf80eb07e86115619b..dfe5da8f6bdc5a30d65b7f31d0e3a42fbe49d22b 100644
--- a/src/execution/v8threads.cc
+++ b/src/execution/v8threads.cc
@@ -6,6 +6,7 @@
#include "include/v8-locker.h"
#include "src/api/api.h"
+#include "src/common/ptr-compr.h"
#include "src/debug/debug.h"
#include "src/execution/execution.h"
#include "src/execution/isolate-inl.h"
@@ -329,4 +330,35 @@ void ThreadManager::IterateArchivedThreads(ThreadVisitor* v) {
ThreadId ThreadManager::CurrentId() { return ThreadId::Current(); }
} // namespace internal
+
+PointerCageContext PointerCageContext::GetCurrent() {
+ PointerCageContext result;
+#ifdef V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE
+ result.cage = i::V8HeapCompressionScheme::base();
+#ifdef V8_EXTERNAL_CODE_SPACE
+ result.code_cage = i::ExternalCodeCompressionScheme::base();
+#else
+ result.code_cage = 0;
+#endif // V8_EXTERNAL_CODE_SPACE
+#else
+ result.cage = 0;
+ result.code_cage = 0;
+#endif // V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE
+ return result;
+}
+
+void PointerCageContext::Apply() const {
+#ifdef V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE
+ i::V8HeapCompressionScheme::InitBase(cage);
+#ifdef V8_EXTERNAL_CODE_SPACE
+ i::ExternalCodeCompressionScheme::InitBase(code_cage);
+#else
+ // Since V8_EXTERNAL_CODE_SPACE is not necessarily defined by the embedder, we always make space
+ // for the code cage in this object but only use it when needed. When not needed, silence the
+ // warning with this line.
+ (void)code_cage;
+#endif // V8_EXTERNAL_CODE_SPACE
+#endif // V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE
+}
+
} // namespace v8