On Thu, 27 Jan 2022 00:15:52 GMT, Tyler Steele <d...@openjdk.java.net> wrote:

>> src/hotspot/os/aix/loadlib_aix.hpp line 79:
>> 
>>> 77:   private:
>>> 78:     const loaded_module_t _module;
>>> 79:     const LoadedModuleList* _next;
>> 
>> While looking at this code, I realized how old it is (the copyright is 
>> wrong, this predates OpenJDK and was written ~2005). Today I would do some 
>> things differently, e.g. use a hash table for string interning.
>> 
>> About your change: `LoadedModuleList` is basically a duplication of the 
>> `entry_t`+`loaded_module_t` tupel. While I am not against it, it's 
>> duplication and a bit much boilerplate. You should at least redo the 
>> recursive deletion scheme. That will blow up if no tail call optimization 
>> happens.
>> 
>> I assume the whole copy list business is due to concurrent reloading? And 
>> because LoadedLibs does not offer an iteration interface?
>> 
>> If you feel up to it, I would simplify this:
>> - merge `entry_t` and `loaded_module_t` into one structure: give 
>> `loaded_module_t` a `next` pointer and get rid of entry_t. This is a scheme 
>> we use all over the hotspot (embedding list pointers directly into the 
>> payload structures) so it is fine and we save one indirection
>> - in LoadedLibs implementation, remove entry_t and use loaded_module_t 
>> directly
>> - in your new copy_libs, build up a list of copied loaded_module_t 
>> structures under lock protection like you do now with LoadedModuleList
>> - Do deletion in a loop, not recursively, with something like a new `static 
>> LoadedLibs::delete_list(loaded_module_t* list);`
>> 
>> Alternative: give LoadedLibs a callback-like functionality where you iterate 
>> the original list under lock protection and just call the given callback or 
>> closure class. In that closure, you call the original perfstat callback, so 
>> no need to pollute LoadedLibs with perfstat symbols.
>> 
>> Just as an info, in these files we tried to avoid JVM infrastructure, hence 
>> the plain `::malloc` instead of `os::malloc`  and we use none of the helper 
>> classes the JVM offers. E.g. instead of just using `GrowableHeapArray`, 
>> which would be nice and convenient. That is because using JVM infrastructure 
>> introduces dependencies to VM state and time (e.g. there are uninitialized 
>> time windows at startup), and we wanted this code to work as reliably as 
>> possible. Also should work during signal handling. Because the VM may crash 
>> at any point, and at any point we want to see call stacks and list of loaded 
>> libraries in the hs-err file.
>
> Thank you for the in-depth review. I appreciate the feedback. I am working on 
> this re-factor.

I performed the refactor (removing entry_t, and adding a next pointer to 
loaded_module_t). This was pretty straightforward, but required writing an 
explicit copy procedure since the new struct loaded_module_t no longer met the 
requirements of the compiler-generated one.

> Alternative: give LoadedLibs a callback-like functionality where you iterate 
> the original list under lock protection and just call the given callback or 
> closure class. In that closure, you call the original perfstat callback, so 
> no need to pollute LoadedLibs with perfstat symbols.

This is a good suggestion. I thought about doing it before, but I am used to 
tamping down my functional programming instincts when writing C. That said, 
this option required no additional memory allocation, so it removes any need 
for the class I wrote before. My implementation is a little brittle, as I chose 
to take os::LoadedModulesCallbackFunc, rather than a more general type (and 
having to construct a closure etc.). This should save on indirection for now, 
and could be extended in the future if needed.

-------------

PR: https://git.openjdk.java.net/jdk/pull/6885

Reply via email to