mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
refactors entities from script_thread into script_runtime
This commit is contained in:
parent
0d0e08638d
commit
2caa9a2a76
28 changed files with 298 additions and 261 deletions
|
@ -20,7 +20,7 @@ use hyper::mime::{Mime, SubLevel, TopLevel};
|
|||
use hyper::status::StatusClass::Success;
|
||||
use net_traits::{AsyncResponseListener, Metadata, ResponseAction};
|
||||
use network_listener::{NetworkListener, PreInvoke};
|
||||
use script_thread::ScriptChan;
|
||||
use script_runtime::ScriptChan;
|
||||
use std::ascii::AsciiExt;
|
||||
use std::borrow::ToOwned;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
|
|
@ -21,7 +21,8 @@ use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL};
|
|||
use msg::constellation_msg::{ConstellationChan, PipelineId};
|
||||
use net_traits::ResourceThread;
|
||||
use profile_traits::mem;
|
||||
use script_thread::{CommonScriptMsg, MainThreadScriptChan, ScriptChan, ScriptPort, ScriptThread};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort};
|
||||
use script_thread::{MainThreadScriptChan, ScriptThread};
|
||||
use script_traits::{MsDuration, ScriptMsg as ConstellationMsg, TimerEventRequest};
|
||||
use task_source::TaskSource;
|
||||
use task_source::dom_manipulation::DOMManipulationTask;
|
||||
|
|
|
@ -28,7 +28,7 @@ use dom::bindings::reflector::{Reflectable, Reflector};
|
|||
use dom::bindings::trace::trace_reflector;
|
||||
use js::jsapi::JSTracer;
|
||||
use libc;
|
||||
use script_thread::{CommonScriptMsg, ScriptChan};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan};
|
||||
use std::cell::RefCell;
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
use std::collections::hash_map::HashMap;
|
||||
|
|
|
@ -63,7 +63,7 @@ use net_traits::response::HttpsState;
|
|||
use net_traits::storage_thread::StorageType;
|
||||
use profile_traits::mem::ProfilerChan as MemProfilerChan;
|
||||
use profile_traits::time::ProfilerChan as TimeProfilerChan;
|
||||
use script_thread::ScriptChan;
|
||||
use script_runtime::ScriptChan;
|
||||
use script_traits::{LayoutMsg, ScriptMsg, TimerEventId, TimerSource, TouchpadPressurePhase, UntrustedNodeAddress};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use smallvec::SmallVec;
|
||||
|
|
|
@ -11,7 +11,7 @@ use dom::bindings::inheritance::Castable;
|
|||
use dom::bindings::js::Root;
|
||||
use dom::bindings::reflector::reflect_dom_object;
|
||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
||||
use script_thread::ScriptChan;
|
||||
use script_runtime::ScriptChan;
|
||||
use string_cache::Atom;
|
||||
use util::str::DOMString;
|
||||
|
||||
|
|
|
@ -28,8 +28,8 @@ use js::rust::Runtime;
|
|||
use msg::constellation_msg::PipelineId;
|
||||
use net_traits::{LoadContext, load_whole_resource};
|
||||
use rand::random;
|
||||
use script_thread::ScriptThreadEventCategory::WorkerEvent;
|
||||
use script_thread::{ScriptThread, ScriptChan, ScriptPort, StackRootTLS, CommonScriptMsg};
|
||||
use script_runtime::ScriptThreadEventCategory::WorkerEvent;
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, StackRootTLS, get_reports, new_rt_and_cx};
|
||||
use script_traits::{TimerEvent, TimerSource};
|
||||
use std::mem::replace;
|
||||
use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel};
|
||||
|
@ -236,7 +236,7 @@ impl DedicatedWorkerGlobalScope {
|
|||
}
|
||||
};
|
||||
|
||||
let runtime = ScriptThread::new_rt_and_cx();
|
||||
let runtime = new_rt_and_cx();
|
||||
|
||||
let (devtools_mpsc_chan, devtools_mpsc_port) = channel();
|
||||
ROUTER.route_ipc_receiver_to_mpsc_sender(from_devtools_receiver, devtools_mpsc_chan);
|
||||
|
@ -347,7 +347,7 @@ impl DedicatedWorkerGlobalScope {
|
|||
let scope = self.upcast::<WorkerGlobalScope>();
|
||||
let cx = scope.get_cx();
|
||||
let path_seg = format!("url({})", scope.get_url());
|
||||
let reports = ScriptThread::get_reports(cx, path_seg);
|
||||
let reports = get_reports(cx, path_seg);
|
||||
reports_chan.send(reports);
|
||||
},
|
||||
}
|
||||
|
|
|
@ -94,7 +94,8 @@ use net_traits::CookieSource::NonHTTP;
|
|||
use net_traits::response::HttpsState;
|
||||
use net_traits::{AsyncResponseTarget, PendingAsyncLoad};
|
||||
use num::ToPrimitive;
|
||||
use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, Runnable, ScriptChan};
|
||||
use script_runtime::ScriptChan;
|
||||
use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, Runnable};
|
||||
use script_traits::UntrustedNodeAddress;
|
||||
use script_traits::{AnimationState, MouseButton, MouseEventType, MozBrowserEvent};
|
||||
use script_traits::{ScriptMsg as ConstellationMsg, ScriptToCompositorMsg};
|
||||
|
|
|
@ -22,8 +22,9 @@ use encoding::label::encoding_from_whatwg_label;
|
|||
use encoding::types::{DecoderTrap, EncodingRef};
|
||||
use hyper::mime::{Attr, Mime};
|
||||
use rustc_serialize::base64::{CharacterSet, Config, Newline, ToBase64};
|
||||
use script_thread::ScriptThreadEventCategory::FileRead;
|
||||
use script_thread::{CommonScriptMsg, Runnable, ScriptChan};
|
||||
use script_runtime::ScriptThreadEventCategory::FileRead;
|
||||
use script_runtime::{ScriptChan, CommonScriptMsg};
|
||||
use script_thread::Runnable;
|
||||
use std::cell::Cell;
|
||||
use string_cache::Atom;
|
||||
use util::str::DOMString;
|
||||
|
|
|
@ -14,7 +14,8 @@ use dom::eventtarget::EventTarget;
|
|||
use dom::htmlelement::HTMLElement;
|
||||
use dom::node::{Node, window_from_node};
|
||||
use dom::virtualmethods::VirtualMethods;
|
||||
use script_thread::{MainThreadScriptChan, Runnable, ScriptChan};
|
||||
use script_runtime::ScriptChan;
|
||||
use script_thread::{MainThreadScriptChan, Runnable};
|
||||
use std::cell::Cell;
|
||||
use string_cache::Atom;
|
||||
use task_source::dom_manipulation::DOMManipulationTask;
|
||||
|
|
|
@ -37,7 +37,8 @@ use hyper::header::ContentType;
|
|||
use hyper::method::Method;
|
||||
use hyper::mime;
|
||||
use msg::constellation_msg::{LoadData, PipelineId};
|
||||
use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, Runnable, ScriptChan};
|
||||
use script_runtime::ScriptChan;
|
||||
use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, Runnable};
|
||||
use std::borrow::ToOwned;
|
||||
use std::cell::Cell;
|
||||
use std::sync::mpsc::Sender;
|
||||
|
|
|
@ -25,8 +25,9 @@ use ipc_channel::ipc;
|
|||
use ipc_channel::router::ROUTER;
|
||||
use net_traits::image::base::{Image, ImageMetadata};
|
||||
use net_traits::image_cache_thread::{ImageResponder, ImageResponse};
|
||||
use script_thread::ScriptThreadEventCategory::UpdateReplacedElement;
|
||||
use script_thread::{CommonScriptMsg, Runnable, ScriptChan};
|
||||
use script_runtime::ScriptThreadEventCategory::UpdateReplacedElement;
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan};
|
||||
use script_thread::Runnable;
|
||||
use std::sync::Arc;
|
||||
use string_cache::Atom;
|
||||
use url::Url;
|
||||
|
|
|
@ -32,8 +32,9 @@ use dom::validation::Validatable;
|
|||
use dom::virtualmethods::VirtualMethods;
|
||||
use msg::constellation_msg::ConstellationChan;
|
||||
use range::Range;
|
||||
use script_thread::ScriptThreadEventCategory::InputEvent;
|
||||
use script_thread::{CommonScriptMsg, Runnable};
|
||||
use script_runtime::CommonScriptMsg;
|
||||
use script_runtime::ScriptThreadEventCategory::InputEvent;
|
||||
use script_thread::Runnable;
|
||||
use script_traits::ScriptMsg as ConstellationMsg;
|
||||
use std::borrow::ToOwned;
|
||||
use std::cell::Cell;
|
||||
|
|
|
@ -34,7 +34,8 @@ use js::jsapi::RootedValue;
|
|||
use js::jsval::UndefinedValue;
|
||||
use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata};
|
||||
use network_listener::{NetworkListener, PreInvoke};
|
||||
use script_thread::{MainThreadScriptChan, ScriptChan};
|
||||
use script_runtime::ScriptChan;
|
||||
use script_thread::MainThreadScriptChan;
|
||||
use std::ascii::AsciiExt;
|
||||
use std::cell::Cell;
|
||||
use std::mem;
|
||||
|
|
|
@ -29,7 +29,8 @@ use msg::constellation_msg::{PipelineId, SubpageId};
|
|||
use net_traits::{AsyncResponseListener, Metadata};
|
||||
use network_listener::PreInvoke;
|
||||
use parse::Parser;
|
||||
use script_thread::{ScriptChan, ScriptThread};
|
||||
use script_runtime::ScriptChan;
|
||||
use script_thread::ScriptThread;
|
||||
use std::cell::Cell;
|
||||
use std::cell::UnsafeCell;
|
||||
use std::default::Default;
|
||||
|
|
|
@ -16,7 +16,8 @@ use dom::urlhelper::UrlHelper;
|
|||
use ipc_channel::ipc;
|
||||
use net_traits::storage_thread::{StorageThread, StorageThreadMsg, StorageType};
|
||||
use page::IterablePage;
|
||||
use script_thread::{MainThreadRunnable, MainThreadScriptChan, ScriptChan, ScriptThread};
|
||||
use script_runtime::ScriptChan;
|
||||
use script_thread::{MainThreadRunnable, MainThreadScriptChan, ScriptThread};
|
||||
use task_source::dom_manipulation::DOMManipulationTask;
|
||||
use url::Url;
|
||||
use util::str::DOMString;
|
||||
|
|
|
@ -35,8 +35,9 @@ use net_traits::MessageData;
|
|||
use net_traits::hosts::replace_hosts;
|
||||
use net_traits::unwrap_websocket_protocol;
|
||||
use net_traits::{WebSocketCommunicate, WebSocketConnectData, WebSocketDomAction, WebSocketNetworkEvent};
|
||||
use script_thread::ScriptThreadEventCategory::WebSocketEvent;
|
||||
use script_thread::{CommonScriptMsg, Runnable, ScriptChan};
|
||||
use script_runtime::ScriptThreadEventCategory::WebSocketEvent;
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan};
|
||||
use script_thread::Runnable;
|
||||
use std::ascii::AsciiExt;
|
||||
use std::borrow::ToOwned;
|
||||
use std::cell::Cell;
|
||||
|
|
|
@ -53,8 +53,9 @@ use page::Page;
|
|||
use profile_traits::mem;
|
||||
use reporter::CSSErrorReporter;
|
||||
use rustc_serialize::base64::{FromBase64, STANDARD, ToBase64};
|
||||
use script_runtime::{ScriptChan, ScriptPort};
|
||||
use script_thread::SendableMainThreadScriptChan;
|
||||
use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, RunnableWrapper};
|
||||
use script_thread::{SendableMainThreadScriptChan, ScriptChan, ScriptPort};
|
||||
use script_traits::{ConstellationControlMsg, UntrustedNodeAddress};
|
||||
use script_traits::{DocumentState, MsDuration, ScriptToCompositorMsg, TimerEvent, TimerEventId};
|
||||
use script_traits::{MozBrowserEvent, ScriptMsg as ConstellationMsg, TimerEventRequest, TimerSource};
|
||||
|
|
|
@ -24,7 +24,8 @@ use ipc_channel::ipc;
|
|||
use js::jsapi::{HandleValue, JSContext, RootedValue};
|
||||
use js::jsapi::{JSAutoCompartment, JSAutoRequest};
|
||||
use js::jsval::UndefinedValue;
|
||||
use script_thread::{Runnable, ScriptChan};
|
||||
use script_runtime::ScriptChan;
|
||||
use script_thread::Runnable;
|
||||
use std::sync::mpsc::{Sender, channel};
|
||||
use util::str::DOMString;
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ use js::rust::Runtime;
|
|||
use msg::constellation_msg::{ConstellationChan, PipelineId};
|
||||
use net_traits::{LoadContext, ResourceThread, load_whole_resource};
|
||||
use profile_traits::mem;
|
||||
use script_thread::{CommonScriptMsg, ScriptChan, ScriptPort};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort};
|
||||
use script_traits::ScriptMsg as ConstellationMsg;
|
||||
use script_traits::{MsDuration, TimerEvent, TimerEventId, TimerEventRequest, TimerSource};
|
||||
use std::cell::Cell;
|
||||
|
|
|
@ -50,7 +50,7 @@ use net_traits::{LoadConsumer, LoadContext, LoadData, ResourceCORSData, Resource
|
|||
use network_listener::{NetworkListener, PreInvoke};
|
||||
use parse::html::{ParseContext, parse_html};
|
||||
use parse::xml::{self, parse_xml};
|
||||
use script_thread::{ScriptChan, ScriptPort};
|
||||
use script_runtime::{ScriptChan, ScriptPort};
|
||||
use std::ascii::AsciiExt;
|
||||
use std::borrow::ToOwned;
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
|
|
@ -93,6 +93,7 @@ mod network_listener;
|
|||
pub mod page;
|
||||
pub mod parse;
|
||||
pub mod reporter;
|
||||
pub mod script_runtime;
|
||||
#[allow(unsafe_code)]
|
||||
pub mod script_thread;
|
||||
mod task_source;
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use net_traits::{AsyncResponseListener, ResponseAction};
|
||||
use script_thread::ScriptThreadEventCategory::NetworkEvent;
|
||||
use script_thread::{CommonScriptMsg, Runnable, ScriptChan};
|
||||
use script_runtime::ScriptThreadEventCategory::NetworkEvent;
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan};
|
||||
use script_thread::Runnable;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
/// An off-thread sink for async network event runnables. All such events are forwarded to
|
||||
|
|
235
components/script/script_runtime.rs
Normal file
235
components/script/script_runtime.rs
Normal file
|
@ -0,0 +1,235 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//! The script runtime contains common traits and structs commonly used by the
|
||||
//! script thread, the dom, and the worker threads.
|
||||
|
||||
use dom::bindings::js::{RootCollection, RootCollectionPtr, trace_roots};
|
||||
use dom::bindings::refcounted::{LiveDOMReferences, TrustedReference, trace_refcounted_objects};
|
||||
use dom::bindings::trace::trace_traceables;
|
||||
use dom::bindings::utils::DOM_CALLBACKS;
|
||||
use js::glue::CollectServoSizes;
|
||||
use js::jsapi::{DisableIncrementalGC, GCDescription, GCProgress};
|
||||
use js::jsapi::{JSContext, JS_GetRuntime, JSRuntime, JSTracer, SetDOMCallbacks, SetGCSliceCallback};
|
||||
use js::jsapi::{JSGCInvocationKind, JSGCStatus, JS_AddExtraGCRootsTracer, JS_SetGCCallback};
|
||||
use js::jsapi::{JSObject, SetPreserveWrapperCallback};
|
||||
use js::rust::Runtime;
|
||||
use libc;
|
||||
use profile_traits::mem::{Report, ReportKind, ReportsChan};
|
||||
use script_thread::{Runnable, STACK_ROOTS, trace_thread};
|
||||
use std::cell::Cell;
|
||||
use std::io::{Write, stdout};
|
||||
use std::marker::PhantomData;
|
||||
use std::ptr;
|
||||
use time::{Tm, now};
|
||||
use util::opts;
|
||||
use util::thread_state;
|
||||
|
||||
/// Common messages used to control the event loops in both the script and the worker
|
||||
pub enum CommonScriptMsg {
|
||||
/// Requests that the script thread measure its memory usage. The results are sent back via the
|
||||
/// supplied channel.
|
||||
CollectReports(ReportsChan),
|
||||
/// A DOM object's last pinned reference was removed (dispatched to all threads).
|
||||
RefcountCleanup(TrustedReference),
|
||||
/// Generic message that encapsulates event handling.
|
||||
RunnableMsg(ScriptThreadEventCategory, Box<Runnable + Send>),
|
||||
}
|
||||
|
||||
/// A cloneable interface for communicating with an event loop.
|
||||
pub trait ScriptChan {
|
||||
/// Send a message to the associated event loop.
|
||||
fn send(&self, msg: CommonScriptMsg) -> Result<(), ()>;
|
||||
/// Clone this handle.
|
||||
fn clone(&self) -> Box<ScriptChan + Send>;
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, JSTraceable, PartialEq)]
|
||||
pub enum ScriptThreadEventCategory {
|
||||
AttachLayout,
|
||||
ConstellationMsg,
|
||||
DevtoolsMsg,
|
||||
DocumentEvent,
|
||||
DomEvent,
|
||||
FileRead,
|
||||
FormPlannedNavigation,
|
||||
ImageCacheMsg,
|
||||
InputEvent,
|
||||
NetworkEvent,
|
||||
Resize,
|
||||
ScriptEvent,
|
||||
SetViewport,
|
||||
StylesheetLoad,
|
||||
TimerEvent,
|
||||
UpdateReplacedElement,
|
||||
WebSocketEvent,
|
||||
WorkerEvent,
|
||||
}
|
||||
|
||||
/// An interface for receiving ScriptMsg values in an event loop. Used for synchronous DOM
|
||||
/// APIs that need to abstract over multiple kinds of event loops (worker/main thread) with
|
||||
/// different Receiver interfaces.
|
||||
pub trait ScriptPort {
|
||||
fn recv(&self) -> Result<CommonScriptMsg, ()>;
|
||||
}
|
||||
|
||||
pub struct StackRootTLS<'a>(PhantomData<&'a u32>);
|
||||
|
||||
impl<'a> StackRootTLS<'a> {
|
||||
pub fn new(roots: &'a RootCollection) -> StackRootTLS<'a> {
|
||||
STACK_ROOTS.with(|ref r| {
|
||||
r.set(Some(RootCollectionPtr(roots as *const _)))
|
||||
});
|
||||
StackRootTLS(PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for StackRootTLS<'a> {
|
||||
fn drop(&mut self) {
|
||||
STACK_ROOTS.with(|ref r| r.set(None));
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
pub fn new_rt_and_cx() -> Runtime {
|
||||
LiveDOMReferences::initialize();
|
||||
let runtime = Runtime::new();
|
||||
|
||||
unsafe {
|
||||
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) {
|
||||
unsafe {
|
||||
JS_SetGCCallback(runtime.rt(), Some(debug_gc_callback), ptr::null_mut());
|
||||
}
|
||||
}
|
||||
if opts::get().gc_profile {
|
||||
unsafe {
|
||||
SetGCSliceCallback(runtime.rt(), Some(gc_slice_callback));
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
unsafe extern "C" fn empty_wrapper_callback(_: *mut JSContext, _: *mut JSObject) -> bool { true }
|
||||
SetDOMCallbacks(runtime.rt(), &DOM_CALLBACKS);
|
||||
SetPreserveWrapperCallback(runtime.rt(), Some(empty_wrapper_callback));
|
||||
// Pre barriers aren't working correctly at the moment
|
||||
DisableIncrementalGC(runtime.rt());
|
||||
}
|
||||
|
||||
runtime
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
pub fn get_reports(cx: *mut JSContext, path_seg: String) -> Vec<Report> {
|
||||
let mut reports = vec![];
|
||||
|
||||
unsafe {
|
||||
let rt = JS_GetRuntime(cx);
|
||||
let mut stats = ::std::mem::zeroed();
|
||||
if CollectServoSizes(rt, &mut stats) {
|
||||
let mut report = |mut path_suffix, kind, size| {
|
||||
let mut path = path![path_seg, "js"];
|
||||
path.append(&mut path_suffix);
|
||||
reports.push(Report {
|
||||
path: path,
|
||||
kind: kind,
|
||||
size: size as usize,
|
||||
})
|
||||
};
|
||||
|
||||
// A note about possibly confusing terminology: the JS GC "heap" is allocated via
|
||||
// mmap/VirtualAlloc, which means it's not on the malloc "heap", so we use
|
||||
// `ExplicitNonHeapSize` as its kind.
|
||||
|
||||
report(path!["gc-heap", "used"],
|
||||
ReportKind::ExplicitNonHeapSize,
|
||||
stats.gcHeapUsed);
|
||||
|
||||
report(path!["gc-heap", "unused"],
|
||||
ReportKind::ExplicitNonHeapSize,
|
||||
stats.gcHeapUnused);
|
||||
|
||||
report(path!["gc-heap", "admin"],
|
||||
ReportKind::ExplicitNonHeapSize,
|
||||
stats.gcHeapAdmin);
|
||||
|
||||
report(path!["gc-heap", "decommitted"],
|
||||
ReportKind::ExplicitNonHeapSize,
|
||||
stats.gcHeapDecommitted);
|
||||
|
||||
// SpiderMonkey uses the system heap, not jemalloc.
|
||||
report(path!["malloc-heap"],
|
||||
ReportKind::ExplicitSystemHeapSize,
|
||||
stats.mallocHeap);
|
||||
|
||||
report(path!["non-heap"],
|
||||
ReportKind::ExplicitNonHeapSize,
|
||||
stats.nonHeap);
|
||||
}
|
||||
}
|
||||
reports
|
||||
}
|
||||
|
||||
thread_local!(static GC_CYCLE_START: Cell<Option<Tm>> = Cell::new(None));
|
||||
thread_local!(static GC_SLICE_START: Cell<Option<Tm>> = Cell::new(None));
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
unsafe extern "C" fn gc_slice_callback(_rt: *mut JSRuntime, progress: GCProgress, desc: *const GCDescription) {
|
||||
match progress {
|
||||
GCProgress::GC_CYCLE_BEGIN => {
|
||||
GC_CYCLE_START.with(|start| {
|
||||
start.set(Some(now()));
|
||||
println!("GC cycle began");
|
||||
})
|
||||
},
|
||||
GCProgress::GC_SLICE_BEGIN => {
|
||||
GC_SLICE_START.with(|start| {
|
||||
start.set(Some(now()));
|
||||
println!("GC slice began");
|
||||
})
|
||||
},
|
||||
GCProgress::GC_SLICE_END => {
|
||||
GC_SLICE_START.with(|start| {
|
||||
let dur = now() - start.get().unwrap();
|
||||
start.set(None);
|
||||
println!("GC slice ended: duration={}", dur);
|
||||
})
|
||||
},
|
||||
GCProgress::GC_CYCLE_END => {
|
||||
GC_CYCLE_START.with(|start| {
|
||||
let dur = now() - start.get().unwrap();
|
||||
start.set(None);
|
||||
println!("GC cycle ended: duration={}", dur);
|
||||
})
|
||||
},
|
||||
};
|
||||
if !desc.is_null() {
|
||||
let desc: &GCDescription = &*desc;
|
||||
let invocationKind = match desc.invocationKind_ {
|
||||
JSGCInvocationKind::GC_NORMAL => "GC_NORMAL",
|
||||
JSGCInvocationKind::GC_SHRINK => "GC_SHRINK",
|
||||
};
|
||||
println!(" isCompartment={}, invocationKind={}", desc.isCompartment_, invocationKind);
|
||||
}
|
||||
let _ = stdout().flush();
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
unsafe extern "C" fn debug_gc_callback(_rt: *mut JSRuntime, status: JSGCStatus, _data: *mut libc::c_void) {
|
||||
match status {
|
||||
JSGCStatus::JSGC_BEGIN => thread_state::enter(thread_state::IN_GC),
|
||||
JSGCStatus::JSGC_END => thread_state::exit(thread_state::IN_GC),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
unsafe extern fn trace_rust_roots(tr: *mut JSTracer, _data: *mut libc::c_void) {
|
||||
trace_thread(tr);
|
||||
trace_traceables(tr);
|
||||
trace_roots(tr);
|
||||
}
|
|
@ -27,11 +27,11 @@ use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, Documen
|
|||
use dom::bindings::conversions::{FromJSValConvertible, StringificationBehavior};
|
||||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::inheritance::Castable;
|
||||
use dom::bindings::js::{JS, MutNullableHeap, Root, RootCollection, trace_roots};
|
||||
use dom::bindings::js::{JS, MutNullableHeap, Root, RootCollection};
|
||||
use dom::bindings::js::{RootCollectionPtr, RootedReference};
|
||||
use dom::bindings::refcounted::{LiveDOMReferences, Trusted, TrustedReference, trace_refcounted_objects};
|
||||
use dom::bindings::trace::{JSTraceable, trace_traceables};
|
||||
use dom::bindings::utils::{DOM_CALLBACKS, WRAP_CALLBACKS};
|
||||
use dom::bindings::refcounted::{LiveDOMReferences, Trusted};
|
||||
use dom::bindings::trace::JSTraceable;
|
||||
use dom::bindings::utils::WRAP_CALLBACKS;
|
||||
use dom::browsingcontext::BrowsingContext;
|
||||
use dom::document::{Document, DocumentProgressHandler, DocumentSource, FocusType, IsHTMLDocument};
|
||||
use dom::element::Element;
|
||||
|
@ -51,18 +51,12 @@ use hyper::method::Method;
|
|||
use hyper::mime::{Mime, SubLevel, TopLevel};
|
||||
use ipc_channel::ipc::{self, IpcSender};
|
||||
use ipc_channel::router::ROUTER;
|
||||
use js::glue::CollectServoSizes;
|
||||
use js::jsapi::{DOMProxyShadowsResult, HandleId, HandleObject, RootedValue};
|
||||
use js::jsapi::{DisableIncrementalGC, JS_AddExtraGCRootsTracer, JS_SetWrapObjectCallbacks};
|
||||
use js::jsapi::{GCDescription, GCProgress, JSGCInvocationKind, SetGCSliceCallback};
|
||||
use js::jsapi::{JSAutoRequest, JSGCStatus, JS_GetRuntime, JS_SetGCCallback, SetDOMCallbacks};
|
||||
use js::jsapi::{JSContext, JSRuntime, JSTracer};
|
||||
use js::jsapi::{JSObject, RuntimeOptionsRef, SetPreserveWrapperCallback};
|
||||
use js::jsapi::{JSAutoRequest, JSContext, JS_SetWrapObjectCallbacks, JSTracer};
|
||||
use js::jsval::UndefinedValue;
|
||||
use js::rust::Runtime;
|
||||
use layout_interface::{ReflowQueryType};
|
||||
use layout_interface::{self, LayoutChan, NewLayoutThreadInfo, ScriptLayoutChan};
|
||||
use libc;
|
||||
use mem::heap_size_of_self_and_children;
|
||||
use msg::constellation_msg::{ConstellationChan, LoadData};
|
||||
use msg::constellation_msg::{PipelineId, PipelineNamespace};
|
||||
|
@ -78,6 +72,8 @@ use parse::html::{ParseContext, parse_html};
|
|||
use parse::xml::{self, parse_xml};
|
||||
use profile_traits::mem::{self, OpaqueSender, Report, ReportKind, ReportsChan};
|
||||
use profile_traits::time::{self, ProfilerCategory, profile};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptThreadEventCategory};
|
||||
use script_runtime::{ScriptPort, StackRootTLS, new_rt_and_cx, get_reports};
|
||||
use script_traits::CompositorEvent::{KeyEvent, MouseButtonEvent, MouseMoveEvent, ResizeEvent};
|
||||
use script_traits::CompositorEvent::{TouchEvent, TouchpadPressureEvent};
|
||||
use script_traits::{CompositorEvent, ConstellationControlMsg, EventResult};
|
||||
|
@ -89,10 +85,7 @@ use std::any::Any;
|
|||
use std::borrow::ToOwned;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::HashSet;
|
||||
use std::io::{Write, stdout};
|
||||
use std::marker::PhantomData;
|
||||
use std::option::Option;
|
||||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
use std::result::Result;
|
||||
use std::sync::atomic::{Ordering, AtomicBool};
|
||||
|
@ -105,7 +98,7 @@ use task_source::file_reading::FileReadingTaskSource;
|
|||
use task_source::history_traversal::HistoryTraversalTaskSource;
|
||||
use task_source::networking::NetworkingTaskSource;
|
||||
use task_source::user_interaction::UserInteractionTaskSource;
|
||||
use time::{Tm, now};
|
||||
use time::Tm;
|
||||
use url::Url;
|
||||
use util::opts;
|
||||
use util::prefs::get_pref;
|
||||
|
@ -117,15 +110,12 @@ use webdriver_handlers;
|
|||
thread_local!(pub static STACK_ROOTS: Cell<Option<RootCollectionPtr>> = Cell::new(None));
|
||||
thread_local!(static SCRIPT_THREAD_ROOT: RefCell<Option<*const ScriptThread>> = RefCell::new(None));
|
||||
|
||||
unsafe extern fn trace_rust_roots(tr: *mut JSTracer, _data: *mut libc::c_void) {
|
||||
pub unsafe fn trace_thread(tr: *mut JSTracer) {
|
||||
SCRIPT_THREAD_ROOT.with(|root| {
|
||||
if let Some(script_thread) = *root.borrow() {
|
||||
(*script_thread).trace(tr);
|
||||
}
|
||||
});
|
||||
|
||||
trace_traceables(tr);
|
||||
trace_roots(tr);
|
||||
}
|
||||
|
||||
/// A document load that is in the process of fetching the requested resource. Contains
|
||||
|
@ -216,39 +206,6 @@ enum MixedMessage {
|
|||
FromScheduler(TimerEvent),
|
||||
}
|
||||
|
||||
/// Common messages used to control the event loops in both the script and the worker
|
||||
pub enum CommonScriptMsg {
|
||||
/// Requests that the script thread measure its memory usage. The results are sent back via the
|
||||
/// supplied channel.
|
||||
CollectReports(ReportsChan),
|
||||
/// A DOM object's last pinned reference was removed (dispatched to all threads).
|
||||
RefcountCleanup(TrustedReference),
|
||||
/// Generic message that encapsulates event handling.
|
||||
RunnableMsg(ScriptThreadEventCategory, Box<Runnable + Send>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, JSTraceable, PartialEq)]
|
||||
pub enum ScriptThreadEventCategory {
|
||||
AttachLayout,
|
||||
ConstellationMsg,
|
||||
DevtoolsMsg,
|
||||
DocumentEvent,
|
||||
DomEvent,
|
||||
FileRead,
|
||||
FormPlannedNavigation,
|
||||
ImageCacheMsg,
|
||||
InputEvent,
|
||||
NetworkEvent,
|
||||
Resize,
|
||||
ScriptEvent,
|
||||
SetViewport,
|
||||
StylesheetLoad,
|
||||
TimerEvent,
|
||||
UpdateReplacedElement,
|
||||
WebSocketEvent,
|
||||
WorkerEvent,
|
||||
}
|
||||
|
||||
/// Messages used to control the script event loop
|
||||
pub enum MainThreadScriptMsg {
|
||||
/// Common variants associated with the script messages
|
||||
|
@ -265,27 +222,12 @@ pub enum MainThreadScriptMsg {
|
|||
DOMManipulation(DOMManipulationTask),
|
||||
}
|
||||
|
||||
/// A cloneable interface for communicating with an event loop.
|
||||
pub trait ScriptChan {
|
||||
/// Send a message to the associated event loop.
|
||||
fn send(&self, msg: CommonScriptMsg) -> Result<(), ()>;
|
||||
/// Clone this handle.
|
||||
fn clone(&self) -> Box<ScriptChan + Send>;
|
||||
}
|
||||
|
||||
impl OpaqueSender<CommonScriptMsg> for Box<ScriptChan + Send> {
|
||||
fn send(&self, msg: CommonScriptMsg) {
|
||||
ScriptChan::send(&**self, msg).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
/// An interface for receiving ScriptMsg values in an event loop. Used for synchronous DOM
|
||||
/// APIs that need to abstract over multiple kinds of event loops (worker/main thread) with
|
||||
/// different Receiver interfaces.
|
||||
pub trait ScriptPort {
|
||||
fn recv(&self) -> Result<CommonScriptMsg, ()>;
|
||||
}
|
||||
|
||||
impl ScriptPort for Receiver<CommonScriptMsg> {
|
||||
fn recv(&self) -> Result<CommonScriptMsg, ()> {
|
||||
self.recv().map_err(|_| ())
|
||||
|
@ -362,24 +304,6 @@ impl MainThreadScriptChan {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct StackRootTLS<'a>(PhantomData<&'a u32>);
|
||||
|
||||
impl<'a> StackRootTLS<'a> {
|
||||
pub fn new(roots: &'a RootCollection) -> StackRootTLS<'a> {
|
||||
STACK_ROOTS.with(|ref r| {
|
||||
r.set(Some(RootCollectionPtr(roots as *const _)))
|
||||
});
|
||||
StackRootTLS(PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for StackRootTLS<'a> {
|
||||
fn drop(&mut self) {
|
||||
STACK_ROOTS.with(|ref r| r.set(None));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Information for an entire page. Pages are top-level browsing contexts and can contain multiple
|
||||
/// frames.
|
||||
#[derive(JSTraceable)]
|
||||
|
@ -561,56 +485,6 @@ impl ScriptThreadFactory for ScriptThread {
|
|||
}
|
||||
}
|
||||
|
||||
thread_local!(static GC_CYCLE_START: Cell<Option<Tm>> = Cell::new(None));
|
||||
thread_local!(static GC_SLICE_START: Cell<Option<Tm>> = Cell::new(None));
|
||||
|
||||
unsafe extern "C" fn gc_slice_callback(_rt: *mut JSRuntime, progress: GCProgress, desc: *const GCDescription) {
|
||||
match progress {
|
||||
GCProgress::GC_CYCLE_BEGIN => {
|
||||
GC_CYCLE_START.with(|start| {
|
||||
start.set(Some(now()));
|
||||
println!("GC cycle began");
|
||||
})
|
||||
},
|
||||
GCProgress::GC_SLICE_BEGIN => {
|
||||
GC_SLICE_START.with(|start| {
|
||||
start.set(Some(now()));
|
||||
println!("GC slice began");
|
||||
})
|
||||
},
|
||||
GCProgress::GC_SLICE_END => {
|
||||
GC_SLICE_START.with(|start| {
|
||||
let dur = now() - start.get().unwrap();
|
||||
start.set(None);
|
||||
println!("GC slice ended: duration={}", dur);
|
||||
})
|
||||
},
|
||||
GCProgress::GC_CYCLE_END => {
|
||||
GC_CYCLE_START.with(|start| {
|
||||
let dur = now() - start.get().unwrap();
|
||||
start.set(None);
|
||||
println!("GC cycle ended: duration={}", dur);
|
||||
})
|
||||
},
|
||||
};
|
||||
if !desc.is_null() {
|
||||
let desc: &GCDescription = &*desc;
|
||||
let invocationKind = match desc.invocationKind_ {
|
||||
JSGCInvocationKind::GC_NORMAL => "GC_NORMAL",
|
||||
JSGCInvocationKind::GC_SHRINK => "GC_SHRINK",
|
||||
};
|
||||
println!(" isCompartment={}, invocationKind={}", desc.isCompartment_, invocationKind);
|
||||
}
|
||||
let _ = stdout().flush();
|
||||
}
|
||||
|
||||
unsafe extern "C" fn debug_gc_callback(_rt: *mut JSRuntime, status: JSGCStatus, _data: *mut libc::c_void) {
|
||||
match status {
|
||||
JSGCStatus::JSGC_BEGIN => thread_state::enter(thread_state::IN_GC),
|
||||
JSGCStatus::JSGC_END => thread_state::exit(thread_state::IN_GC),
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe extern "C" fn shadow_check_callback(_cx: *mut JSContext,
|
||||
_object: HandleObject, _id: HandleId) -> DOMProxyShadowsResult {
|
||||
// XXX implement me
|
||||
|
@ -647,7 +521,7 @@ impl ScriptThread {
|
|||
port: Receiver<MainThreadScriptMsg>,
|
||||
chan: Sender<MainThreadScriptMsg>)
|
||||
-> ScriptThread {
|
||||
let runtime = ScriptThread::new_rt_and_cx();
|
||||
let runtime = new_rt_and_cx();
|
||||
|
||||
unsafe {
|
||||
JS_SetWrapObjectCallbacks(runtime.rt(),
|
||||
|
@ -711,47 +585,6 @@ impl ScriptThread {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new_rt_and_cx() -> Runtime {
|
||||
LiveDOMReferences::initialize();
|
||||
let runtime = Runtime::new();
|
||||
|
||||
unsafe {
|
||||
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) {
|
||||
unsafe {
|
||||
JS_SetGCCallback(runtime.rt(), Some(debug_gc_callback), ptr::null_mut());
|
||||
}
|
||||
}
|
||||
if opts::get().gc_profile {
|
||||
unsafe {
|
||||
SetGCSliceCallback(runtime.rt(), Some(gc_slice_callback));
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
unsafe extern "C" fn empty_wrapper_callback(_: *mut JSContext, _: *mut JSObject) -> bool { true }
|
||||
SetDOMCallbacks(runtime.rt(), &DOM_CALLBACKS);
|
||||
SetPreserveWrapperCallback(runtime.rt(), Some(empty_wrapper_callback));
|
||||
// Pre barriers aren't working correctly at the moment
|
||||
DisableIncrementalGC(runtime.rt());
|
||||
}
|
||||
|
||||
// Enable or disable the JITs.
|
||||
let rt_opts = unsafe { &mut *RuntimeOptionsRef(runtime.rt()) };
|
||||
if let Some(val) = get_pref("js.baseline.enabled").as_boolean() {
|
||||
rt_opts.set_baseline_(val);
|
||||
}
|
||||
if let Some(val) = get_pref("js.ion.enabled").as_boolean() {
|
||||
rt_opts.set_ion_(val);
|
||||
}
|
||||
|
||||
runtime
|
||||
}
|
||||
|
||||
// Return the root page in the frame tree. Panics if it doesn't exist.
|
||||
pub fn root_page(&self) -> Rc<Page> {
|
||||
self.page.borrow().as_ref().unwrap().clone()
|
||||
|
@ -1292,56 +1125,6 @@ impl ScriptThread {
|
|||
chan.send(ConstellationMsg::LoadComplete(pipeline)).unwrap();
|
||||
}
|
||||
|
||||
pub fn get_reports(cx: *mut JSContext, path_seg: String) -> Vec<Report> {
|
||||
let mut reports = vec![];
|
||||
|
||||
unsafe {
|
||||
let rt = JS_GetRuntime(cx);
|
||||
let mut stats = ::std::mem::zeroed();
|
||||
if CollectServoSizes(rt, &mut stats) {
|
||||
let mut report = |mut path_suffix, kind, size| {
|
||||
let mut path = path![path_seg, "js"];
|
||||
path.append(&mut path_suffix);
|
||||
reports.push(Report {
|
||||
path: path,
|
||||
kind: kind,
|
||||
size: size as usize,
|
||||
})
|
||||
};
|
||||
|
||||
// A note about possibly confusing terminology: the JS GC "heap" is allocated via
|
||||
// mmap/VirtualAlloc, which means it's not on the malloc "heap", so we use
|
||||
// `ExplicitNonHeapSize` as its kind.
|
||||
|
||||
report(path!["gc-heap", "used"],
|
||||
ReportKind::ExplicitNonHeapSize,
|
||||
stats.gcHeapUsed);
|
||||
|
||||
report(path!["gc-heap", "unused"],
|
||||
ReportKind::ExplicitNonHeapSize,
|
||||
stats.gcHeapUnused);
|
||||
|
||||
report(path!["gc-heap", "admin"],
|
||||
ReportKind::ExplicitNonHeapSize,
|
||||
stats.gcHeapAdmin);
|
||||
|
||||
report(path!["gc-heap", "decommitted"],
|
||||
ReportKind::ExplicitNonHeapSize,
|
||||
stats.gcHeapDecommitted);
|
||||
|
||||
// SpiderMonkey uses the system heap, not jemalloc.
|
||||
report(path!["malloc-heap"],
|
||||
ReportKind::ExplicitSystemHeapSize,
|
||||
stats.mallocHeap);
|
||||
|
||||
report(path!["non-heap"],
|
||||
ReportKind::ExplicitNonHeapSize,
|
||||
stats.nonHeap);
|
||||
}
|
||||
}
|
||||
reports
|
||||
}
|
||||
|
||||
fn collect_reports(&self, reports_chan: ReportsChan) {
|
||||
let mut urls = vec![];
|
||||
let mut dom_tree_size = 0;
|
||||
|
@ -1366,7 +1149,7 @@ impl ScriptThread {
|
|||
}
|
||||
}
|
||||
let path_seg = format!("url({})", urls.join(", "));
|
||||
reports.extend(ScriptThread::get_reports(self.get_cx(), path_seg));
|
||||
reports.extend(get_reports(self.get_cx(), path_seg));
|
||||
reports_chan.send(reports);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use script_thread::{CommonScriptMsg, MainThreadScriptMsg, ScriptChan};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan};
|
||||
use script_thread::MainThreadScriptMsg;
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
#[derive(JSTraceable)]
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use script_thread::{CommonScriptMsg, MainThreadScriptMsg, ScriptChan};
|
||||
use script_runtime::{ScriptChan, CommonScriptMsg};
|
||||
use script_thread::MainThreadScriptMsg;
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
#[derive(JSTraceable)]
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use script_thread::{CommonScriptMsg, MainThreadScriptMsg, ScriptChan};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan};
|
||||
use script_thread::MainThreadScriptMsg;
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
#[derive(JSTraceable)]
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use script_thread::{CommonScriptMsg, MainThreadScriptMsg, ScriptChan};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan};
|
||||
use script_thread::MainThreadScriptMsg;
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
#[derive(JSTraceable)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue