mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Auto merge of #18952 - jdm:no-leak-on-shutdown, r=nox
Do not trace Rust values when thread is shutting down. This addresses a paint point when using debug-mozjs builds. jonco says that it is considered a leak when objects stored in side tables in a SpiderMonkey embedding are traced right before shutting down. This PR adds a per-thread flag that controls whether to run the Rust-side trace hooks, which is automatically toggled before the final GC occurs when destroying a JS runtime. --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #18948 and fix #18947. - [x] These changes do not require tests because we don't use debug-mozjs on CI <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18952) <!-- Reviewable:end -->
This commit is contained in:
commit
a71470abe5
8 changed files with 35 additions and 18 deletions
|
@ -35,7 +35,6 @@ use std::collections::hash_map::Entry::{Occupied, Vacant};
|
|||
use std::collections::hash_map::HashMap;
|
||||
use std::hash::Hash;
|
||||
use std::marker::PhantomData;
|
||||
use std::os;
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, Weak};
|
||||
use task::TaskOnce;
|
||||
|
@ -267,8 +266,7 @@ fn remove_nulls<K: Eq + Hash + Clone, V> (table: &mut HashMap<K, Weak<V>>) {
|
|||
|
||||
/// A JSTraceDataOp for tracing reflectors held in LIVE_REFERENCES
|
||||
#[allow(unrooted_must_root)]
|
||||
pub unsafe extern "C" fn trace_refcounted_objects(tracer: *mut JSTracer,
|
||||
_data: *mut os::raw::c_void) {
|
||||
pub unsafe fn trace_refcounted_objects(tracer: *mut JSTracer) {
|
||||
info!("tracing live refcounted references");
|
||||
LIVE_REFERENCES.with(|ref r| {
|
||||
let r = r.borrow();
|
||||
|
|
|
@ -28,11 +28,10 @@ use ipc_channel::router::ROUTER;
|
|||
use js::jsapi::{HandleValue, JS_SetInterruptCallback};
|
||||
use js::jsapi::{JSAutoCompartment, JSContext, NullHandleValue};
|
||||
use js::jsval::UndefinedValue;
|
||||
use js::rust::Runtime;
|
||||
use msg::constellation_msg::TopLevelBrowsingContextId;
|
||||
use net_traits::{IpcSend, load_whole_resource};
|
||||
use net_traits::request::{CredentialsMode, Destination, RequestInit, Type as RequestType};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, new_rt_and_cx};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, new_rt_and_cx, Runtime};
|
||||
use script_runtime::ScriptThreadEventCategory::WorkerEvent;
|
||||
use script_traits::{TimerEvent, TimerSource, WorkerGlobalScopeInit, WorkerScriptLoadOrigin};
|
||||
use servo_rand::random;
|
||||
|
|
|
@ -22,10 +22,9 @@ use ipc_channel::ipc::{self, IpcSender, IpcReceiver};
|
|||
use ipc_channel::router::ROUTER;
|
||||
use js::jsapi::{JS_SetInterruptCallback, JSAutoCompartment, JSContext};
|
||||
use js::jsval::UndefinedValue;
|
||||
use js::rust::Runtime;
|
||||
use net_traits::{load_whole_resource, IpcSend, CustomResponseMediator};
|
||||
use net_traits::request::{CredentialsMode, Destination, RequestInit, Type as RequestType};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan, new_rt_and_cx};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan, new_rt_and_cx, Runtime};
|
||||
use script_traits::{TimerEvent, WorkerGlobalScopeInit, ScopeThings, ServiceWorkerMsg, WorkerScriptLoadOrigin};
|
||||
use servo_config::prefs::PREFS;
|
||||
use servo_rand::random;
|
||||
|
|
|
@ -57,7 +57,6 @@ use ipc_channel::router::ROUTER;
|
|||
use js::jsapi::{HandleObject, HandleValue, JSAutoCompartment, JSContext};
|
||||
use js::jsapi::{JS_GC, JS_GetRuntime};
|
||||
use js::jsval::UndefinedValue;
|
||||
use js::rust::Runtime;
|
||||
use layout_image::fetch_image_for_layout;
|
||||
use microtask::MicrotaskQueue;
|
||||
use msg::constellation_msg::{FrameType, PipelineId};
|
||||
|
@ -75,7 +74,7 @@ use script_layout_interface::reporter::CSSErrorReporter;
|
|||
use script_layout_interface::rpc::{ContentBoxResponse, ContentBoxesResponse, LayoutRPC};
|
||||
use script_layout_interface::rpc::{MarginStyleResponse, NodeScrollRootIdResponse};
|
||||
use script_layout_interface::rpc::{ResolvedStyleResponse, TextIndexResponse};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, ScriptThreadEventCategory};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, ScriptThreadEventCategory, Runtime};
|
||||
use script_thread::{ImageCacheMsg, MainThreadScriptChan, MainThreadScriptMsg};
|
||||
use script_thread::{ScriptThread, SendableMainThreadScriptChan};
|
||||
use script_traits::{ConstellationControlMsg, DocumentState, LoadData, MozBrowserEvent};
|
||||
|
|
|
@ -29,10 +29,9 @@ use ipc_channel::ipc::IpcSender;
|
|||
use js::jsapi::{HandleValue, JSAutoCompartment, JSContext, JSRuntime};
|
||||
use js::jsval::UndefinedValue;
|
||||
use js::panic::maybe_resume_unwind;
|
||||
use js::rust::Runtime;
|
||||
use net_traits::{IpcSend, load_whole_resource};
|
||||
use net_traits::request::{CredentialsMode, Destination, RequestInit as NetRequestInit, Type as RequestType};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, get_reports};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, get_reports, Runtime};
|
||||
use script_traits::{TimerEvent, TimerEventId};
|
||||
use script_traits::WorkerGlobalScopeInit;
|
||||
use servo_url::{MutableOrigin, ServoUrl};
|
||||
|
|
|
@ -37,7 +37,6 @@ use js::jsapi::JSGCParamKey;
|
|||
use js::jsapi::JSTracer;
|
||||
use js::jsapi::JS_GC;
|
||||
use js::jsapi::JS_GetGCParameter;
|
||||
use js::rust::Runtime;
|
||||
use msg::constellation_msg::PipelineId;
|
||||
use net_traits::IpcSend;
|
||||
use net_traits::load_whole_resource;
|
||||
|
@ -46,6 +45,7 @@ use net_traits::request::RequestInit;
|
|||
use net_traits::request::RequestMode;
|
||||
use net_traits::request::Type as RequestType;
|
||||
use script_runtime::CommonScriptMsg;
|
||||
use script_runtime::Runtime;
|
||||
use script_runtime::ScriptThreadEventCategory;
|
||||
use script_runtime::new_rt_and_cx;
|
||||
use script_thread::{MainThreadScriptMsg, ScriptThread};
|
||||
|
|
|
@ -20,7 +20,7 @@ use js::jsapi::{JSGCMode, JSGCParamKey, JS_SetGCParameter, JS_SetGlobalJitCompil
|
|||
use js::jsapi::{JSJitCompilerOption, JS_SetOffthreadIonCompilationEnabled, JS_SetParallelParsingEnabled};
|
||||
use js::jsapi::{JSObject, RuntimeOptionsRef, SetPreserveWrapperCallback, SetEnqueuePromiseJobCallback};
|
||||
use js::panic::wrap_panic;
|
||||
use js::rust::Runtime;
|
||||
use js::rust::Runtime as RustRuntime;
|
||||
use microtask::{EnqueuedPromiseCallback, Microtask};
|
||||
use profile_traits::mem::{Report, ReportKind, ReportsChan};
|
||||
use script_thread::trace_thread;
|
||||
|
@ -29,6 +29,7 @@ use servo_config::prefs::PREFS;
|
|||
use std::cell::Cell;
|
||||
use std::fmt;
|
||||
use std::io::{Write, stdout};
|
||||
use std::ops::Deref;
|
||||
use std::os;
|
||||
use std::os::raw::c_void;
|
||||
use std::panic::AssertUnwindSafe;
|
||||
|
@ -120,13 +121,28 @@ unsafe extern "C" fn enqueue_job(cx: *mut JSContext,
|
|||
}), false)
|
||||
}
|
||||
|
||||
#[derive(JSTraceable)]
|
||||
pub struct Runtime(RustRuntime);
|
||||
|
||||
impl Drop for Runtime {
|
||||
fn drop(&mut self) {
|
||||
THREAD_ACTIVE.with(|t| t.set(false));
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Runtime {
|
||||
type Target = RustRuntime;
|
||||
fn deref(&self) -> &RustRuntime {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
pub unsafe fn new_rt_and_cx() -> Runtime {
|
||||
LiveDOMReferences::initialize();
|
||||
let runtime = Runtime::new().unwrap();
|
||||
let runtime = RustRuntime::new().unwrap();
|
||||
|
||||
JS_AddExtraGCRootsTracer(runtime.rt(), Some(trace_rust_roots), ptr::null_mut());
|
||||
JS_AddExtraGCRootsTracer(runtime.rt(), Some(trace_refcounted_objects), ptr::null_mut());
|
||||
|
||||
// Needed for debug assertions about whether GC is running.
|
||||
if cfg!(debug_assertions) {
|
||||
|
@ -293,7 +309,7 @@ pub unsafe fn new_rt_and_cx() -> Runtime {
|
|||
}
|
||||
}
|
||||
|
||||
runtime
|
||||
Runtime(runtime)
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
|
@ -399,12 +415,20 @@ unsafe extern "C" fn debug_gc_callback(_rt: *mut JSRuntime, status: JSGCStatus,
|
|||
}
|
||||
}
|
||||
|
||||
thread_local!(
|
||||
static THREAD_ACTIVE: Cell<bool> = Cell::new(true);
|
||||
);
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
unsafe extern fn trace_rust_roots(tr: *mut JSTracer, _data: *mut os::raw::c_void) {
|
||||
if !THREAD_ACTIVE.with(|t| t.get()) {
|
||||
return;
|
||||
}
|
||||
debug!("starting custom root handler");
|
||||
trace_thread(tr);
|
||||
trace_traceables(tr);
|
||||
trace_roots(tr);
|
||||
trace_refcounted_objects(tr);
|
||||
settings_stack::trace(tr);
|
||||
debug!("done custom root handler");
|
||||
}
|
||||
|
|
|
@ -72,7 +72,6 @@ use js::glue::GetWindowProxyClass;
|
|||
use js::jsapi::{JSAutoCompartment, JSContext, JS_SetWrapObjectCallbacks};
|
||||
use js::jsapi::{JSTracer, SetWindowProxyClass};
|
||||
use js::jsval::UndefinedValue;
|
||||
use js::rust::Runtime;
|
||||
use malloc_size_of::MallocSizeOfOps;
|
||||
use mem::malloc_size_of_including_self;
|
||||
use metrics::PaintTimeMetrics;
|
||||
|
@ -87,7 +86,7 @@ use profile_traits::mem::{self, OpaqueSender, Report, ReportKind, ReportsChan};
|
|||
use profile_traits::time::{self, ProfilerCategory, profile};
|
||||
use script_layout_interface::message::{self, Msg, NewLayoutThreadInfo, ReflowGoal};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptThreadEventCategory};
|
||||
use script_runtime::{ScriptPort, get_reports, new_rt_and_cx};
|
||||
use script_runtime::{ScriptPort, get_reports, new_rt_and_cx, Runtime};
|
||||
use script_traits::{CompositorEvent, ConstellationControlMsg};
|
||||
use script_traits::{DiscardBrowsingContext, DocumentActivity, EventResult};
|
||||
use script_traits::{InitialScriptState, JsEvalResult, LayoutMsg, LoadData};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue