From: Nuutti Kotivuori <naked+caml@naked.iki.fi>
To: caml-list@inria.fr
Subject: [Caml-list] [PATCH] Dynamic freeing of dynamically loaded code
Date: Mon, 22 Dec 2003 09:55:40 +0200 [thread overview]
Message-ID: <873cbdqoar.fsf@naked.iki.fi> (raw)
* NOTE * NOTE * NOTE * NOTE * NOTE * NOTE * NOTE * NOTE * NOTE * NOTE *
This is a preliminary release of this patch and contains requires
still a lot of tweaking to be decently usable. Feel free to play
around with it, but don't expect it to work or solve your problems.
* NOTE * NOTE * NOTE * NOTE * NOTE * NOTE * NOTE * NOTE * NOTE * NOTE *
Yuletime tidings!
So, as the questions on the list on how to make dynamically loaded
code garbage collectable evolved into implementation plans, now the
implementation plans evolved into actual code.
I'll outline really briefly what the implementation consists of:
- Staticalloc module to have static_alloc'd blocks that are freed on
finalization.
- Modification to byterun - on CLOSURE and CLOSUREREC instructions,
if nvars is below zero, negate it before using and append the last
element of current env into the created closure.
- Explanation: making two new bytecode instructions, CLOSUREDYN and
CLOSURERECDYN, proved to be more difficult than I assumed, so I
went the trivial way for now.
- Implement reify_bytecode_with_ref - do as reify_bytecode, but go
through the codeblock and negate all nvars parameters to CLOSURE and
CLOSUREDYN and append given ref to the closure generated.
- Make Dynlink use all this.
- Fix utils/consistbl.ml to only store last crc given for an
interface name. Should not affect functionality at all, but prevents
memory bloat. (In the process of finding this I also noticed that
Hashtbl resizing will use a non-tail-recursive function to reallocate
a single bucket - and if that bucket is large enough: stack
overflow. I filed a bug report on this already.)
What is the result now then:
- Running Dynlink.loadfile "test.cmo";; on a file 1,000,000 times
results a memory image rougly 12Mb when finished. Even 50,000 times
used to make it 40Mb and crash on a stack overflow. Since the memory
image of ocamlrun at start seems to be around 4Mb, a conservative
estimate for the amount of memory taken by the loading would be 8Mb -
that is, roughly 8 bytes per load. And atleast four bytes will
necessarily go to the allocation of a new global on each time around.
- Performance impacts of this on either normal bytecode, or
dynamically loaded code, were totally unnoticeable. Somebody should
run a much longer tests and prepare them better though. The impact of
the code should be that executing CLOSURE and CLOSUREDYN instructions
is a tiny bit more expensive, and each closure created from
dynamically loaded code takes one word more memory.
What are the limitations then:
- If the module defines any toplevel functions, it cannot ever be
freed, because the closures are referenced from the global
table. This is true even for loadfile_private. Eg. code that defines
functions will still not be garbage collected.
- If the module has any literals, the literals will not be freed and
will be reallocated on each time it is loaded.
- The global_data table will bloat for each load and the space will
not be reclaimed.
- Toploop doesn't use this yet.
What next:
- Removing the limitations as much as possible - some might be
unavoidable, but the cost shouldn't be higher than what it is now -
and 8 bytes per loaded file is quite acceptable in all but the
stringest environments.
So, in summary:
SUCCESS!
There is still a lot to do, though, and I will keep on working on the
implementation. Any review on the code anyone might wish to do would
be welcome indeed - as well as general comments on the subject.
I fear to attach the diff here as I don't know the policy of this list
on them, so I will put it online. If it's okay to post patches here, I
will do so in future revisions of this code. Also I wonder how I might
supply this patch when it's finished to the OCaml maintainers - they
will probably wish to do several things differently though - or if
just having it here on the mailing list is enough.
The patch should be applied on top of a current cvs checkout of
ocaml. Making it compile is a bit tricky though. I include hand hacked
Makefile and .depend changes in it to make it easier - yet I didn't
wish to supply a new ocamlc binary or anything. When starting to use
the code, first run 'make world' - this will break at some point
because the primitives are different - after that do 'make bootstrap',
which should complete gracefully. After that you can do whatever, like
'make clean', 'make world.opt' and 'make install' - everything should
work.
So, here's the link:
http://www.iki.fi/naked/ocaml-dynlink-free.diff
Thanks for listening, and have a nice holiday everyone!
-- Naked
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
next reply other threads:[~2003-12-22 8:52 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-12-22 7:55 Nuutti Kotivuori [this message]
2003-12-22 11:43 ` Richard Jones
2003-12-22 17:04 ` Nuutti Kotivuori
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=873cbdqoar.fsf@naked.iki.fi \
--to=naked+caml@naked.iki.fi \
--cc=caml-list@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox