Code generation
steve goldman
Steve.Goldman at Sun.COM
Thu Nov 8 07:13:08 PST 2007
Peter Helfer wrote:
> Hi all!
>
> After solving the thread-thing finally, i'm off to testing of my
> generated code.. after I figured out that I need to commit a
> CodeBuffer into a CodeBlob, I thought a RuntimeStub would match my
> needs; however to generate the RuntimeStub, I need to know the
> frame_complete as well as the frame size, and the OopMapSet for this
> 'static constructor':
>
> static RuntimeStub* new_runtime_stub(
> const char* stub_name,
> CodeBuffer* cb,
> int frame_complete,
> int frame_size,
> OopMapSet* oop_maps,
> bool caller_must_gc_arguments
> );
>
> - when using it with a CodeBuffer generated before; and return
> stub->entry_point(), is that thing completely working, i.e. I dont
> have to care about, where it is allocated (does this go into a
> CodeCache ?),
yes.
and about any relocations ? I just had some assertion
> problems with the relocs -- is there anything special to look for when
> generating code ?
Don't really understand what was the assertion?
>
> - the frame_complete is the offset of the code to the point, where
> this frame is at its maximum size, without arguments for the next
> invocation ?
This is the offset where sp is stable (and fp if any is also stable). It
is only used for trying to make the async call trace more stable.
>
> - the OopMapSet (my usual friend) - I am still missing that kind of
> good explanation for the OopMaps, and how to use them properly...
> especially that part here:
>
> OopMap* map = new OopMap(framesize, 0);
> oop_maps->add_gc_map(__ pc() - start, map);
> // this means that 0 oops have to be handled specially in this part, right ?
>
> Now lets assume I really wanted to put some Oops in my frame, I would
> want to use
> map->set_oop( VMReg local); - this VMReg can be used to depict either
> a real register or a location on stack, right ?
yes.
>
> enum {
> my_second_oop
> my_first_oop
> rbp
> return_pc
> framesize
> }
>
> could be a fictious frame layout; now how do I tell OopMap to include
> my_first_oop and my_second_oop ?
The slots for the oops are in 32bit quantities regardless of whether
oops are 32/64bits. Unlike register descriptions oops only need a single
oopmap to describe them (I'm going to fix that register thing one
day...). So you'd do
map->set_oop(VMRegImpl::stack2reg(my_first_oop));
...
Once you've generated one of these in the debugger you can do something
like "call map->print()" and see that the stack offset is what you think.
not that in 64bit world your enum needs 2 enum for each item, e.g.
my_second_oop, my_second_oopX
If you think understanding the differences between
Register/VMReg/OptoReg is ugly and complicated you should have seen it a
couple of years ago. :-)
Then there's framesize. The framesize in that constructor is measured in
words (32bits in 32bit world, 64bits in 64bit world). Oopmaps always
deal in frame units of 32bits (the size of a "VMReg") so this can be
confusing too. Good places to look at code examples is in
SharedRuntime_<cpu>.cpp where the save/restore registers code is. That
code doesn't deal with oops directly only callee save registers but it
should help.
--
Steve
More information about the hotspot-runtime-dev
mailing list