Skip to content
Permalink
Browse files

Use better JS engine defaults

This adds in preferences for all the SM 39 available options (as
retrieved from Gecko), and uses the same defaults as Gecko. A few
properties are not supported yet, and incremental GC is still always
disabled regardless of the preference setting.

This also adds back in the options that were accidentally deleted when
\#10342 was rebased, which moved things from script_thread.rs to
script_runtime.rs.
  • Loading branch information
metajack committed Apr 8, 2016
1 parent 6150e17 commit 1bec1934153479de7ef3ebd17d78562c048356ba
Showing with 230 additions and 3 deletions.
  1. +177 −0 components/script/script_runtime.rs
  2. +2 −1 components/script/script_thread.rs
  3. +16 −2 components/util/prefs.rs
  4. +35 −0 resources/prefs.json
@@ -13,6 +13,8 @@ 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::{JSGCMode, JSGCParamKey, JS_SetGCParameter, JS_SetGlobalJitCompilerOption};
use js::jsapi::{JSJitCompilerOption, JS_SetOffthreadIonCompilationEnabled, JS_SetParallelParsingEnabled};
use js::jsapi::{JSObject, RuntimeOptionsRef, SetPreserveWrapperCallback};
use js::rust::Runtime;
use libc;
@@ -130,6 +132,181 @@ pub fn new_rt_and_cx() -> Runtime {
if let Some(val) = get_pref("js.ion.enabled").as_boolean() {
rt_opts.set_ion_(val);
}
if let Some(val) = get_pref("js.asmjs.enabled").as_boolean() {
rt_opts.set_asmJS_(val);
}
if let Some(val) = get_pref("js.strict.enabled").as_boolean() {
rt_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) = get_pref("js.native_regexp.enabled").as_boolean() {
rt_opts.set_nativeRegExp_(val);
}
if let Some(val) = get_pref("js.parallel_parsing.enabled").as_boolean() {
unsafe { JS_SetParallelParsingEnabled(runtime.rt(), val); }
}
if let Some(val) = get_pref("js.offthread_compilation_enabled").as_boolean() {
unsafe { JS_SetOffthreadIonCompilationEnabled(runtime.rt(), val); }
}
if let Some(val) = get_pref("js.baseline.unsafe_eager_compilation.enabled").as_boolean() {
let trigger: i32 = if val {
0
} else {
-1
};
unsafe {
JS_SetGlobalJitCompilerOption(runtime.rt(),
JSJitCompilerOption::JSJITCOMPILER_BASELINE_WARMUP_TRIGGER,
trigger as u32);
}
}
if let Some(val) = get_pref("js.ion.unsafe_eager_compilation.enabled").as_boolean() {
let trigger: i64 = if val {
0
} else {
-1
};
unsafe {
JS_SetGlobalJitCompilerOption(runtime.rt(),
JSJitCompilerOption::JSJITCOMPILER_ION_WARMUP_TRIGGER,
trigger as u32);
}
}
// TODO: handle js.discard_system_source.enabled
// TODO: handle js.asyncstack.enabled (needs new Spidermonkey)
// 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) = get_pref("js.werror.enabled").as_boolean() {
rt_opts.set_werror_(val);
}
// TODO: handle js.shared_memory.enabled
if let Some(val) = get_pref("js.mem.high_water_mark").as_i64() {
unsafe {
JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_MAX_MALLOC_BYTES, val as u32 * 1024 * 1024);
}
}
if let Some(val) = get_pref("js.mem.max").as_i64() {
let max = if val <= 0 || val >= 0x1000 {
-1
} else {
val * 1024 * 1024
};
unsafe {
JS_SetGCParameter(runtime.rt(), 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) = get_pref("js.mem.gc.incremental.enabled").as_boolean() {
let compartment = if let Some(val) = get_pref("js.mem.gc.per_compartment.enabled").as_boolean() {
val
} else {
false
};
let mode = if val {
JSGCMode::JSGC_MODE_INCREMENTAL
} else if compartment {
JSGCMode::JSGC_MODE_COMPARTMENT
} else {
JSGCMode::JSGC_MODE_GLOBAL
};
unsafe {
JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_MODE, mode as u32);
}
}
if let Some(val) = get_pref("js.mem.gc.incremental.slice_ms").as_i64() {
if val >= 0 && val < 100000 {
unsafe {
JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_SLICE_TIME_BUDGET, val as u32);
}
}
}
if let Some(val) = get_pref("js.mem.gc.compacting.enabled").as_boolean() {
unsafe {
JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_COMPACTING_ENABLED, val as u32);
}
}
if let Some(val) = get_pref("js.mem.gc.high_frequency_time_limit_ms").as_i64() {
if val >= 0 && val < 10000 {
unsafe {
JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_HIGH_FREQUENCY_TIME_LIMIT, val as u32);
}
}
}
if let Some(val) = get_pref("js.mem.gc.dynamic_mark_slice.enabled").as_boolean() {
unsafe {
JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_DYNAMIC_MARK_SLICE, val as u32);
}
}
// TODO: handle js.mem.gc.refresh_frame_slices.enabled
if let Some(val) = get_pref("js.mem.gc.dynamic_heap_growth.enabled").as_boolean() {
unsafe {
JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_DYNAMIC_HEAP_GROWTH, val as u32);
}
}
if let Some(val) = get_pref("js.mem.gc.low_frequency_heap_growth").as_i64() {
if val >= 0 && val < 10000 {
unsafe {
JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_LOW_FREQUENCY_HEAP_GROWTH, val as u32);
}
}
}
if let Some(val) = get_pref("js.mem.gc.high_frequency_heap_growth_min").as_i64() {
if val >= 0 && val < 10000 {
unsafe {
JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN, val as u32);
}
}
}
if let Some(val) = get_pref("js.mem.gc.high_frequency_heap_growth_max").as_i64() {
if val >= 0 && val < 10000 {
unsafe {
JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX, val as u32);
}
}
}
if let Some(val) = get_pref("js.mem.gc.high_frequency_low_limit_mb").as_i64() {
if val >= 0 && val < 10000 {
unsafe {
JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_HIGH_FREQUENCY_LOW_LIMIT, val as u32);
}
}
}
if let Some(val) = get_pref("js.mem.gc.high_frequency_high_limit_mb").as_i64() {
if val >= 0 && val < 10000 {
unsafe {
JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_HIGH_FREQUENCY_HIGH_LIMIT, val as u32);
}
}
}
if let Some(val) = get_pref("js.mem.gc.allocation_threshold_mb").as_i64() {
if val >= 0 && val < 10000 {
unsafe {
JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_ALLOCATION_THRESHOLD, val as u32);
}
}
}
if let Some(val) = get_pref("js.mem.gc.decommit_threshold_mb").as_i64() {
if val >= 0 && val < 10000 {
unsafe {
JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_DECOMMIT_THRESHOLD, val as u32);
}
}
}
if let Some(val) = get_pref("js.mem.gc.empty_chunk_count_min").as_i64() {
if val >= 0 && val < 10000 {
unsafe {
JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_MIN_EMPTY_CHUNK_COUNT, val as u32);
}
}
}
if let Some(val) = get_pref("js.mem.gc.empty_chunk_count_max").as_i64() {
if val >= 0 && val < 10000 {
unsafe {
JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_MAX_EMPTY_CHUNK_COUNT, val as u32);
}
}
}

