Zaheer, an idea: setup a tiny stub which will call into API function indirectly (using a register) and would be pretty much like CEntryStub: only single instance of this stub and generated early enough to never get moved. You probably should just add it into ARM specific stub list in src/code-stubs.h.
Of course, indirect call and jump to/from this tiny stub adds an overhead, but let's hope it's acceptable. Do you have some cycles to measure performance implications of indirect call? And answering your question about CEntryStub. That is to some extent pure luck: all the objects allocated in code space (special part of the heap to keep generated code) before CEntryStub code should be not collectable (various parts of core v8 infrastructure), hence we cannot have free space before the code of CEntryStub and hence cannot move it. And yes, it's somewhat scary. yours, anton. On Wed, Jan 19, 2011 at 3:12 PM, <[email protected]> wrote: > On 2011/01/19 11:23:26, SeRya wrote: >> >> On 2011/01/19 06:19:44, zaheer wrote: >> > Thanks serya for comments. I checked this patch with a moving stub test >> > and > > it >> >> > seems to work. details below. >> > >> > On 2011/01/18 19:01:57, SeRya wrote: >> > > >> > > > http://codereview.chromium.org/6170001/diff/44002/src/arm/macro-assembler-arm.cc >> >> > > File src/arm/macro-assembler-arm.cc (right): >> > > >> > > >> > > > http://codereview.chromium.org/6170001/diff/44002/src/arm/macro-assembler-arm.cc#newcode1478 >> >> > > src/arm/macro-assembler-arm.cc:1478: Call(function->address(), >> > > RelocInfo::RUNTIME_ENTRY); >> > > This will be translated into >> > > mov(lr, Operand(pc), LeaveCC, cond); >> > > mov(pc, Operand(target), LeaveCC, cond); >> > > (or equivalent with blx). >> > > >> > > The register is unreachable for GC which needs to fix the return >> > > address > > if >> >> > the >> > > code has been moved, isn't it? >> > The first instruction in the native callback pushes the lr in the first > > stack >> >> > slot. I point the exit frame pc to it and it gets patched. >> > >> > callback is native callback >> > (gdb) bt >> > #0 callback (args=@0xbec33bb8) at >> > external/v8/v8_latest/directcall.cc:59 >> > #1 0x4087d0b0 in ?? () >> > >> > The first instruction pushes lr which is pointed to by exit frame pc >> > Dump of assembler code for function _Z8callbackRKN2v89ArgumentsE: >> > 0x0001d9ac <_Z8callbackRKN2v89ArgumentsE+0>: push {r4, r5, r6, lr} >> > >> > (gdb) x/4x $sp >> > 0xbec33ba8: 0x001ac80c 0x001ad6b8 0x00000003 0x4087d0b0 >> > (lr) >> > >> > GC moves the stub >> > forward 0x4087cfc0 -> 0x4087cc40. >> > >> > lr is patched >> > (gdb) x/4x 0xbec33ba8 >> > 0xbec33ba8: 0x001ac80c 0x001ad6b8 0x00000003 0x4087cd30 >> > (patched) >> > >> > (gdb) bt >> > #0 0x0001d9e0 in callback (args=<value optimized out>) at >> > external/v8/v8_latest/directcall.cc:68 >> > #1 0x4087cd30 in ?? () --> modified return address >> > >> > native function uses modified lr to return >> > 0x0001d9e0 <_Z8callbackRKN2v89ArgumentsE+52>: pop {r4, r5, r6, pc} > >> I can't find a place in ARM ABI docs what would require this behavior. Is >> this > > a >> >> compiler specific stuff? If so it's not a good idea to rely on it. > > Yes, i agree the return should be caller controlled. > >> > > Apparently the only way to survive code relocation is to make the lr >> register >> > to >> > > point to an unmovable piece of code. >> > in this case how do we return to a moving stub? > >> I actually see 2 ways to deal with it (it only make sense if the stuff >> above > > is >> >> really compiler specific): > >> a. >> 1. Push return address on stack (it will make it accessible to GC). >> 2. Set up the lr register pointing to the "pop pc" instruction >> in unmovable code. > > I guess this would need to create a new stub with single instruction similar > to > centry > >> b. >> 1. Make the rest of code above >> Call(function->address(), RelocInfo::RUNTIME_ENTRY); >> to be unmovable. >> Apparently it doesn't depend on args. >> 2. Put a pointer to that code to lr. >> 3. Jump to the C function. > > since this is not feasible will try a) > >> The second approach would share some piece of code and probably faster. >> But > > I'm >> >> afraid there is no good method to make a code unmovable for now. In other >> case >> there wouldble be such a comment in CEntryStub::Generate: > >> // TODO(1242173): To let the GC traverse the return address of the exit >> // frames, we need to know where the return address is. Right now, >> // we push it on the stack to be able to find it again, but we never >> // restore from it in case of changes, which makes it impossible to >> // support moving the C entry code stub. This should be fixed, but >> currently >> // this is OK because the CEntryStub gets generated so early in the V8 >> boot >> // sequence that it is not moving ever. > > curious why stub created early doesnt move. > > > http://codereview.chromium.org/6170001/ > -- v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev
