Skip to content

Commit

Permalink
Push LibXML's global state to the list of GC roots
Browse files Browse the repository at this point in the history
We are using the GC to allocate memory in LibXML, but it keeps a per-thread
global structure with pointers to dynamically allocated objects, which is
allocated using a regular malloc(). Push this structure to the GC's roots list
such that the GC knows about these pointers and doesn't free them on collection.
  • Loading branch information
ggiraldez committed Mar 6, 2017
1 parent 4c2e8e0 commit d179297
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/gc/boehm.cr
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ lib LibGC
fun set_push_other_roots = GC_set_push_other_roots(proc : ->)
fun get_push_other_roots = GC_get_push_other_roots : ->

fun push_all = GC_push_all(bottom : Void*, top : Void*)
fun push_all_eager = GC_push_all_eager(bottom : Void*, top : Void*)

fun set_stackbottom = GC_set_stackbottom(Void*, Void*)
Expand Down
25 changes: 25 additions & 0 deletions src/xml/error.cr
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ end
class Thread
@__xml_errors = [] of XML::Error
@__xml_errors_initialized = false
@__xml_global_state : Void* = Pointer(Void).null

# FIXME: "fix" this magic number; this is sizeof(xmlGlobalState) for Mac OS X
# 64 bits
XML_GLOBAL_STATE_SIZE = 968

def xml_errors
@__xml_errors
Expand Down Expand Up @@ -65,5 +70,25 @@ class Thread
{% end %}
}
@__xml_errors_initialized = true
@__xml_global_state = LibXML.xmlGetGlobalState
end

protected def xml_push_gc_roots
return unless @__xml_global_state
LibGC.push_all @__xml_global_state, @__xml_global_state + XML_GLOBAL_STATE_SIZE
end

# TODO: provide a nicer interface to registering other roots pushers in GC
# See also fiber.cr
@@__xml_prev_push_other_roots : ->
@@__xml_prev_push_other_roots = LibGC.get_push_other_roots

LibGC.set_push_other_roots ->do
@@threads_mutex.synchronize do
@@threads.each do |thread|
thread.xml_push_gc_roots
end
end
@@__xml_prev_push_other_roots.call
end
end
2 changes: 2 additions & 0 deletions src/xml/libxml2.cr
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ lib LibXML
fun xmlSetGenericErrorFunc(ctx : Void*, f : GenericErrorFunc)

fun xmlGetNsList(doc : Doc*, node : Node*) : NS**

fun xmlGetGlobalState : Void*
end

LibXML.xmlGcMemSetup(
Expand Down

0 comments on commit d179297

Please sign in to comment.