runtime
}
@@ -52,7 +52,8 @@ use hyper::mime::{Mime, SubLevel, TopLevel};
use ipc_channel::ipc::{self, IpcSender};
use ipc_channel::router::ROUTER;
use js::jsapi::{DOMProxyShadowsResult, HandleId, HandleObject, RootedValue};
use js::jsapi::{JSAutoRequest, JSContext, JS_SetWrapObjectCallbacks, JSTracer};
use js::jsapi::{JSAutoRequest, JS_SetWrapObjectCallbacks};
use js::jsapi::{JSContext, JSTracer};
use js::jsval::UndefinedValue;
use js::rust::Runtime;
use layout_interface::{ReflowQueryType};
@@ -23,6 +23,7 @@ lazy_static! {
pub enum PrefValue {
Boolean(bool),
String(String),
Number(f64),
Missing
}

@@ -31,6 +32,9 @@ impl PrefValue {
let value = match data {
Json::Boolean(x) => PrefValue::Boolean(x),
Json::String(x) => PrefValue::String(x),
Json::F64(x) => PrefValue::Number(x),
Json::I64(x) => PrefValue::Number(x as f64),
Json::U64(x) => PrefValue::Number(x as f64),
_ => return Err(())
};
Ok(value)
@@ -53,6 +57,13 @@ impl PrefValue {
_ => None
}
}

pub fn as_i64(&self) -> Option<i64> {
match *self {
PrefValue::Number(x) => Some(x as i64),
_ => None,
}
}
}

