mirror of
https://github.com/servo/servo.git
synced 2025-06-25 09:34:32 +01:00
Make GC work.
This commit is contained in:
parent
535bfb3cbb
commit
db5eca4764
10 changed files with 128 additions and 42 deletions
7
src/patches/README
Normal file
7
src/patches/README
Normal file
|
@ -0,0 +1,7 @@
|
|||
Patches live here for submodules that should remain as pristine as possible.
|
||||
This will allow us to unconditionally update them, then apply necessary
|
||||
patches as needed.
|
||||
|
||||
* mozjs-stack-bounds.diff:
|
||||
add a public API to overwrite the engine's computed stack bounds for
|
||||
GC scanning.
|
72
src/patches/mozjs-stack-bounds.diff
Normal file
72
src/patches/mozjs-stack-bounds.diff
Normal file
|
@ -0,0 +1,72 @@
|
|||
diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp
|
||||
index 5571fc0..df2fabd 100644
|
||||
--- a/js/src/jsapi.cpp
|
||||
+++ b/js/src/jsapi.cpp
|
||||
@@ -735,6 +735,7 @@ JSRuntime::JSRuntime()
|
||||
#endif
|
||||
selfHostedGlobal_(NULL),
|
||||
nativeStackBase(0),
|
||||
+ nativeStackEnd(0),
|
||||
nativeStackQuota(0),
|
||||
interpreterFrames(NULL),
|
||||
cxCallback(NULL),
|
||||
@@ -7084,6 +7085,13 @@ JS_SetRuntimeThread(JSRuntime *rt)
|
||||
#endif
|
||||
}
|
||||
|
||||
+extern JS_PUBLIC_API(void)
|
||||
+JS_SetNativeStackBounds(JSRuntime *rt, uintptr_t stackBase, uintptr_t stackEnd)
|
||||
+{
|
||||
+ rt->nativeStackBase = stackBase;
|
||||
+ rt->nativeStackEnd = stackEnd;
|
||||
+}
|
||||
+
|
||||
extern JS_NEVER_INLINE JS_PUBLIC_API(void)
|
||||
JS_AbortIfWrongThread(JSRuntime *rt)
|
||||
{
|
||||
diff --git a/js/src/jsapi.h b/js/src/jsapi.h
|
||||
index c8ab0f0..0edb722 100644
|
||||
--- a/js/src/jsapi.h
|
||||
+++ b/js/src/jsapi.h
|
||||
@@ -6248,6 +6248,9 @@ JS_ClearRuntimeThread(JSRuntime *rt);
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_SetRuntimeThread(JSRuntime *rt);
|
||||
|
||||
+extern JS_PUBLIC_API(void)
|
||||
+JS_SetNativeStackBounds(JSRuntime *rt, uintptr_t stackBase, uintptr_t stackEnd);
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
JS_END_EXTERN_C
|
||||
|
||||
diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h
|
||||
index 0bb6d1c..32e016e 100644
|
||||
--- a/js/src/jscntxt.h
|
||||
+++ b/js/src/jscntxt.h
|
||||
@@ -439,6 +439,9 @@ struct JSRuntime : js::RuntimeFriendFields
|
||||
/* Base address of the native stack for the current thread. */
|
||||
uintptr_t nativeStackBase;
|
||||
|
||||
+ /* Base address of the native stack for the current thread. */
|
||||
+ uintptr_t nativeStackEnd;
|
||||
+
|
||||
/* The native stack size limit that runtime should not exceed. */
|
||||
size_t nativeStackQuota;
|
||||
|
||||
diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp
|
||||
index f5cbc62..eae29da 100644
|
||||
--- a/js/src/jsgc.cpp
|
||||
+++ b/js/src/jsgc.cpp
|
||||
@@ -1177,9 +1177,11 @@ MarkConservativeStackRoots(JSTracer *trc, bool useSavedRoots)
|
||||
uintptr_t *stackMin, *stackEnd;
|
||||
#if JS_STACK_GROWTH_DIRECTION > 0
|
||||
stackMin = rt->nativeStackBase;
|
||||
- stackEnd = cgcd->nativeStackTop;
|
||||
+ stackEnd = rt->nativeStackEnd ? reinterpret_cast<uintptr_t*>(rt->nativeStackEnd)
|
||||
+ : cgcd->nativeStackTop;
|
||||
#else
|
||||
- stackMin = cgcd->nativeStackTop + 1;
|
||||
+ stackMin = rt->nativeStackEnd ? reinterpret_cast<uintptr_t*>(rt->nativeStackEnd)
|
||||
+ : cgcd->nativeStackTop + 1;
|
||||
stackEnd = reinterpret_cast<uintptr_t *>(rt->nativeStackBase);
|
||||
#endif
|
||||
|
|
@ -32,10 +32,10 @@ extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
|
|||
}
|
||||
}
|
||||
|
||||
pub extern fn trace(tracer: *JSTracer, obj: *JSObject) {
|
||||
pub extern fn trace(tracer: *mut JSTracer, obj: *JSObject) {
|
||||
let node = unsafe { unwrap(obj) };
|
||||
|
||||
fn trace_node(tracer: *JSTracer, node: Option<AbstractNode>, name: &str) {
|
||||
fn trace_node(tracer: *mut JSTracer, node: Option<AbstractNode>, name: &str) {
|
||||
if node.is_none() {
|
||||
return;
|
||||
}
|
||||
|
@ -45,7 +45,12 @@ pub extern fn trace(tracer: *JSTracer, obj: *JSObject) {
|
|||
let wrapper = cache.get_wrapper();
|
||||
assert!(wrapper.is_not_null());
|
||||
unsafe {
|
||||
JS_CallTracer(tracer, wrapper, JSTRACE_OBJECT as u32);
|
||||
(*tracer).debugPrinter = ptr::null();
|
||||
(*tracer).debugPrintIndex = -1;
|
||||
do str::as_c_str(name) |name| {
|
||||
(*tracer).debugPrintArg = name as *libc::c_void;
|
||||
JS_CallTracer(cast::transmute(tracer), wrapper, JSTRACE_OBJECT as u32);
|
||||
}
|
||||
}
|
||||
}
|
||||
error!("tracing %?:", obj as uint);
|
||||
|
|
|
@ -290,10 +290,8 @@ static DOM_PROXY_OBJECT_SLOT: uint = js::JSSLOT_PROXY_PRIVATE as uint;
|
|||
// changes.
|
||||
static DOM_PROTO_INSTANCE_CLASS_SLOT: u32 = 0;
|
||||
|
||||
// All DOM globals must have a slot at DOM_PROTOTYPE_SLOT. We have to
|
||||
// start at 1 past JSCLASS_GLOBAL_SLOT_COUNT because XPConnect uses
|
||||
// that one.
|
||||
pub static DOM_PROTOTYPE_SLOT: u32 = js::JSCLASS_GLOBAL_SLOT_COUNT + 1;
|
||||
// All DOM globals must have a slot at DOM_PROTOTYPE_SLOT.
|
||||
pub static DOM_PROTOTYPE_SLOT: u32 = js::JSCLASS_GLOBAL_SLOT_COUNT;
|
||||
|
||||
// NOTE: This is baked into the Ion JIT as 0 in codegen for LGetDOMProperty and
|
||||
// LSetDOMProperty. Those constants need to be changed accordingly if this value
|
||||
|
@ -580,6 +578,10 @@ pub impl WrapperCache {
|
|||
self.wrapper = wrapper;
|
||||
}
|
||||
|
||||
fn get_rootable(&self) -> **JSObject {
|
||||
return ptr::addr_of(&self.wrapper);
|
||||
}
|
||||
|
||||
fn new() -> WrapperCache {
|
||||
WrapperCache {
|
||||
wrapper: ptr::null()
|
||||
|
|
|
@ -16,7 +16,7 @@ use js::crust::{JS_PropertyStub, JS_StrictPropertyStub};
|
|||
use js::global::jsval_to_rust_str;
|
||||
use js::glue::bindgen::*;
|
||||
use js::glue::bindgen::RUST_JSVAL_TO_INT;
|
||||
use js::jsapi::bindgen::{JS_DefineFunctions};
|
||||
use js::jsapi::bindgen::{JS_DefineFunctions, JS_GC, JS_GetRuntime};
|
||||
use js::jsapi::bindgen::{JS_GetReservedSlot, JS_SetReservedSlot};
|
||||
use js::jsapi::bindgen::{JS_ValueToString};
|
||||
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSFreeOp, JSFunctionSpec};
|
||||
|
@ -31,12 +31,15 @@ extern fn alert(cx: *JSContext, argc: c_uint, vp: *JSVal) -> JSBool {
|
|||
assert!(argc == 1);
|
||||
// Abstract this pattern and use it in debug, too?
|
||||
let jsstr = JS_ValueToString(cx, *ptr::offset(argv, 0));
|
||||
if jsstr.is_null() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
(*unwrap(JS_THIS_OBJECT(cx, vp))).payload.alert(jsval_to_rust_str(cx, jsstr));
|
||||
|
||||
JS_SET_RVAL(cx, vp, JSVAL_NULL);
|
||||
return 1;
|
||||
}
|
||||
1_i32
|
||||
}
|
||||
|
||||
extern fn setTimeout(cx: *JSContext, argc: c_uint, vp: *JSVal) -> JSBool {
|
||||
|
@ -63,6 +66,14 @@ extern fn close(cx: *JSContext, _argc: c_uint, vp: *JSVal) -> JSBool {
|
|||
}
|
||||
}
|
||||
|
||||
extern fn gc(cx: *JSContext, _argc: c_uint, _vp: *JSVal) -> JSBool {
|
||||
unsafe {
|
||||
let runtime = JS_GetRuntime(cx);
|
||||
JS_GC(runtime);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn unwrap(obj: *JSObject) -> *rust_box<Window> {
|
||||
let val = JS_GetReservedSlot(obj, 0);
|
||||
cast::reinterpret_cast(&RUST_JSVAL_TO_PRIVATE(val))
|
||||
|
@ -99,7 +110,14 @@ pub fn init(compartment: @mut Compartment) {
|
|||
JSFunctionSpec {
|
||||
name: compartment.add_name(~"close"),
|
||||
call: JSNativeWrapper { op: close, info: null() },
|
||||
nargs: 2,
|
||||
nargs: 0,
|
||||
flags: 0,
|
||||
selfHostedName: null()
|
||||
},
|
||||
JSFunctionSpec {
|
||||
name: compartment.add_name(~"_trigger_gc"),
|
||||
call: JSNativeWrapper { op: gc, info: null() },
|
||||
nargs: 0,
|
||||
flags: 0,
|
||||
selfHostedName: null()
|
||||
},
|
||||
|
|
|
@ -27,9 +27,9 @@ pub fn Document(root: AbstractNode,
|
|||
};
|
||||
let compartment = global_content().compartment.get();
|
||||
do root.with_imm_node |node| {
|
||||
let wrapper = node.wrapper.get_wrapper();
|
||||
assert!(wrapper.is_not_null());
|
||||
unsafe { JS_AddObjectRoot(compartment.cx.ptr, ptr::addr_of(&wrapper)); }
|
||||
assert!(node.wrapper.get_wrapper().is_not_null());
|
||||
let rootable = node.wrapper.get_rootable();
|
||||
unsafe { JS_AddObjectRoot(compartment.cx.ptr, rootable); }
|
||||
}
|
||||
document::create(compartment, doc);
|
||||
doc
|
||||
|
@ -40,9 +40,9 @@ impl Drop for Document {
|
|||
fn finalize(&self) {
|
||||
let compartment = global_content().compartment.get();
|
||||
do self.root.with_imm_node |node| {
|
||||
let wrapper = node.wrapper.get_wrapper();
|
||||
assert!(wrapper.is_not_null());
|
||||
unsafe { JS_RemoveObjectRoot(compartment.cx.ptr, ptr::addr_of(&wrapper)); }
|
||||
assert!(node.wrapper.get_wrapper().is_not_null());
|
||||
let rootable = node.wrapper.get_rootable();
|
||||
unsafe { JS_RemoveObjectRoot(compartment.cx.ptr, rootable); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,13 +20,6 @@ pub struct Element {
|
|||
attrs: ~[Attr],
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
impl Drop for Element {
|
||||
fn finalize(&self) {
|
||||
fail!(~"uh oh");
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Eq)]
|
||||
pub enum ElementTypeId {
|
||||
HTMLAnchorElementTypeId,
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
div #styled {
|
||||
#styled {
|
||||
color: red;
|
||||
}
|
|
@ -4,6 +4,6 @@
|
|||
<script src="test_hammer_layout.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="styled">This text is unstyled.</div>
|
||||
<div id="">This text is unstyled.</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
window.setTimeout(function() {
|
||||
//var divs = document.getElementsByTagName("div");
|
||||
// divs[0].setAttribute('id', 'styled');
|
||||
function print_tree(n) {
|
||||
window.alert(n.nodeType);
|
||||
//window.alert(n.tagName);
|
||||
n = n.firstChild;
|
||||
while (n) {
|
||||
print_tree(n);
|
||||
n = n.nextSibling;
|
||||
}
|
||||
}
|
||||
print_tree(document.documentElement);
|
||||
//window.alert(document.documentElement.tagName);
|
||||
//window.alert(document.documentElement.firstChild.nodeType);
|
||||
//window.alert(document.documentElement.firstChild.firstChild.nodeType);
|
||||
}, 200);
|
||||
var divs = document.getElementsByTagName("div");
|
||||
var div = divs[0];
|
||||
for (var i = 0; i < 1000000; i++) {
|
||||
div.setAttribute('id', 'styled');
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue