From 3783a5c725712dcf75b30db042f97c21b47b5ba4 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Wed, 30 Nov 2022 08:25:10 -0800 Subject: [PATCH] feat: Isolate::memory_pressure_notification() (#1139) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartek IwaƄczuk --- src/binding.cc | 5 +++++ src/isolate.rs | 22 ++++++++++++++++++++++ src/lib.rs | 1 + tests/test_api.rs | 9 +++++++++ 4 files changed, 37 insertions(+) diff --git a/src/binding.cc b/src/binding.cc index 13aeeef7e6..c5ff4fd33f 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -142,6 +142,11 @@ void v8__Isolate__Enter(v8::Isolate* isolate) { isolate->Enter(); } void v8__Isolate__Exit(v8::Isolate* isolate) { isolate->Exit(); } +void v8__Isolate__MemoryPressureNotification(v8::Isolate* isolate, + v8::MemoryPressureLevel level) { + isolate->MemoryPressureNotification(level); +} + void v8__Isolate__ClearKeptObjects(v8::Isolate* isolate) { isolate->ClearKeptObjects(); } diff --git a/src/isolate.rs b/src/isolate.rs index be4f776d5d..ec01ee6aa5 100644 --- a/src/isolate.rs +++ b/src/isolate.rs @@ -70,6 +70,18 @@ pub enum MicrotasksPolicy { Auto = 2, } +/// Memory pressure level for the MemoryPressureNotification. +/// None hints V8 that there is no memory pressure. +/// Moderate hints V8 to speed up incremental garbage collection at the cost +/// of higher latency due to garbage collection pauses. +/// Critical hints V8 to free memory as soon as possible. Garbage collection +/// pauses at this level will be large. +pub enum MemoryPressureLevel { + None = 0, + Moderate = 1, + Critical = 2, +} + /// PromiseHook with type Init is called when a new promise is /// created. When a new promise is created as part of the chain in the /// case of Promise.then or in the intermediate promises created by @@ -348,6 +360,7 @@ extern "C" { fn v8__Isolate__GetNumberOfDataSlots(this: *const Isolate) -> u32; fn v8__Isolate__Enter(this: *mut Isolate); fn v8__Isolate__Exit(this: *mut Isolate); + fn v8__Isolate__MemoryPressureNotification(this: *mut Isolate, level: u8); fn v8__Isolate__ClearKeptObjects(isolate: *mut Isolate); fn v8__Isolate__LowMemoryNotification(isolate: *mut Isolate); fn v8__Isolate__GetHeapStatistics(this: *mut Isolate, s: *mut HeapStatistics); @@ -772,6 +785,15 @@ impl Isolate { v8__Isolate__Exit(self) } + /// Optional notification that the system is running low on memory. + /// V8 uses these notifications to guide heuristics. + /// It is allowed to call this function from another thread while + /// the isolate is executing long running JavaScript code. + #[inline(always)] + pub fn memory_pressure_notification(&mut self, level: MemoryPressureLevel) { + unsafe { v8__Isolate__MemoryPressureNotification(self, level as u8) } + } + /// Clears the set of objects held strongly by the heap. This set of /// objects are originally built when a WeakRef is created or /// successfully dereferenced. diff --git a/src/lib.rs b/src/lib.rs index 2477cd7072..30e9cd8f45 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -101,6 +101,7 @@ pub use isolate::HostImportModuleDynamicallyCallback; pub use isolate::HostInitializeImportMetaObjectCallback; pub use isolate::Isolate; pub use isolate::IsolateHandle; +pub use isolate::MemoryPressureLevel; pub use isolate::MessageCallback; pub use isolate::MicrotasksPolicy; pub use isolate::NearHeapLimitCallback; diff --git a/tests/test_api.rs b/tests/test_api.rs index 3730fdb878..b96184b4c0 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -6355,6 +6355,15 @@ fn value_serializer_not_implemented() { ); } +#[test] +fn memory_pressure_notification() { + let _setup_guard = setup(); + let isolate = &mut v8::Isolate::new(Default::default()); + isolate.memory_pressure_notification(v8::MemoryPressureLevel::Moderate); + isolate.memory_pressure_notification(v8::MemoryPressureLevel::Critical); + isolate.memory_pressure_notification(v8::MemoryPressureLevel::None); +} + // Flaky on aarch64-qemu (Stack corruption). #[cfg(not(target_os = "android"))] #[test]