These are chat archives for dropbox/pyston

10th
Jun 2015
Marius Wachtler
@undingen
Jun 10 2015 00:30
yeah. tracing jit stopped crashing all the time :-D
Chris Toshok
@toshok
Jun 10 2015 00:31
nice :)
Marius Wachtler
@undingen
Jun 10 2015 00:33
ok I have first results for microbenchmarks/prime_summing.py:
it takes 7secs with the interpreter without tracing (and disabled jitting) and 2 secs with tracing jit + runtime ics (for compare and binop)
it outputs the same value but haven't verified if it really does the same... :-D
Chris Toshok
@toshok
Jun 10 2015 00:35
wow, impressive speedup
Marius Wachtler
@undingen
Jun 10 2015 00:35
oh and I decreased the number of iterations of prime summing because it took to long
Marius Wachtler
@undingen
Jun 10 2015 00:43
while exciting I still should go to sleep now :-D. see you tomorrow
Kevin Modzelewski
@kmod
Jun 10 2015 00:51
nice!
Rudi Chen
@rudi-c
Jun 10 2015 00:59
So turns out that it's not safe to calls finalizers from gcallocations. Also, adding finalizers makes django-template go from 12.3s to 17.0s --
Chris Toshok
@toshok
Jun 10 2015 01:02
hm, why isn’t it safe to call them?
is the 17.0s just with creating the list of finalizers but not calling them? or are they being called someplace else?
i moved the handling of the unwind state out of unwindProcessFrame, but ended up having to duplicate that piece all over unwinding.cpp (it might not be 100% necessary in every case but I didn’t want to chance it.)
I can put that call into unwindPythonStack itself, but that one shows roughly how it would be used to limit the calls and keep the logic out of unwindProcessFrame
Rudi Chen
@rudi-c
Jun 10 2015 17:32
@toshok Allocations can be called from compiled functions that don't create frame information. So if the finalizer has code that eventually requires a traceback, it fails to find that information and crashes.
17.0s includes calling the finalizer (it's the total runtime of the test)
I need to break down how much is calling the finalizer vs ordering them though.
Chris Toshok
@toshok
Jun 10 2015 17:35
"requires a traceback” = does introspection (like sys._getframe) or throws an exception?
Rudi Chen
@rudi-c
Jun 10 2015 17:36
Exception - this is a traceback that happened with virtualenv:
#0  0x00007ffff55e9cc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ffff55ed0d8 in __GI_abort () at abort.c:89
#2  0x00000000008b6b6d in abort () at /home/vagrant/pyston/src/runtime/stacktrace.cpp:156
#3  0x00000000007c0d21 in pyston::PythonFrameIteratorImpl::getCurrentStatement (this=0xc9bcd70)
    at /home/vagrant/pyston/src/codegen/unwinding.cpp:348
#4  0x00000000007c62b5 in pyston::lineInfoForFrame (frame_it=...)
    at /home/vagrant/pyston/src/codegen/unwinding.cpp:524
#5  0x00000000007c6264 in operator() (this=0xca57110, 
    frame_iter=<error reading variable: Cannot access memory at address 0x2713>)
    at /home/vagrant/pyston/src/codegen/unwinding.cpp:588
#6  0x00000000007c6032 in std::_Function_handler<bool (std::unique_ptr<pyston::PythonFrameIteratorImpl, std::default_delete<pyston::PythonFrameIteratorImpl> >), pyston::getTraceback()::$_0>::_M_invoke(std::_Any_data const&, std::unique_ptr<pyston::PythonFrameIteratorImpl, std::default_delete<pyston::PythonFrameIteratorImpl> >) (__functor=..., 
    __args=...) at /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/functional:2056
#7  0x00000000007bd56b in std::function<bool (std::unique_ptr<pyston::PythonFrameIteratorImpl, std::default_delete<pyston::PythonFrameIteratorImpl> >)>::operator()(std::unique_ptr<pyston::PythonFrameIteratorImpl, std::default_delete<pyston::PythonFrameIteratorImpl> >) const (this=0x427abeb5c0, __args=...)
    at /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/functional:2464
