auto merge of #5282 : gfxmonk/servo/finalize_global, r=Ms2ger

Fixes #1871

I thought I'd take a look at this for a first contribution to servo. A couple of things I'm not 100% sure on are:

1) `get_proto_or_iface_array` returns a `*mut *mut JSObj`, which I'm assuming is really an array of pointers to `JSObj`s. So dropping its return value will drop the memory for the array of pointers. Do we also need to drop each element, or is that handled by GC?

2) Are there any tests I need to add for this? I don't know if there are existing leak tests, or if leaks are mostly discovered by profiling.
This commit is contained in:
bors-servo 2015-03-20 07:54:48 -06:00
commit 8998edb912
2 changed files with 16 additions and 2 deletions

View file

@ -4061,7 +4061,12 @@ let this: *const %s = native_from_reflector::<%s>(obj);
assert(False)
def finalizeHook(descriptor, hookName, context):
release = """\
release = ""
if descriptor.isGlobal():
release += """\
finalize_global(obj);
"""
release += """\
let _ = Box::from_raw(this as *mut %s);
debug!("%s finalize: {:p}", this);\
""" % (descriptor.concreteType, descriptor.concreteType)
@ -4650,6 +4655,7 @@ class CGBindingRoot(CGThing):
'dom::bindings::utils::{DOMJSClass, JSCLASS_DOM_GLOBAL}',
'dom::bindings::utils::{find_enum_string_index, get_array_index_from_id}',
'dom::bindings::utils::{get_property_on_prototype, get_proto_or_iface_array}',
'dom::bindings::utils::finalize_global',
'dom::bindings::utils::has_property_on_prototype',
'dom::bindings::utils::is_platform_object',
'dom::bindings::utils::{Reflectable}',

View file

@ -321,10 +321,12 @@ pub unsafe extern fn throwing_constructor(cx: *mut JSContext, _argc: c_uint,
return 0;
}
type ProtoOrIfaceArray = [*mut JSObject; PrototypeList::ID::Count as usize];
/// Construct and cache the ProtoOrIfaceArray for the given global.
/// Fails if the argument is not a DOM global.
pub fn initialize_global(global: *mut JSObject) {
let proto_array = box ()
let proto_array: Box<ProtoOrIfaceArray> = box ()
([0 as *mut JSObject; PrototypeList::ID::Count as usize]);
unsafe {
assert!(((*JS_GetClass(global)).flags & JSCLASS_DOM_GLOBAL) != 0);
@ -560,6 +562,12 @@ pub fn create_dom_global(cx: *mut JSContext, class: *const JSClass)
}
}
/// Drop the resources held by reserved slots of a global object
pub unsafe fn finalize_global(obj: *mut JSObject) {
let _: Box<ProtoOrIfaceArray> =
Box::from_raw(get_proto_or_iface_array(obj) as *mut ProtoOrIfaceArray);
}
/// Callback to outerize windows when wrapping.
pub unsafe extern fn wrap_for_same_compartment(cx: *mut JSContext, obj: *mut JSObject) -> *mut JSObject {
JS_ObjectToOuterObject(cx, obj)