impl ToJson for PrefValue {
@@ -63,7 +74,10 @@ impl ToJson for PrefValue {
},
PrefValue::String(ref x) => {
Json::String(x.clone())
}
},
PrefValue::Number(x) => {
Json::F64(x)
},
PrefValue::Missing => Json::Null
}
}
@@ -136,7 +150,7 @@ pub fn read_prefs_from_file<T>(mut file: T)
Ok(x) => {
prefs.insert(name, x);
},
Err(_) => println!("Ignoring non-boolean/string preference value for {:?}", name)
Err(_) => println!("Ignoring non-boolean/string/i64 preference value for {:?}", name),
}
}
}
@@ -5,6 +5,41 @@
"gfx.webrender.enabled": false,
"js.baseline.enabled": true,
"js.ion.enabled": true,
"js.asmjs.enabled": true,
"js.strict.enabled": false,
"js.strict.debug.enabled": false,
"js.throw_on_asmjs_validation_failure.enabled": false,
"js.native_regexp.enabled": true,
"js.parallel_parsing.enabled": true,
"js.ion.offthread_compilation.enabled": true,
"js.baseline.unsafe_eager_compilation.enabled": false,
"js.ion.unsafe_eager_compilation.enabled": false,
"js.discard_system_source.enabled": false,
"js.asyncstack.enabled": false,
"js.throw_on_debuggee_would_run.enabled": false,
"js.dump_stack_on_debuggee_would_run.enabled": false,
"js.werror.enabled": false,
"js.strict.enabled": false,
"js.shared_memory.enabled": true,
"js.mem.high_water_mark": 128,
"js.mem.max": -1,
"js.mem.gc.per_compartment.enabled": true,
"js.mem.gc.incremental.enabled": true,
"js.mem.gc.incremental.slice_ms": 10,
"js.mem.gc.compacting.enabled": true,
"js.mem.gc.high_frequency_time_limit_ms": 1000,
"js.mem.gc.dynamic_mark_slice.enabled": true,
"js.mem.gc.refresh_frame_slices.enabled": true,
"js.mem.gc.dynamic_heap_growth.enabled": true,
"js.mem.gc.low_frequency_heap_growth": 150,
"js.mem.gc.high_frequency_heap_growth_min": 150,
"js.mem.gc.high_frequency_heap_growth_max": 300,
"js.mem.gc.high_frequency_low_limit_mb": 100,
"js.mem.gc.high_frequency_high_limit_mb": 500,
"js.mem.gc.allocation_threshold_mb": 30,
"js.mem.gc.decommit_threshold_mb": 32,
"js.mem.gc.empty_chunk_count_min": 1,
"js.mem.gc.empty_chunk_count_max": 30,
"layout.columns.enabled": false,
"layout.column-width.enabled": false,
"layout.column-count.enabled": false,

0 comments on commit 1bec193

Please sign in to comment.
You can’t perform that action at this time.