Skip to content

Commit

Permalink
Added off thread compilation
Browse files Browse the repository at this point in the history
Co-authored-by: Gregory Terzian <2792687+gterzian@users.noreply.github.com>
Co-authored-by: Abhishek Sharma <20724848+AbhishekSharma102@users.noreply.github.com>
  • Loading branch information
2 people authored and jdm committed Jul 21, 2020
1 parent bfb7bea commit 1119dd1
Show file tree
Hide file tree
Showing 8 changed files with 315 additions and 90 deletions.
3 changes: 3 additions & 0 deletions components/config/prefs.rs
Expand Up @@ -186,6 +186,9 @@ mod gen {
allowed_in_nonsecure_contexts: bool,
}
},
script: {
asynch: bool,
},
serviceworker: {
enabled: bool,
timeout_seconds: i64,
Expand Down
5 changes: 4 additions & 1 deletion components/script/devtools.rs
Expand Up @@ -14,6 +14,7 @@ use crate::dom::bindings::str::DOMString;
use crate::dom::document::AnimationFrameCallback;
use crate::dom::element::Element;
use crate::dom::globalscope::GlobalScope;
use crate::dom::htmlscriptelement::SourceCode;
use crate::dom::node::{window_from_node, Node, ShadowIncluding};
use crate::realms::enter_realm;
use crate::script_module::ScriptFetchOptions;
Expand All @@ -25,6 +26,7 @@ use js::jsval::UndefinedValue;
use js::rust::wrappers::ObjectClassName;
use msg::constellation_msg::PipelineId;
use std::ffi::CStr;
use std::rc::Rc;
use std::str;
use uuid::Uuid;

Expand All @@ -35,8 +37,9 @@ pub fn handle_evaluate_js(global: &GlobalScope, eval: String, reply: IpcSender<E
let cx = global.get_cx();
let _ac = enter_realm(global);
rooted!(in(*cx) let mut rval = UndefinedValue());
let source_code = SourceCode::Text(Rc::new(DOMString::from_string(eval)));
global.evaluate_script_on_global_with_result(
&eval,
&source_code,
"<eval>",
rval.handle_mut(),
1,
Expand Down
27 changes: 25 additions & 2 deletions components/script/dom/bindings/trace.rs
Expand Up @@ -77,8 +77,10 @@ use hyper::Method;
use hyper::StatusCode;
use indexmap::IndexMap;
use ipc_channel::ipc::{IpcReceiver, IpcSender};
use js::glue::{CallObjectTracer, CallStringTracer, CallValueTracer};
use js::jsapi::{GCTraceKindToAscii, Heap, JSObject, JSString, JSTracer, JobQueue, TraceKind};
use js::glue::{CallObjectTracer, CallScriptTracer, CallStringTracer, CallValueTracer};
use js::jsapi::{
GCTraceKindToAscii, Heap, JSObject, JSScript, JSString, JSTracer, JobQueue, TraceKind,
};
use js::jsval::JSVal;
use js::rust::{GCMethods, Handle, Runtime};
use js::typedarray::TypedArray;
Expand Down Expand Up @@ -219,6 +221,18 @@ unsafe_no_jsmanaged_fields!(Cow<'static, str>);

unsafe_no_jsmanaged_fields!(CspList);

/// Trace a `JSScript`.
pub fn trace_script(tracer: *mut JSTracer, description: &str, script: &Heap<*mut JSScript>) {
unsafe {
trace!("tracing {}", description);
CallScriptTracer(
tracer,
script.ptr.get() as *mut _,
GCTraceKindToAscii(TraceKind::Script),
);
}
}

/// Trace a `JSVal`.
pub fn trace_jsval(tracer: *mut JSTracer, description: &str, val: &Heap<JSVal>) {
unsafe {
Expand Down Expand Up @@ -328,6 +342,15 @@ unsafe impl<T: JSTraceable> JSTraceable for RefCell<T> {
}
}

unsafe impl JSTraceable for Heap<*mut JSScript> {
unsafe fn trace(&self, trc: *mut JSTracer) {
if self.get().is_null() {
return;
}
trace_script(trc, "heap script", self);
}
}

unsafe impl JSTraceable for Heap<*mut JSObject> {
unsafe fn trace(&self, trc: *mut JSTracer) {
if self.get().is_null() {
Expand Down
99 changes: 55 additions & 44 deletions components/script/dom/globalscope.rs
Expand Up @@ -38,7 +38,7 @@ use crate::dom::file::File;
use crate::dom::gpudevice::GPUDevice;
use crate::dom::gpuoutofmemoryerror::GPUOutOfMemoryError;
use crate::dom::gpuvalidationerror::GPUValidationError;
use crate::dom::htmlscriptelement::ScriptId;
use crate::dom::htmlscriptelement::{ScriptId, SourceCode};
use crate::dom::identityhub::Identities;
use crate::dom::imagebitmap::ImageBitmap;
use crate::dom::messageevent::MessageEvent;
Expand Down Expand Up @@ -91,9 +91,9 @@ use js::jsval::PrivateValue;
use js::jsval::{JSVal, UndefinedValue};
use js::panic::maybe_resume_unwind;
use js::rust::transform_str_to_source_text;
use js::rust::wrappers::{JS_ExecuteScript, JS_GetScriptPrivate};
use js::rust::wrappers::{JS_ExecuteScript, JS_ExecuteScript1, JS_GetScriptPrivate};
use js::rust::{get_object_class, CompileOptionsWrapper, ParentRuntime, Runtime};
use js::rust::{HandleValue, MutableHandleValue};
use js::rust::{HandleScript, HandleValue, MutableHandleValue};
use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL};
use msg::constellation_msg::{
BlobId, BroadcastChannelRouterId, MessagePortId, MessagePortRouterId, PipelineId,
Expand Down Expand Up @@ -2552,8 +2552,9 @@ impl GlobalScope {
fetch_options: ScriptFetchOptions,
script_base_url: ServoUrl,
) -> bool {
let source_code = SourceCode::Text(Rc::new(DOMString::from_string((*code).to_string())));
self.evaluate_script_on_global_with_result(
code,
&source_code,
"",
rval,
1,
Expand All @@ -2566,7 +2567,7 @@ impl GlobalScope {
#[allow(unsafe_code)]
pub fn evaluate_script_on_global_with_result(
&self,
code: &str,
code: &SourceCode,
filename: &str,
rval: MutableHandleValue,
line_number: u32,
Expand Down Expand Up @@ -2595,48 +2596,58 @@ impl GlobalScope {
let _aes = AutoEntryScript::new(self);

unsafe {
let options = CompileOptionsWrapper::new(*cx, filename.as_ptr(), line_number);

debug!("compiling Dom string");
rooted!(in(*cx) let compiled_script =
Compile1(
*cx,
options.ptr,
&mut transform_str_to_source_text(code),
)
);
let result = match code {
SourceCode::Text(text_code) => {
let options =
CompileOptionsWrapper::new(*cx, filename.as_ptr(), line_number);

debug!("compiling Dom string");
rooted!(in(*cx) let compiled_script =
Compile1(
*cx,
options.ptr,
&mut transform_str_to_source_text(text_code),
)
);

if compiled_script.is_null() {
debug!("error compiling Dom string");
report_pending_exception(*cx, true, InRealm::Entered(&ar));
return false;
}
if compiled_script.is_null() {
debug!("error compiling Dom string");
report_pending_exception(*cx, true, InRealm::Entered(&ar));
return false;
}

rooted!(in(*cx) let mut script_private = UndefinedValue());
JS_GetScriptPrivate(*compiled_script, script_private.handle_mut());

// When `ScriptPrivate` for the compiled script is undefined,
// we need to set it so that it can be used in dynamic import context.
if script_private.is_undefined() {
debug!("Set script private for {}", script_base_url);

let module_script_data = Rc::new(ModuleScript::new(
script_base_url,
fetch_options,
// We can't initialize an module owner here because
// the executing context of script might be different
// from the dynamic import script's executing context.
None,
));

SetScriptPrivate(
*compiled_script,
&PrivateValue(Rc::into_raw(module_script_data) as *const _),
);
}
rooted!(in(*cx) let mut script_private = UndefinedValue());
JS_GetScriptPrivate(*compiled_script, script_private.handle_mut());

// When `ScriptPrivate` for the compiled script is undefined,
// we need to set it so that it can be used in dynamic import context.
if script_private.is_undefined() {
debug!("Set script private for {}", script_base_url);

let module_script_data = Rc::new(ModuleScript::new(
script_base_url,
fetch_options,
// We can't initialize an module owner here because
// the executing context of script might be different
// from the dynamic import script's executing context.
None,
));

SetScriptPrivate(
*compiled_script,
&PrivateValue(Rc::into_raw(module_script_data) as *const _),
);
}

debug!("evaluating Dom string");
let result = JS_ExecuteScript(*cx, compiled_script.handle(), rval);
debug!("evaluating Dom string");
JS_ExecuteScript(*cx, compiled_script.handle(), rval)
},
SourceCode::Compiled(compiled_script) => {
let script = compiled_script.source_code.get();
let script_handle = HandleScript::new(&script);
JS_ExecuteScript1(*cx, script_handle)
},
};

if !result {
debug!("error evaluating Dom string");
Expand Down

0 comments on commit 1119dd1

Please sign in to comment.