aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/script_runtime.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/script_runtime.rs')
-rw-r--r--components/script/script_runtime.rs270
1 files changed, 166 insertions, 104 deletions
diff --git a/components/script/script_runtime.rs b/components/script/script_runtime.rs
index 6758e3bd852..18138dcc2b0 100644
--- a/components/script/script_runtime.rs
+++ b/components/script/script_runtime.rs
@@ -52,7 +52,12 @@ pub enum CommonScriptMsg {
/// supplied channel.
CollectReports(ReportsChan),
/// Generic message that encapsulates event handling.
- Task(ScriptThreadEventCategory, Box<TaskBox>, Option<PipelineId>, TaskSourceName),
+ Task(
+ ScriptThreadEventCategory,
+ Box<TaskBox>,
+ Option<PipelineId>,
+ TaskSourceName,
+ ),
}
impl fmt::Debug for CommonScriptMsg {
@@ -113,21 +118,26 @@ pub trait ScriptPort {
/// SM callback for promise job resolution. Adds a promise callback to the current
/// global's microtask queue.
#[allow(unsafe_code)]
-unsafe extern "C" fn enqueue_job(cx: *mut JSContext,
- job: HandleObject,
- _allocation_site: HandleObject,
- _incumbent_global: HandleObject,
- _data: *mut c_void) -> bool {
- wrap_panic(AssertUnwindSafe(|| {
- //XXXjdm - use a different global now?
- let global = GlobalScope::from_object(job.get());
- let pipeline = global.pipeline_id();
- global.enqueue_microtask(Microtask::Promise(EnqueuedPromiseCallback {
- callback: PromiseJobCallback::new(cx, job.get()),
- pipeline: pipeline,
- }));
- true
- }), false)
+unsafe extern "C" fn enqueue_job(
+ cx: *mut JSContext,
+ job: HandleObject,
+ _allocation_site: HandleObject,
+ _incumbent_global: HandleObject,
+ _data: *mut c_void,
+) -> bool {
+ wrap_panic(
+ AssertUnwindSafe(|| {
+ //XXXjdm - use a different global now?
+ let global = GlobalScope::from_object(job.get());
+ let pipeline = global.pipeline_id();
+ global.enqueue_microtask(Microtask::Promise(EnqueuedPromiseCallback {
+ callback: PromiseJobCallback::new(cx, job.get()),
+ pipeline: pipeline,
+ }));
+ true
+ }),
+ false,
+ )
}
#[derive(JSTraceable)]
@@ -163,7 +173,9 @@ pub unsafe fn new_rt_and_cx() -> Runtime {
SetGCSliceCallback(cx, Some(gc_slice_callback));
}
- unsafe extern "C" fn empty_wrapper_callback(_: *mut JSContext, _: *mut JSObject) -> bool { true }
+ unsafe extern "C" fn empty_wrapper_callback(_: *mut JSContext, _: *mut JSObject) -> bool {
+ true
+ }
SetDOMCallbacks(cx, &DOM_CALLBACKS);
SetPreserveWrapperCallback(cx, Some(empty_wrapper_callback));
// Pre barriers aren't working correctly at the moment
@@ -213,25 +225,27 @@ pub unsafe fn new_rt_and_cx() -> Runtime {
if let Some(val) = PREFS.get("js.offthread_compilation_enabled").as_boolean() {
JS_SetOffthreadIonCompilationEnabled(cx, val);
}
- if let Some(val) = PREFS.get("js.baseline.unsafe_eager_compilation.enabled").as_boolean() {
- let trigger: i32 = if val {
- 0
- } else {
- -1
- };
- JS_SetGlobalJitCompilerOption(cx,
- JSJitCompilerOption::JSJITCOMPILER_BASELINE_WARMUP_TRIGGER,
- trigger as u32);
- }
- if let Some(val) = PREFS.get("js.ion.unsafe_eager_compilation.enabled").as_boolean() {
- let trigger: i64 = if val {
- 0
- } else {
- -1
- };
- JS_SetGlobalJitCompilerOption(cx,
- JSJitCompilerOption::JSJITCOMPILER_ION_WARMUP_TRIGGER,
- trigger as u32);
+ if let Some(val) = PREFS
+ .get("js.baseline.unsafe_eager_compilation.enabled")
+ .as_boolean()
+ {
+ let trigger: i32 = if val { 0 } else { -1 };
+ JS_SetGlobalJitCompilerOption(
+ cx,
+ JSJitCompilerOption::JSJITCOMPILER_BASELINE_WARMUP_TRIGGER,
+ trigger as u32,
+ );
+ }
+ if let Some(val) = PREFS
+ .get("js.ion.unsafe_eager_compilation.enabled")
+ .as_boolean()
+ {
+ let trigger: i64 = if val { 0 } else { -1 };
+ JS_SetGlobalJitCompilerOption(
+ cx,
+ JSJitCompilerOption::JSJITCOMPILER_ION_WARMUP_TRIGGER,
+ trigger as u32,
+ );
}
// TODO: handle js.discard_system_source.enabled
// TODO: handle js.asyncstack.enabled (needs new Spidermonkey)
@@ -242,7 +256,11 @@ pub unsafe fn new_rt_and_cx() -> Runtime {
}
// TODO: handle js.shared_memory.enabled
if let Some(val) = PREFS.get("js.mem.high_water_mark").as_i64() {
- JS_SetGCParameter(cx, JSGCParamKey::JSGC_MAX_MALLOC_BYTES, val as u32 * 1024 * 1024);
+ JS_SetGCParameter(
+ cx,
+ JSGCParamKey::JSGC_MAX_MALLOC_BYTES,
+ val as u32 * 1024 * 1024,
+ );
}
if let Some(val) = PREFS.get("js.mem.max").as_i64() {
let max = if val <= 0 || val >= 0x1000 {
@@ -281,10 +299,16 @@ pub unsafe fn new_rt_and_cx() -> Runtime {
JS_SetGCParameter(cx, JSGCParamKey::JSGC_HIGH_FREQUENCY_TIME_LIMIT, val as u32);
}
}
- if let Some(val) = PREFS.get("js.mem.gc.dynamic_mark_slice.enabled").as_boolean() {
+ if let Some(val) = PREFS
+ .get("js.mem.gc.dynamic_mark_slice.enabled")
+ .as_boolean()
+ {
JS_SetGCParameter(cx, JSGCParamKey::JSGC_DYNAMIC_MARK_SLICE, val as u32);
}
- if let Some(val) = PREFS.get("js.mem.gc.dynamic_heap_growth.enabled").as_boolean() {
+ if let Some(val) = PREFS
+ .get("js.mem.gc.dynamic_heap_growth.enabled")
+ .as_boolean()
+ {
JS_SetGCParameter(cx, JSGCParamKey::JSGC_DYNAMIC_HEAP_GROWTH, val as u32);
}
if let Some(val) = PREFS.get("js.mem.gc.low_frequency_heap_growth").as_i64() {
@@ -292,14 +316,28 @@ pub unsafe fn new_rt_and_cx() -> Runtime {
JS_SetGCParameter(cx, JSGCParamKey::JSGC_LOW_FREQUENCY_HEAP_GROWTH, val as u32);
}
}
- if let Some(val) = PREFS.get("js.mem.gc.high_frequency_heap_growth_min").as_i64() {
+ if let Some(val) = PREFS
+ .get("js.mem.gc.high_frequency_heap_growth_min")
+ .as_i64()
+ {
if val >= 0 && val < 10000 {
- JS_SetGCParameter(cx, JSGCParamKey::JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN, val as u32);
+ JS_SetGCParameter(
+ cx,
+ JSGCParamKey::JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN,
+ val as u32,
+ );
}
}
- if let Some(val) = PREFS.get("js.mem.gc.high_frequency_heap_growth_max").as_i64() {
+ if let Some(val) = PREFS
+ .get("js.mem.gc.high_frequency_heap_growth_max")
+ .as_i64()
+ {
if val >= 0 && val < 10000 {
- JS_SetGCParameter(cx, JSGCParamKey::JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX, val as u32);
+ JS_SetGCParameter(
+ cx,
+ JSGCParamKey::JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX,
+ val as u32,
+ );
}
}
if let Some(val) = PREFS.get("js.mem.gc.high_frequency_low_limit_mb").as_i64() {
@@ -314,12 +352,23 @@ pub unsafe fn new_rt_and_cx() -> Runtime {
}
if let Some(val) = PREFS.get("js.mem.gc.allocation_threshold_factor").as_i64() {
if val >= 0 && val < 10000 {
- JS_SetGCParameter(cx, JSGCParamKey::JSGC_ALLOCATION_THRESHOLD_FACTOR, val as u32);
+ JS_SetGCParameter(
+ cx,
+ JSGCParamKey::JSGC_ALLOCATION_THRESHOLD_FACTOR,
+ val as u32,
+ );
}
}
- if let Some(val) = PREFS.get("js.mem.gc.allocation_threshold_avoid_interrupt_factor").as_i64() {
+ if let Some(val) = PREFS
+ .get("js.mem.gc.allocation_threshold_avoid_interrupt_factor")
+ .as_i64()
+ {
if val >= 0 && val < 10000 {
- JS_SetGCParameter(cx, JSGCParamKey::JSGC_ALLOCATION_THRESHOLD_FACTOR_AVOID_INTERRUPT, val as u32);
+ JS_SetGCParameter(
+ cx,
+ JSGCParamKey::JSGC_ALLOCATION_THRESHOLD_FACTOR_AVOID_INTERRUPT,
+ val as u32,
+ );
}
}
if let Some(val) = PREFS.get("js.mem.gc.empty_chunk_count_min").as_i64() {
@@ -347,10 +396,10 @@ unsafe extern "C" fn get_size(obj: *mut JSObject) -> usize {
}
let mut ops = MallocSizeOfOps::new(::servo_allocator::usable_size, None, None);
(v.malloc_size_of)(&mut ops, dom_object)
- }
+ },
Err(_e) => {
return 0;
- }
+ },
}
}
@@ -375,30 +424,42 @@ pub fn get_reports(cx: *mut JSContext, path_seg: String) -> Vec<Report> {
// 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);
+ 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);
+ report(
+ path!["malloc-heap"],
+ ReportKind::ExplicitSystemHeapSize,
+ stats.mallocHeap,
+ );
+
+ report(
+ path!["non-heap"],
+ ReportKind::ExplicitNonHeapSize,
+ stats.nonHeap,
+ );
}
}
reports
@@ -408,34 +469,30 @@ 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(_cx: *mut JSContext, progress: GCProgress, desc: *const GCDescription) {
+unsafe extern "C" fn gc_slice_callback(
+ _cx: *mut JSContext,
+ 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);
- })
- },
+ 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;
@@ -443,25 +500,30 @@ unsafe extern "C" fn gc_slice_callback(_cx: *mut JSContext, progress: GCProgress
JSGCInvocationKind::GC_NORMAL => "GC_NORMAL",
JSGCInvocationKind::GC_SHRINK => "GC_SHRINK",
};
- println!(" isZone={}, invocation_kind={}", desc.isZone_, invocation_kind);
+ println!(
+ " isZone={}, invocation_kind={}",
+ desc.isZone_, invocation_kind
+ );
}
let _ = stdout().flush();
}
#[allow(unsafe_code)]
-unsafe extern "C" fn debug_gc_callback(_cx: *mut JSContext, status: JSGCStatus, _data: *mut os::raw::c_void) {
+unsafe extern "C" fn debug_gc_callback(
+ _cx: *mut JSContext,
+ status: JSGCStatus,
+ _data: *mut os::raw::c_void,
+) {
match status {
JSGCStatus::JSGC_BEGIN => thread_state::enter(ThreadState::IN_GC),
- JSGCStatus::JSGC_END => thread_state::exit(ThreadState::IN_GC),
+ JSGCStatus::JSGC_END => thread_state::exit(ThreadState::IN_GC),
}
}
-thread_local!(
- static THREAD_ACTIVE: Cell<bool> = Cell::new(true);
-);
+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) {
+unsafe extern "C" fn trace_rust_roots(tr: *mut JSTracer, _data: *mut os::raw::c_void) {
if !THREAD_ACTIVE.with(|t| t.get()) {
return;
}