-
Notifications
You must be signed in to change notification settings - Fork 104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Another great bundle of messy stuff #1257
Conversation
Does that mean KOReader doesn't leak memory anymore ?! Well done ! :) |
In practice, it showed that most of our manual cleanup efforts did the job mostly correctly ;). (Hence the extra-shitty double-free guards in KOptContext, for instance ^^). As far as BB is concerned, I haven't really caught much that was missed, maybe a few tiny BBs during startup. Incidentally, that's the reason for a few finalizers using a dedicated function when they just call our old manual finalizer: that was to debug which is which when they trigger ;). |
I'm still utterly puzzled by where roughly 8MB of memory go each time a CRe document is opened (the only thing I can say is that's it's probably CRe logic unrelated to BB/DrawBuf, because it's not affected by the target buffer size), but the PDF stuff seem pretty solid, with clearly visible chunks of memory being reclaimed at runtime in a single document. DjVu appears to be a fairly bad student, and will eat a metric shitton of RAM each time you open a new page, and not reclaim any of it on close. |
I haven't been seeing that (looking at the footer Memory info). What I see is it raises a log when you do a dict lookup, show history,... and then stay there. |
Haven't tried a CRe -> CRe swap, so this may not actually all be at CRe's feet, but doing a CRe -> FM -> CRe nets me a ~4 to 5MB increase each time on Kobo. |
(A CRe -> CRe swap doesn't make a lick of difference over here, both with or without my mess applied, similar behavior between the H2O/Forma/emu ^^). |
A difference vs what ? :) You mean you get the same memory increase as CRe>FM>CRe ? Or that you get the same memory usage (no increase) ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note to self, read through blitbuffer and zstd.lua later
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks fine, no real comment.
@@ -20,15 +20,17 @@ set(ANTIWORD_INCLUDE_DIR ${CR_3RDPARTY_DIR}/antiword) | |||
set(CHM_INCLUDE_DIRS ${CR_3RDPARTY_DIR}/chmlib/src) | |||
set(CREGINE_INCLUDE_DIR ${CRE_DIR}/include) | |||
|
|||
assert_var_defined(JCONFIG_INCLUDE_DIR) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason for you to move this at top ? Looks a bit related to JPEGLIB - or may be not, dunno :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was to keep the same order as the order in which they're defined/used below ;).
@@ -360,7 +360,7 @@ class XText { | |||
if (m_bidi_ctypes) { free(m_bidi_ctypes); m_bidi_ctypes = NULL; } | |||
if (m_bidi_btypes) { free(m_bidi_btypes); m_bidi_btypes = NULL; } | |||
if (m_bidi_levels) { free(m_bidi_levels); m_bidi_levels = NULL; } | |||
if (m_lang) { delete m_lang; m_lang = NULL; } | |||
if (m_lang) { delete[] m_lang; m_lang = NULL; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this change anything in any way in what the compiler would do ? Or it's just for sake of correctness?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It deletes the entire array of characters instead of the first one. Until now the memory of the rest of characters was leaked on each deallocation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get the idea.
But it's one single thing I created/allocated with m_lang = new char[strlen(lang)+1];
- so I find it strange the compiler would just delete the first char (a fragment of that thing, while it knows how much was allocated). It's my idea the compiler would do the right thing, but I don't know him personally :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know him personally :)
Me neither 😄
But C++ is a humongous beast with operator overloading and other stuff and this specific behaviour is forbidden. See https://isocpp.org/wiki/faq/freestore-mgmt#delete-array-built-ins
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's apparently mostly harmless on Linux, but, that is admittedly an implementation detail, and Valgrind was certainly unhappy about it ;).
EDIT: Oh, read through the link, yeah, operator overloads would certainly complicate the matter ^^.
Yep, same increase. Checking statm manually, the increase is actually in two steps: on close, and then on open. c.f., emu:
Kobo:
|
I also think I have a vague idea of why djvu is stuffing itself like crazy, I'll see if I can tame it a bit. EDIT: Nope that's just the Cache's watermark being high ;). |
Slightly more subtle than that, which means possibly not all-that-CRe-related ;). (On the H2O w/ this applied)
etc. ;). Soooo, probably not so much CRe's fault ;p. (Whether xtext is enabled or not has not much bearing on the results, FWIW). |
Horray. I admire zstd. I wIll test this bunch of commit tomorrow. +5 from my side :)) |
@poire-z: FWIW, now that I finally have a somewhat readable Valgrind output (hi, koreader/koreader#6980), most, if not all, of the "still reachable" stuff is from FT/HB. It's a bit hard to dig into that, because AFAICT, LuaJIT doesn't unload packages on exit (and we don't really have teardown facilities in place anyway), so it's hard to judge which of those pointers are actually expected to stay alive (i.e., cached stuff). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 30 of 30 files at r1.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @poire-z)
History cleaned up (use a merge commit to merge); detailed history archived in https://github.com/NiLuJe/koreader-base/tree/cbb-c99_archive |
316a72d feels like it doesn't deserve its own commit - and could be squased in the main commit(s) that touched these parts.
Isn't "Rebase and merge" cleaner ? (no strange "Merge pull request..." additional commit that seems to redo what the previous do). |
Agreed, but it was simply too hellish to re-order in terms of merge conflicts ;).
It makes it clear that a series of commits belonged to a single PR (besides the tiny, tiny mention about that in GitHub's UI when looking at individual commits). I'm not generally a fan of it, but when the series is as "messy" as these, it kinda helps a bit? |
A tiny little wee bit, ok :) There's another little thing I don't like much, it's the commit timestamps. I'd rather have them all the date of the merge, that a mix of misordered date from the last 2 weeks (which may make following the changes a bit confusing). |
|
I think I needed the |
Okay, Busted apparently has a really hard time dealing with cdata finalizers (even when running Busted master, which supposedly does it better), so, ensure the tests properly cleanup behind themselves. Also, finally fix the KOptContext language thingy so that it stops randomly failing because that's not how you copy a C string ;p. |
* Tighter scope, const, restricted pointers * Avoid array indexing where possible * Use unsigned data types for dimensions/sizes That's really what the code expects, and everything is already bounds-checked on the Lua side. * Resync dither_o8x8 w/ FBInk * In the few places that weren't already doing so, cadge a few shifts by relying on pointer arithmetic rules, much like BB_GET_PIXEL * Implement ditheralphablitFrom (straight alpha) * Move the helper macros to the header, it's useful for C consumers * ffi/blitbuffer: Clear up a c/p snafu w/ invertBlitFrom * ffi/blitbuffer: Good-bye, lovingly handcrafted BMP encoding ;)
* Also, make sure make dist-clean works in front * nnsvg: Enable the BB type check, now that it's available
* Build CRe w/ zstd support * Other minor CRe build cleanups after koreader/crengine#399 * Move zlib FFI from xutil in the coverbrowser plugin to a dedicated module * As far as our wrapper goes, the ZSTD one differs from zlib in that it has switched to explicit memory allocation: Instead of taking/returning a Lua string copy, take/return a cdata ptr, size tuple. (Technically, void *, size_t)
* When *getting* a BLOB, return instead a tagged table, with the first elements being the (void) pointer, and the second the amount of data in bytes. * When *setting* a blob, free the original pointer: SQL_TRANSIENT means SQLite's just made a copy of it.
* Allow reusing a zstd decompression context * Handle the context's lifetime via a cdata finalizer
(c.f., comments in ffi/blitbuffer) * BlitBuffer: handle it via an explicit cdata finalizer in setAllocated Move BlitBuffer memory management to FFI cdata finalizer * KoptContext: put the __gc metamethod in the right place, and add a bunch of double-free guards now that it actually triggers. * Made NULL pointer checks more explicit: ctypes are sticky; assigning nil to a cdata<ptr> makes that a NULL ptr, not a plain lua nil, meaning if foo is *true* for a foo cdata NULL ptr. (This is clearer in vanilla libffi, where NULL/nullptr is usually a dedicated constant, e.g., ffi.NULL). * MuPDF: via explicit cdata finalizers * Comment out the useless __gc methods in ffi/pic * Import https://github.com/katlogic/__gc To make the very last few things that tried to do this on plain tables in front actually work...
* Don't leave a dangling dom_doc pointer * When debugging, implement a _fini to make Valgrind happier about CRe This'll run on library unload (i.e., on exit).
Fix LuaCheck warnings: ffi.gc does return the cdata unchanged We apparently can't use a local function as a finalizer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 11 of 11 files at r2.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @poire-z)
Also resync GH workflow with front
ensure proper teardowns are put into place, because Busted can't deal with cdata finalizers sanely. Fix KOptContext language copy: Make sure it's NUL terminated, it's a C string.
* Handle CFLAGS & LDFLAGS via env vars, it's less likely to implode in fun and interesting ways down the line... * Refresh ZSTD ffi wrapper for v1.4.7
* In the C variant, pack the pixels ourselves instead of going through the Color structs, as it generates shorter code. (We probably should make that clearer like with the union trickery in FBInk). * Fix a number of inconsistencies in how the invert flag was sometimes mishandled in the Lua blitter (it's still completely ignored by the C blitter). * Handle inversion in Lua fill * Fix a bug where, in most blend methods, the inversion flag was only honored when blending, and not for the fully opaque fast path...
(Latest history archived in https://github.com/NiLuJe/koreader-base/tree/cbb-c99-front_archive_r2 (nice typo!) :D). |
Companion to koreader/crengine#399
Much like over there, I intend to somewhat cleanup the history before merge.
CBB:
(This makes the diff a horrible mess to read, so, don't, and hope there aren't any more typos than those I already caught ;D).
LBB:
Add ZSTD and an FFI binding.
Rejig our understanding and usage of the
__gc
metamethod: it doesn't run on plain tables in Lua 5.1, only on userdata. In LuaJIT, it's also usable on cdata metatypes, and cdata finalizers can also be setup explicitly.Convert stuff to the sanest solution in each case, and, in cases where it's not possible, use the hacky workaround of introducing an empty
newproxy
userdata in the mix, via ffi/__gc.This finally solves a number of puzzling code comments that were wondering why the hell our __gc methods were never called (hint: because it's not supported, or, in a few cases it's not supported and they were misnamed anyway ^^).
Tweak lj-sqlite3 to stop coercing BLOBs as Lua strings. Instead return a raw pointer and a byte count, like the SQLite C API. This allows avoiding a few useless copies in BookInfo, our sole user of BLOB. It also just plain makes sense, because if I wanted strings, I'd be using a TEXT column ;).
Use proper symbol visibility discipline for our Lua/C modules, much like was done in nnsvg. This avoids leaking a ton of useless symbols, and makes the dynamic loader's job that much easier.
Update the stbiw version shipped by NanoSVG to the latest one (only used by a CRe helper function).
Fun Valgrind experiments in cre.cpp if DEBUG_CRENGINE is set ;p.
This change is![Reviewable](https://camo.githubusercontent.com/23b05f5fb48215c989e92cc44cf6512512d083132bd3daf689867c8d9d386888/68747470733a2f2f72657669657761626c652e696f2f7265766965775f627574746f6e2e737667)