[External] : Re: Feedback / query on jextract for Windows 10
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Wed Jan 27 14:45:35 UTC 2021
Hi Duncan,
On Wed, 2021-01-27 at 14:36 +0000, Duncan Gittins wrote:
> Thanks, that's very helpful. Use of repeated --filter option solves
> my
> problem with huge jars - now down to 800k and cuts the first-time
> startup delay vs handcoded to around 50-150ms depending on the calls
> made.
I'm happy that the filter option worked for you! I still have to
investigate on the startup issue.
>
> It might be helpful if there was a command line option to set the
> output
> class name so the top level classname isn't derived from the header
> file
> name. I avoid static imports, and would prefer to call say
> "Ole32.CoInitializeEx()" than "shlobj_core.CoInitializeEx()" for
> code
> derived from shlobj_core.h.
I think this is a good suggestion. While inferring from header file is
a good "default" I agree that it should be possible to override this,
especially now that a single header file is generated (the reason we
don't have this is that it was harder to to in the previous design).
>
> This would also help for projects that had one master header file
> which
> set up #define for other includes. eg. Consider winuser.h:
>
> set "WINKIT=c:\Program Files (x86)\Windows
> Kits\10\Include\10.0.18362.0"
> jextract -luser32 -t duncan.win.user32 -d winuser.classes --
> filter
> winuser.h "%WINKIT%/um/winuser.h"
> => Fails error: "No Target Architecture"
>
> jextract -luser32 -t duncan.win.user32 -d winuser.classes --
> filter
> winuser.h "%WINKIT%/um/shlobj_core.h"
> => Works fine, but the top level class name is shlobj_core_h
> which
> would same class name as for this jextract:
>
> jextract -lshell32 -t duncan.win.shell32 -d shlobj_core.classes
> --filter shlobj_core.h "%WINKIT%/um/shlobj_core.h"
>
> However there is a very simple workaround: I can create a User32.h
> file
> which contains "#include <shlobj_core.h>"
Yes! I expect this kind of workaround to be unavoidable in the general
cases - especially when dealing with very large monolithic headers such
as Windows.h.
Ideally, one day, IDEs might provide some integration for this, so that
maybe when you extract you get a nice dialog with all the "discovered
symbols" and you can manually click on the ones you want to import.
This is why our aim is to provide not just a tool, but also some kind
of API, so that this kind of IDE plugin will, one day, be possible.
CheersMaurizio
>
> jextract -luser32 -t duncan.win.user32 -d winuser.classes --
> filter
> winuser.h -I "%WINKIT%/um" User32.h
>
> Duncan
>
> On 26/01/2021 17:25, Maurizio Cimadamore wrote:
> > Another fly by comment - have you tried using the --filter option
> > so
> > that jextract will just extract the header you want?
> >
> > e.g. you might try adding `--filter shlobj_core` and see what
> > happens
> > (but it might be too narrow of a filter).
> >
> > Maurizio
> >
> >
> > On 26/01/2021 15:43, Duncan Gittins wrote:
> > > I don't know what causes the speed difference, which may be down
> > > to
> > > the jar size as you suggest. I'll re-test after the time that
> > > "--source" generates same code as seen in the .class files when
> > > it
> > > may be easier to understand why there is a difference. I am
> > > using
> > > 16-panama+3-385.
> > >
> > > This isn't a very robust test, but I also tried deleted all the
> > > un-necessary .class files from the 11MB jextract generated
> > > classes
> > > (not produced using --source) down to 2MB jar, then I moved my
> > > handcoded method into a separate class and added a dependency on
> > > a
> > > different 2MB jar. Neither of those changes affected the typical
> > > speeds of first call times - I still consistently see that the
> > > hand
> > > coded method handle version of my app is ~300-500ms faster on
> > > first
> > > call, and no difference for 2nd+ calls.
> > >
> > > Duncan
> > >
> > > On 25/01/2021 16:18, Maurizio Cimadamore wrote:
> > > > On 25/01/2021 16:13, Duncan Gittins wrote:
> > > > > Thanks for the information. As you suspected that bug must
> > > > > be
> > > > > related and there is a minor difference in the --source
> > > > > output
> > > > > because the problem does go away when removing the jextract
> > > > > "--source" flag and making jar directly from generated
> > > > > classes
> > > > > rather than just compiling from the generated source code.
> > > > >
> > > > > My code samples using jextract bindings are ~300ms slower at
> > > > > startup time (but same speed runtime). I'm not certain if
> > > > > this
> > > > > overhead is down to initialisation of static constants or
> > > > > simply to
> > > > > be expected when adding 11MB jar footprint (compared to 56k
> > > > > jar for
> > > > > my handwritten MH bindings). I will follow-up if I find out
> > > > > more.
> > > > If you see the startup slowdown even when omitting --source,
> > > > then
> > > > the issue is with loading the jar, rather than initializing -
> > > > as
> > > > explaining no initializing should happen outside for stuff that
> > > > is
> > > > actually used by your code - so I'd expect that initialization
> > > > overhead for jextract code and your manually written versions
> > > > should
> > > > be roughly the same.
> > > > > Looking at the generated code for "xxx$constants$nn.java"
> > > > > there
> > > > > seems to be a degree of unnecessary initialisation per
> > > > > xxx$constants$nn class as it contains static variables for
> > > > > FunctionDescriptor / MemoryLayout which would be initialised
> > > > > every
> > > > > time that particular class was loaded and not used in my
> > > > > code. I
> > > > > felt that my own jar was slow starting so switched foreign
> > > > > linker
> > > > > references to a lazy load Supplier for every library / symbol
> > > > > / mh
> > > > > / vh so that only the referenced types get created.
> > > >
> > > > Sure - but that's only when --source is used - when you
> > > > generated
> > > > classes directly, everything is lazy (and in a more general way
> > > > than
> > > > using Suppliers).
> > > >
> > > > So, can you please confirm, to be clear, that you still see
> > > > startup
> > > > regression even when NOT using "--source" ?
> > > >
> > > > Thanks!
> > > > Maurizio
> > > >
> > > > > I will have a look at future builds - this project is
> > > > > extremely
> > > > > useful so I hope it gets into a full JDK release soon.
> > > > > Unfortunately my issue with a huge jar in Eclipse means I
> > > > > can't
> > > > > easily develop using the generated code variant right now,
> > > > > but in
> > > > > the meantime the jextract code is still very helpful to work
> > > > > out
> > > > > how to call Windows APIs correctly.
> > > > >
> > > > > Duncan
> > > > >
> > > > > On 25/01/2021 10:20, Maurizio Cimadamore wrote:
> > > > > > On 23/01/2021 18:34, Duncan Gittins wrote:
> > > > > > > I've been using Panama on Windows 10 to eliminate my C#
> > > > > > > apps
> > > > > > > which I would normally call via ProcessBuilder. I'm very
> > > > > > > impressed so far and looking forward to newer versions:
> > > > > > > everything I have written in Windows C# is now replaced
> > > > > > > with
> > > > > > > foreign memory / linker calls to native code using the
> > > > > > > latest
> > > > > > > Java 16 EA. I have examples for various Win32 API and
> > > > > > > COM
> > > > > > > objects, HWND objects and screensaver. However I'm
> > > > > > > struggling to
> > > > > > > get the code running with output from jextract build.
> > > > > > > Perhaps I
> > > > > > > overlooked something very obvious in how to setup?
> > > > > > >
> > > > > > > One example app is attached - this calls
> > > > > > > SystemParametersInfoA to
> > > > > > > set the Windows desktop background. There are two
> > > > > > > implementations
> > > > > > > of setImage: one with hardwired MethodHandle works fine,
> > > > > > > but the
> > > > > > > jextract version gives UnsupportedOperationException for
> > > > > > > layout
> > > > > > > unrelated to SystemParametersInfoA. If I edit the
> > > > > > > generated code
> > > > > > > to comment out all lines unrelated to
> > > > > > > SystemParametersInfoA then
> > > > > > > both versions of setImage work.
> > > > > >
> > > > > > I think the culprit is this:
> > > > > >
> > > > > > ```
> > > > > > Caused by: java.lang.UnsupportedOperationException:
> > > > > > Invalid
> > > > > > alignment requirements for layout
> > > > > > b64(ArbitraryUserPointer)[abi/kind=POINTER,layout/name=Arbi
> > > > > > traryUserPointer]
> > > > > > at
> > > > > > jdk.incubator.foreign/jdk.internal.foreign.LayoutPath.check
> > > > > > Alignment(LayoutPath.java:273)
> > > > > > at
> > > > > > jdk.incubator.foreign/jdk.internal.foreign.LayoutPath.deref
> > > > > > erenceHandle(LayoutPath.java:159)
> > > > > > at
> > > > > > jdk.incubator.foreign/jdk.incubator.foreign.MemoryLayout.la
> > > > > > mbda$varHandle$2(MemoryLayout.java:488)
> > > > > > at
> > > > > > jdk.incubator.foreign/jdk.incubator.foreign.MemoryLayout.co
> > > > > > mputePathOp(MemoryLayout.java:534)
> > > > > > at
> > > > > > jdk.incubator.foreign/jdk.incubator.foreign.MemoryLayout.va
> > > > > > rHandle(MemoryLayout.java:488)
> > > > > > at
> > > > > > duncan.win32.shobjidl_core.shlobj_core_h$constants$16.<clin
> > > > > > it>(shlobj_core_h$constants$16.java:1844)
> > > > > > ```
> > > > > >
> > > > > > This seems a duplicate of another issue that has been
> > > > > > reported
> > > > > > last week:
> > > > > >
> > > > > > https://bugs.openjdk.java.net/browse/JDK-8259832
> > > > > >
> > > > > > E.g. jextract ignoring alignment requirements. Note that
> > > > > > jextract
> > > > > > generates lots of constants, and it takes only one bad one
> > > > > > to make
> > > > > > initialization fail.
> > > > > >
> > > > > > > The jextract command on Windows 10 (with fresh Vis
> > > > > > > Studio
> > > > > > > installation) expands shlobj_core.h because I my app also
> > > > > > > uses
> > > > > > > IShellLink.
> > > > > > >
> > > > > > > set "WINKIT=c:\Program Files (x86)\Windows
> > > > > > > Kits\10\Include\10.0.18362.0"
> > > > > > > jextract --source -t duncan.win32.shobjidl_core -d
> > > > > > > shlobj_core.h/java "%WINKIT%/um/shlobj_core.h"
> > > > > > >
> > > > > > > Another issue is that this single windows header file
> > > > > > > gives rise
> > > > > > > to 11MB jar and is unusable inside Eclipse (on my slow
> > > > > > > PC), and
> > > > > > > is slow startup at runtime. Have you considered changing
> > > > > > > the
> > > > > > > generated code to use lazy Supplier<MethodHandle> instead
> > > > > > > of
> > > > > > > MethodHandle to ensure only required handles are created
> > > > > > > on-demand?
> > > > > >
> > > > > > Uhm... we are already using dynamic constants, so you
> > > > > > should only
> > > > > > pay for the MHs and VHs you use - e.g. in fact I'm even
> > > > > > surprised
> > > > > > you get the failure inside the <clinit> above - since that
> > > > > > constant should not be initialized unless it's used. I
> > > > > > wonder if
> > > > > > there's a regression here... are you using the `--source`
> > > > > > flag?
> > > > > > With that flag we revert back to a monolithic header, so
> > > > > > that will
> > > > > > explain both failures. If so, try removing that flag - and
> > > > > > see
> > > > > > what happens (if everything is working as it should I don't
> > > > > > think
> > > > > > you should even see the error above, assuming you never use
> > > > > > that
> > > > > > layout).
> > > > > >
> > > > > > Maurizio
> > > > > >
> > > > > > > Kind regards
> > > > > > >
> > > > > > > Duncan
> > > > > > >
> > > > > > >
More information about the panama-dev
mailing list