#8  0x00000000007bcf6d in pyston::unwindPythonStack(std::function<bool (std::unique_ptr<pyston::PythonFrameIteratorImpl, std::default_delete<pyston::PythonFrameIteratorImpl> >)>) (func=...)
    at /home/vagrant/pyston/src/codegen/unwinding.cpp:467
#9  0x00000000007bd81b in pyston::getTraceback () at /home/vagrant/pyston/src/codegen/unwinding.cpp:587
#10 0x00000000008b6982 in pyston::_printStacktrace () at /home/vagrant/pyston/src/runtime/stacktrace.cpp:112
#11 0x00000000008b6a63 in abort () at /home/vagrant/pyston/src/runtime/stacktrace.cpp:138
#12 0x00000000007c0d21 in pyston::PythonFrameIteratorImpl::getCurrentStatement (this=0xc9af160)
    at /home/vagrant/pyston/src/codegen/unwinding.cpp:348
#13 0x00000000007c62b5 in pyston::lineInfoForFrame (frame_it=...)
    at /home/vagrant/pyston/src/codegen/unwinding.cpp:524
#14 0x00000000007c6264 in operator() (this=0xca10600, 
    frame_iter=<error reading variable: Cannot access memory at address 0x2713>)
    at /home/vagrant/pyston/src/codegen/unwinding.cpp:588
#15 0x00000000007c6032 in std::_Function_handler<bool (std::unique_ptr<pyston::PythonFrameIteratorImpl, std::default_delete<pyston::PythonFrameIteratorImpl> >), pyston::getTraceback()::$_0>::_M_invoke(std::_Any_data const&, std::unique_ptr<pyston::PythonFrameIteratorImpl, std::default_delete<pyston::PythonFrameIteratorImpl> >) (__functor=..., 
    __args=...) at /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/functional:2056
#16 0x00000000007bd56b in std::function<bool (std::unique_ptr<pyston::PythonFrameIteratorImpl, std::default_delete<pyston::PythonFrameIteratorImpl> >)>::operator()(std::unique_ptr<pyston::PythonFrameIteratorImpl, std::default_delete<pyston::PythonFrameIteratorImpl> >) const (this=0x427abec2a0, __args=...)
    at /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/functional:2464
#17 0x00000000007bcf6d in pyston::unwindPythonStack(std::function<bool (std::unique_ptr<pyston::PythonFrameIteratorImpl, std::default_delete<pyston::PythonFrameIteratorImpl> >)>) (func=...)
    at /home/vagrant/pyston/src/codegen/unwinding.cpp:467
#18 0x00000000007bd81b in pyston::getTraceback () at /home/vagrant/pyston/src/codegen/unwinding.cpp:587
#19 0x00000000008b6364 in pyston::raiseExc (exc_obj=0x1270930848)
    at /home/vagrant/pyston/src/runtime/stacktrace.cpp:63
#20 0x00000000008b6e1f in pyston::raiseExcHelper (cls=0x1d7c658 <_PyExc_AttributeError>, 
    msg=0x1605d1e "%s instance has no attribute '%s'") at /home/vagrant/pyston/src
kmod has suggestions about adding flags to allowGLReadreemption about whether to perform potentially expensive operations though
Chris Toshok
@toshok
Jun 10 2015 17:38
nod. although I don’t know that that state can be statically determined at the callsite
it might also end up needing to be some global flag that the gc sets to true when it sees many finalizers queuing up
Rudi Chen
@rudi-c
Jun 10 2015 17:40
For now I made the finalizer list (and weakref callback list) visible so that allowGLReadPreemption checks if they are empty before making a function call, I think that should help a bit with performance.
Chris Toshok
@toshok
Jun 10 2015 17:40
having finalizers run on a thread that’s already running python has interesting traceback implications though. right now sys._getframe will happily walk up the C stack until it finds another python frame (even if the frame is beyond the finalizer)
nod
are you inserting calls to allowGLRP elsewhere in the code, or is this with the safe point workaround?
Rudi Chen
@rudi-c
Jun 10 2015 17:42
I didn't add more calls to allowGLRP.
Marius Wachtler
@undingen
Jun 10 2015 17:48
Did I understand you guys correctly that the problem you are talking about is that:
we have an instance of a class implemented using the CAPI which has a __del__ which raises an exception inside it. And if we would call this one during a collection we wound not find a python callstack for the __del__ function?
Rudi Chen
@rudi-c
Jun 10 2015 17:49
It's not specifically the __del__ function that is missing a callstack
I was trying to have call callPendingFinalizers in gc_alloc, but you could have a stacktrace like regular stuff -> compiled function without frame info -> call to gc_alloc -> call to finalizers -> exception
Something like this (part of the same stacktrace as the previous one, but lower down):
    at /home/vagrant/pyston/from_cpython/Modules/_io/iobase.c:213
