This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author vstinner
Recipients brett.cannon, dino.viehland, serhiy.storchaka, steve.dower, vstinner
Date 2016-12-15.09:17:04
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1481793425.53.0.93976785317.issue28924@psf.upfronthosting.co.za>
In-reply-to
Content
Serhiy: "Since almost all calls of PyEval_EvalFrameEx() are in the same file as its definition, I suppose the compiler can inline it even without PGO."

Let me check. My patch changes gen_send_ex() of genobject.c and _PyEval_EvalCodeWithName() of ceval.c. "gcc -O3" is able to inline PyEval_EvalFrameEx() in the same file (ceval.c), but not in a different file (genobject.c).

My patch also avoids an useless call to PyThreadState_GET()... Well, I'm not sure that it's worth it. I propose the change because the indirection now looks completely useless to me, but I didn't expect that it could break anything. With my patch, python-gdb.py is fixed. Steve says that Visual Studio is already fixed as well. So I don't know, it's up to you ;-)

--

gen_send_ex().

C code:
188	    gen->gi_running = 1;
189	    result = PyEval_EvalFrameEx(f, exc);
190	    gen->gi_running = 0;

x86_64 assembler (gcc -03):
=> 0x000000000047fe37 <gen_iternext+103>:	movb   $0x1,0x18(%rbp)
   0x000000000047fe3b <gen_iternext+107>:	callq  0x54b870 <PyEval_EvalFrameEx>
   0x000000000047fe40 <gen_iternext+112>:	movb   $0x0,0x18(%rbp)
   0x000000000047fe44 <gen_iternext+116>:	mov    %rax,%r12
   0x000000000047fe47 <gen_iternext+119>:	mov    0x18(%rbx),%rdi

I still see the call to PyEval_EvalFrameEx().

--

_PyEval_EvalCodeWithName().

C code:
4169        retval = PyEval_EvalFrameEx(f,0);

x86_64 assembler (gcc -03):
=> 0x000000000054ae30 <+2544>:  mov    0x3827f9(%rip),%rax        # 0x8cd630 <_PyThreadState_Current>
   0x000000000054ae37 <+2551>:  xor    %esi,%esi
   0x000000000054ae39 <+2553>:  mov    0x40(%rsp),%rdi
   0x000000000054ae3e <+2558>:  mov    0x10(%rax),%rax
   0x000000000054ae42 <+2562>:  callq  *0x70(%rax)

In this file, PyEval_EvalFrameEx() is inlined. I understand that the first instruction is the PyThreadState_GET() call which is an atomic read (single x86 instruction). My patch avoids the useless PyThreadState_GET(), since tstate must not change.
History
Date User Action Args
2016-12-15 09:17:05vstinnersetrecipients: + vstinner, brett.cannon, dino.viehland, serhiy.storchaka, steve.dower
2016-12-15 09:17:05vstinnersetmessageid: <1481793425.53.0.93976785317.issue28924@psf.upfronthosting.co.za>
2016-12-15 09:17:05vstinnerlinkissue28924 messages
2016-12-15 09:17:04vstinnercreate