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.rs125
1 files changed, 75 insertions, 50 deletions
diff --git a/components/script/script_runtime.rs b/components/script/script_runtime.rs
index f758a1131c0..b5d598d1c79 100644
--- a/components/script/script_runtime.rs
+++ b/components/script/script_runtime.rs
@@ -15,12 +15,15 @@ use dom::bindings::trace::{JSTraceable, trace_traceables};
use dom::bindings::utils::DOM_CALLBACKS;
use dom::globalscope::GlobalScope;
use js::glue::CollectServoSizes;
+use js::glue::SetBuildId;
use js::jsapi::{DisableIncrementalGC, GCDescription, GCProgress, HandleObject};
-use js::jsapi::{JSContext, JS_GetRuntime, JSRuntime, JSTracer, SetDOMCallbacks, SetGCSliceCallback};
+use js::jsapi::{JSContext, JSTracer, SetDOMCallbacks, SetGCSliceCallback};
use js::jsapi::{JSGCInvocationKind, JSGCStatus, JS_AddExtraGCRootsTracer, JS_SetGCCallback};
use js::jsapi::{JSGCMode, JSGCParamKey, JS_SetGCParameter, JS_SetGlobalJitCompilerOption};
use js::jsapi::{JSJitCompilerOption, JS_SetOffthreadIonCompilationEnabled, JS_SetParallelParsingEnabled};
-use js::jsapi::{JSObject, RuntimeOptionsRef, SetPreserveWrapperCallback, SetEnqueuePromiseJobCallback};
+use js::jsapi::{JSObject, SetPreserveWrapperCallback, SetEnqueuePromiseJobCallback};
+use js::jsapi::{SetBuildIdOp, BuildIdCharVector};
+use js::jsapi::ContextOptionsRef;
use js::panic::wrap_panic;
use js::rust::Runtime as RustRuntime;
use malloc_size_of::MallocSizeOfOps;
@@ -112,6 +115,7 @@ pub trait ScriptPort {
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?
@@ -145,52 +149,68 @@ impl Deref for Runtime {
pub unsafe fn new_rt_and_cx() -> Runtime {
LiveDOMReferences::initialize();
let runtime = RustRuntime::new().unwrap();
+ let cx = runtime.cx();
- JS_AddExtraGCRootsTracer(runtime.rt(), Some(trace_rust_roots), ptr::null_mut());
+ JS_AddExtraGCRootsTracer(cx, Some(trace_rust_roots), ptr::null_mut());
// Needed for debug assertions about whether GC is running.
if cfg!(debug_assertions) {
- JS_SetGCCallback(runtime.rt(), Some(debug_gc_callback), ptr::null_mut());
+ JS_SetGCCallback(cx, Some(debug_gc_callback), ptr::null_mut());
}
if opts::get().gc_profile {
- SetGCSliceCallback(runtime.rt(), Some(gc_slice_callback));
+ SetGCSliceCallback(cx, Some(gc_slice_callback));
}
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));
+ SetDOMCallbacks(cx, &DOM_CALLBACKS);
+ SetPreserveWrapperCallback(cx, Some(empty_wrapper_callback));
// Pre barriers aren't working correctly at the moment
- DisableIncrementalGC(runtime.rt());
+ DisableIncrementalGC(cx);
- SetEnqueuePromiseJobCallback(runtime.rt(), Some(enqueue_job), ptr::null_mut());
+ SetEnqueuePromiseJobCallback(cx, Some(enqueue_job), ptr::null_mut());
- set_gc_zeal_options(runtime.rt());
+ set_gc_zeal_options(cx);
// Enable or disable the JITs.
- let rt_opts = &mut *RuntimeOptionsRef(runtime.rt());
+ let cx_opts = &mut *ContextOptionsRef(cx);
if let Some(val) = PREFS.get("js.baseline.enabled").as_boolean() {
- rt_opts.set_baseline_(val);
+ cx_opts.set_baseline_(val);
}
if let Some(val) = PREFS.get("js.ion.enabled").as_boolean() {
- rt_opts.set_ion_(val);
+ cx_opts.set_ion_(val);
}
if let Some(val) = PREFS.get("js.asmjs.enabled").as_boolean() {
- rt_opts.set_asmJS_(val);
+ cx_opts.set_asmJS_(val);
+ }
+ if let Some(val) = PREFS.get("js.wasm.enabled").as_boolean() {
+ cx_opts.set_wasm_(val);
+ if val {
+ // If WASM is enabled without setting the buildIdOp,
+ // initializing a module will report an out of memory error.
+ // https://dxr.mozilla.org/mozilla-central/source/js/src/wasm/WasmTypes.cpp#458
+ SetBuildIdOp(cx, Some(servo_build_id));
+ }
+ }
+ if let Some(val) = PREFS.get("js.wasm.baseline.enabled").as_boolean() {
+ cx_opts.set_wasmBaseline_(val);
+ }
+ if let Some(val) = PREFS.get("js.wasm.ion.enabled").as_boolean() {
+ cx_opts.set_wasmIon_(val);
}
if let Some(val) = PREFS.get("js.strict.enabled").as_boolean() {
- rt_opts.set_extraWarnings_(val);
+ cx_opts.set_extraWarnings_(val);
}
// TODO: handle js.strict.debug.enabled
// TODO: handle js.throw_on_asmjs_validation_failure (needs new Spidermonkey)
if let Some(val) = PREFS.get("js.native_regexp.enabled").as_boolean() {
- rt_opts.set_nativeRegExp_(val);
+ cx_opts.set_nativeRegExp_(val);
}
if let Some(val) = PREFS.get("js.parallel_parsing.enabled").as_boolean() {
- JS_SetParallelParsingEnabled(runtime.rt(), val);
+ JS_SetParallelParsingEnabled(cx, val);
}
if let Some(val) = PREFS.get("js.offthread_compilation_enabled").as_boolean() {
- JS_SetOffthreadIonCompilationEnabled(runtime.rt(), val);
+ JS_SetOffthreadIonCompilationEnabled(cx, val);
}
if let Some(val) = PREFS.get("js.baseline.unsafe_eager_compilation.enabled").as_boolean() {
let trigger: i32 = if val {
@@ -198,7 +218,7 @@ pub unsafe fn new_rt_and_cx() -> Runtime {
} else {
-1
};
- JS_SetGlobalJitCompilerOption(runtime.rt(),
+ JS_SetGlobalJitCompilerOption(cx,
JSJitCompilerOption::JSJITCOMPILER_BASELINE_WARMUP_TRIGGER,
trigger as u32);
}
@@ -208,7 +228,7 @@ pub unsafe fn new_rt_and_cx() -> Runtime {
} else {
-1
};
- JS_SetGlobalJitCompilerOption(runtime.rt(),
+ JS_SetGlobalJitCompilerOption(cx,
JSJitCompilerOption::JSJITCOMPILER_ION_WARMUP_TRIGGER,
trigger as u32);
}
@@ -217,11 +237,11 @@ pub unsafe fn new_rt_and_cx() -> Runtime {
// TODO: handle js.throw_on_debugee_would_run (needs new Spidermonkey)
// TODO: handle js.dump_stack_on_debugee_would_run (needs new Spidermonkey)
if let Some(val) = PREFS.get("js.werror.enabled").as_boolean() {
- rt_opts.set_werror_(val);
+ cx_opts.set_werror_(val);
}
// TODO: handle js.shared_memory.enabled
if let Some(val) = PREFS.get("js.mem.high_water_mark").as_i64() {
- JS_SetGCParameter(runtime.rt(), 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 {
@@ -229,11 +249,11 @@ pub unsafe fn new_rt_and_cx() -> Runtime {
} else {
val * 1024 * 1024
};
- JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_MAX_BYTES, max as u32);
+ JS_SetGCParameter(cx, JSGCParamKey::JSGC_MAX_BYTES, max as u32);
}
// NOTE: This is disabled above, so enabling it here will do nothing for now.
if let Some(val) = PREFS.get("js.mem.gc.incremental.enabled").as_boolean() {
- let compartment = if let Some(val) = PREFS.get("js.mem.gc.per_compartment.enabled").as_boolean() {
+ let compartment = if let Some(val) = PREFS.get("js.mem.gc.per_zone.enabled").as_boolean() {
val
} else {
false
@@ -241,74 +261,74 @@ pub unsafe fn new_rt_and_cx() -> Runtime {
let mode = if val {
JSGCMode::JSGC_MODE_INCREMENTAL
} else if compartment {
- JSGCMode::JSGC_MODE_COMPARTMENT
+ JSGCMode::JSGC_MODE_ZONE
} else {
JSGCMode::JSGC_MODE_GLOBAL
};
- JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_MODE, mode as u32);
+ JS_SetGCParameter(cx, JSGCParamKey::JSGC_MODE, mode as u32);
}
if let Some(val) = PREFS.get("js.mem.gc.incremental.slice_ms").as_i64() {
if val >= 0 && val < 100000 {
- JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_SLICE_TIME_BUDGET, val as u32);
+ JS_SetGCParameter(cx, JSGCParamKey::JSGC_SLICE_TIME_BUDGET, val as u32);
}
}
if let Some(val) = PREFS.get("js.mem.gc.compacting.enabled").as_boolean() {
- JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_COMPACTING_ENABLED, val as u32);
+ JS_SetGCParameter(cx, JSGCParamKey::JSGC_COMPACTING_ENABLED, val as u32);
}
if let Some(val) = PREFS.get("js.mem.gc.high_frequency_time_limit_ms").as_i64() {
if val >= 0 && val < 10000 {
- JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_HIGH_FREQUENCY_TIME_LIMIT, val as u32);
+ 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() {
- JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_DYNAMIC_MARK_SLICE, val as u32);
+ 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() {
- JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_DYNAMIC_HEAP_GROWTH, val as u32);
+ 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() {
if val >= 0 && val < 10000 {
- JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_LOW_FREQUENCY_HEAP_GROWTH, val as u32);
+ 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 val >= 0 && val < 10000 {
- JS_SetGCParameter(runtime.rt(), 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 val >= 0 && val < 10000 {
- JS_SetGCParameter(runtime.rt(), 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() {
if val >= 0 && val < 10000 {
- JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_HIGH_FREQUENCY_LOW_LIMIT, val as u32);
+ JS_SetGCParameter(cx, JSGCParamKey::JSGC_HIGH_FREQUENCY_LOW_LIMIT, val as u32);
}
}
if let Some(val) = PREFS.get("js.mem.gc.high_frequency_high_limit_mb").as_i64() {
if val >= 0 && val < 10000 {
- JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_HIGH_FREQUENCY_HIGH_LIMIT, val as u32);
+ JS_SetGCParameter(cx, JSGCParamKey::JSGC_HIGH_FREQUENCY_HIGH_LIMIT, val as u32);
}
}
- if let Some(val) = PREFS.get("js.mem.gc.allocation_threshold_mb").as_i64() {
+ if let Some(val) = PREFS.get("js.mem.gc.allocation_threshold_factor").as_i64() {
if val >= 0 && val < 10000 {
- JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_ALLOCATION_THRESHOLD, val as u32);
+ JS_SetGCParameter(cx, JSGCParamKey::JSGC_ALLOCATION_THRESHOLD_FACTOR, val as u32);
}
}
- if let Some(val) = PREFS.get("js.mem.gc.decommit_threshold_mb").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(runtime.rt(), JSGCParamKey::JSGC_DECOMMIT_THRESHOLD, 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() {
if val >= 0 && val < 10000 {
- JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_MIN_EMPTY_CHUNK_COUNT, val as u32);
+ JS_SetGCParameter(cx, JSGCParamKey::JSGC_MIN_EMPTY_CHUNK_COUNT, val as u32);
}
}
if let Some(val) = PREFS.get("js.mem.gc.empty_chunk_count_max").as_i64() {
if val >= 0 && val < 10000 {
- JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_MAX_EMPTY_CHUNK_COUNT, val as u32);
+ JS_SetGCParameter(cx, JSGCParamKey::JSGC_MAX_EMPTY_CHUNK_COUNT, val as u32);
}
}
@@ -338,9 +358,8 @@ 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, Some(get_size)) {
+ if CollectServoSizes(cx, &mut stats, Some(get_size)) {
let mut report = |mut path_suffix, kind, size| {
let mut path = path![path_seg, "js"];
path.append(&mut path_suffix);
@@ -388,7 +407,7 @@ 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) {
+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| {
@@ -423,13 +442,13 @@ unsafe extern "C" fn gc_slice_callback(_rt: *mut JSRuntime, progress: GCProgress
JSGCInvocationKind::GC_NORMAL => "GC_NORMAL",
JSGCInvocationKind::GC_SHRINK => "GC_SHRINK",
};
- println!(" isCompartment={}, invocation_kind={}", desc.isCompartment_, invocation_kind);
+ println!(" isZone={}, invocation_kind={}", desc.isZone_, invocation_kind);
}
let _ = stdout().flush();
}
#[allow(unsafe_code)]
-unsafe extern "C" fn debug_gc_callback(_rt: *mut JSRuntime, 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),
@@ -455,8 +474,14 @@ unsafe extern fn trace_rust_roots(tr: *mut JSTracer, _data: *mut os::raw::c_void
}
#[allow(unsafe_code)]
+unsafe extern "C" fn servo_build_id(build_id: *mut BuildIdCharVector) -> bool {
+ let servo_id = b"Servo\0";
+ SetBuildId(build_id, &servo_id[0], servo_id.len())
+}
+
+#[allow(unsafe_code)]
#[cfg(feature = "debugmozjs")]
-unsafe fn set_gc_zeal_options(rt: *mut JSRuntime) {
+unsafe fn set_gc_zeal_options(cx: *mut JSContext) {
use js::jsapi::{JS_DEFAULT_ZEAL_FREQ, JS_SetGCZeal};
let level = match PREFS.get("js.mem.gc.zeal.level").as_i64() {
@@ -467,9 +492,9 @@ unsafe fn set_gc_zeal_options(rt: *mut JSRuntime) {
Some(frequency) if frequency >= 0 => frequency as u32,
_ => JS_DEFAULT_ZEAL_FREQ,
};
- JS_SetGCZeal(rt, level, frequency);
+ JS_SetGCZeal(cx, level, frequency);
}
#[allow(unsafe_code)]
#[cfg(not(feature = "debugmozjs"))]
-unsafe fn set_gc_zeal_options(_: *mut JSRuntime) {}
+unsafe fn set_gc_zeal_options(_: *mut JSContext) {}