#69 0x0000000000930c55 in iobase_dealloc (self=0x12712d3a68)
    at /home/vagrant/pyston/from_cpython/Modules/_io/iobase.c:290
#70 0x0000000000891152 in pyston::subtype_dealloc (self=0x12712d3a68)
    at /home/vagrant/pyston/src/runtime/objmodel.cpp:346
#71 0x000000000080bb66 in pyston::gc::finalize (b=0x12712d3a68) at /home/vagrant/pyston/src/gc/heap.cpp:169
#72 0x000000000080319a in pyston::gc::callPendingFinalizers () at /home/vagrant/pyston/src/gc/collector.cpp:525
#73 0x00000000015b75b7 in gc_alloc (bytes=16, kind_id=pyston::gc::PYTHON)
    at /home/vagrant/pyston/src/gc/gc_alloc.h:47
#74 0x0000000000822923 in pyston::BoxedInt::operator new (size=16) at /home/vagrant/pyston/src/runtime/types.h:398
#75 0x00000000015b7249 in pyston::boxInt (n=-1) at /home/vagrant/pyston/src/runtime/inline/boxing.cpp:78
#76 0x00007ffff3f6b1b6 in insertText_e2_168 ()
    at /home/vagrant/pyston/test_env/site-packages/pip/_vendor/html5lib/treebuilders/etree.py:113
#77 0x00007ffff3f7e072 in insertText_e2_166 ()
    at /home/vagrant/pyston/test_env/site-packages/pip/_vendor/html5lib/treebuilders/_base.py:320
#78 0x00007ffff3ff8a78 in processSpaceCharacters_e1_155 ()
    at /home/vagrant/pyston/test_env/site-packages/pip/_vendor/html5lib/html5parser.py:1000
#79 0x000000000089fd83 in pyston::callChosenCF (chosen_cf=0xc46c8c0, closure=0x0, generator=0x0, 
    oarg1=0x12707b5b08, oarg2=0x12716f9c08, oarg3=0x0, oargs=0x0)
    at /home/vagrant/pyston/src/runtime/objmodel.cpp:3298
Marius Wachtler
@undingen
Jun 10 2015 17:55
So what we need is a try {} catch block inside callPendingFinalizers and a change to the unwinder to unwind until the try catch block even if it can't find line info?
Rudi Chen
@rudi-c
Jun 10 2015 17:58
Oh interesting. I just realized that I never paid attention to the case where a natively implement tp_dealloc function (here iobase_dealloc) throws an exception.
For Python-implemented __del__ functions, I already wrap the exception in try {} catch and print a warning that finalizers should not throw exceptions (which is what the Python specs suggest doing).
Marius Wachtler
@undingen
Jun 10 2015 18:06
But for c type implementations you are hitting the issue that finding a frame is mandatory otherwise it will crash (even though it's fine for this particular case that there is no traceback available)? (I'm just asking out of curiosity - would like to understand what the issue is)
Chris Toshok
@toshok
Jun 10 2015 18:10
Which compiled functions do we generate without unwind info?
Rudi Chen
@rudi-c
Jun 10 2015 18:10
@undingen Yes, at frame #11 in getCurrentStatement, cf->code_start corresponds to the function insertText_e2_168 which doesn't have frame info.
(And getCurrentStatment is where the abort happens/RELEASE_ASSERT gets triggered)
Chris Toshok
@toshok
Jun 10 2015 18:11
Re: continuing to unwind - that should be fine, we just have to relax the restriction that ips inside Python functions might lack line info, whether that's something we want more than the alternatives...
But in this particular case we shouldn't be seeing that frame at all
And won't once the incremental tb stuff goes in
Chris Toshok
@toshok
Jun 10 2015 18:21
Man gitter on mobile is rough :)
Kevin Modzelewski
@kmod
Jun 10 2015 19:31
I think it's going to be a losing battle to try to call finalizers from anywhere we do allocations...
even if we find a workaround for the frame introspection stuff, now that we're going to be doing allocations from the exception unwinder (for tracebacks) we'd have to worry about making it safe to call finalizers there
Chris Toshok
@toshok
Jun 10 2015 19:31
i’m kinda of the opinion that it’s a losing battle (and going to be the source of annoyances as well as bugs) if we try to call them from anywhere but another thread :)
we can always wake up the finalizer thread and block the waking thread. that way we should be guaranteed some amount of isolation
Kevin Modzelewski
@kmod
Jun 10 2015 19:32
and also exceptions aren't the only way that destructors can investigate the stack
ex sys._getframe will run into the same lack-of-frame-introspection issue
Chris Toshok
@toshok
Jun 10 2015 19:33
right. that’s a workaround I’d rather not add
if (ipIsInCallFinalizers(&cursor)) { /* stop unwinding */ }
Marius Wachtler
@undingen
Jun 10 2015 20:22
oh the unwinder can also alloc memory??? But yeah sounds like it has to if it generates the traceback...
Chris Toshok
@toshok
Jun 10 2015 20:24
yeah. I can lessen the number of gc allocations, but they need to happen at least when/if we jump to a landing pad
oh we can potentially be really sneaky and only materialize traceback objects when they’re asked for, but ugh :)
Marius Wachtler
@undingen
Jun 10 2015 20:32
We already have this one: remove the -T command line arg and run the test script again and it will display a traceback :-P
Chris Toshok
@toshok
Jun 10 2015 20:47
hm, is there a way to run pyxl without using the # coding: pyxl?
sorry, an easy way that pyxl supports. I’m sure I can duplicate what #coding does :)
Marius Wachtler
@undingen
Jun 10 2015 21:15
You could probably directly call the PyxlStreamReader decoder inside pyxl/pyxl/codec/register.py. Put it should also get registered... so maybe "<foo>".decode("pyxl") is enough?
Chris Toshok
@toshok
Jun 10 2015 21:15
i found pyxl_transform_string (in register.py)
which seems to do the trick
funny that gitter tried to autocorrect pyxl with pixel
Marius Wachtler
@undingen
Jun 10 2015 21:16
oh yeah or call that one directly :-D
Chris Toshok
@toshok
Jun 10 2015 21:16
unfortunately it removes most of the codec machinery from the benchmark, but I think that’s ok
Marius Wachtler
@undingen
Jun 10 2015 21:17
The first few times the project got mentioned I always thought it's a graphics framework
Chris Toshok
@toshok
Jun 10 2015 21:19
hm, should I be adding git submodules for other libraries? babel, etc?
so that I can add minibenchmarks for them
Chris Toshok
@toshok
Jun 10 2015 21:25
Chris Toshok
@toshok
Jun 10 2015 21:32
wow, pycparser spends 10% of its time in llvm::MachineInstr::addOperand
Travis Hance
@tjhance
Jun 10 2015 21:48
fascinating
Marius Wachtler
@undingen
Jun 10 2015 21:52
building babel is currently extremely slow ~15min (I think your incremental traceback change should help) so maybe add benchmarks for other projects first...
and concerning the the git submodules: I tried to not use them for the tests in order to not depend on even more modules. But now with the benchmark stuff it may make sense to put them into submodules...
Maybe even fork them and apply patches if needed?
Marius Wachtler
@undingen
Jun 10 2015 21:58
On the other side I would prefer if it would stay as is because changing the tests doesn't sound like fun.