<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Sat, 3 Sep 2016 at 16:43 Yury Selivanov <<a href="mailto:yselivanov.ml@gmail.com">yselivanov.ml@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
<br>
On 2016-09-03 4:15 PM, Christian Heimes wrote:<br>
> On 2016-09-04 00:03, Yury Selivanov wrote:<br>
>><br>
>> On 2016-09-03 12:27 PM, Brett Cannon wrote:<br>
>>> Below is the `co_extra` section of PEP 523 with the update saying that<br>
>>> users are expected to put a tuple in the field for easier simultaneous<br>
>>> use of the field.<br>
>>><br>
>>> Since the `co_extra` discussions do not affect CPython itself I'm<br>
>>> planning on landing the changes stemming from the PEP probably on Monday.<br>
>> Tuples are immutable. If you have multiple co_extra users then they<br>
>> will have to either mutate tuple (which isn't always possible, for<br>
>> instance, you can't increase size), or to replace it with another tuple.<br>
>><br>
>> Creating lists is a bit more expensive, but item access speed should be<br>
>> in the same ballpark.<br>
>><br>
>> Another question -- sorry if this was discussed before -- why do we want<br>
>> a PyObject* there at all? I.e. why don't we create a dedicated struct<br>
>> CoExtraContainer to manage the stuff in co_extra? My understanding is<br>
>> that the users of co_extra are C-level python optimizers and profilers,<br>
>> which don't need the overhead of CPython API.<br></blockquote><div><br></div><div>As Chris pointed out in another email, the overhead is only in the allocation, not the iteration/access if you use the PyTuple macros to get the size and index into the tuple the overhead is negligible.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
>><br>
>> This way my work to add an extra caching layer (which I'm very much<br>
>> willing to continue to work on) wouldn't require another set of extra<br>
>> fields for code objects.<br>
> Quick idea before I go to bed:<br>
><br>
> You could adopt a similar API to OpenSSL's CRYPTO_get_ex_new_index()<br>
> API,<br>
> <a href="https://www.openssl.org/docs/manmaster/crypto/CRYPTO_get_ex_new_index.html" rel="noreferrer" target="_blank">https://www.openssl.org/docs/manmaster/crypto/CRYPTO_get_ex_new_index.html</a><br>
><br>
><br>
> static int code_index = 0;<br>
><br>
> int PyCodeObject_NewIndex() {<br>
> return code_index++;<br>
> }<br>
><br>
> A library like Pyjion has to acquire an index first. In further calls it<br>
> uses the index as offset into the new co_extra field. Libraries don't<br>
> have to hard-code their offset and two libraries will never conflict.<br>
> PyCode_New() can pre-populate co_extra with a PyTuple of size<br>
> code_index. This avoids most resizes if you load Pyjion early. For<br>
> code_index == 0 leaf the field NULL.<br>
<br>
Sounds like a very good idea!<br></blockquote><div><br></div><div>The problem with this is the pre-population. If you don't get your index assigned before the very first code object is allocated then you still have to manage the size of the tuple in co_extra. So what this would do is avoid the iteration but not the allocation overhead.</div><div><br></div><div>If we open up the can of worms in terms of custom functions for this (which I was trying to avoid), then you end up with <span style="line-height:1.5">Py_ssize_t </span><span style="line-height:1.5">_PyCode_ExtraIndex(), </span><span style="line-height:1.5">PyObject *</span></div><div> _PyCode_GetExtra(PyCodeObject *code, Py_ssize_t index), and int _PyCode_SetExtra(PyCodeObject *code, Py_ssize_t index, PyObject *data) which does all the right things for creating or resizing the tuple as necessary and which I think matches mostly what Nick had proposed earlier. But the pseudo-code for _PyCode_GetExtra() would be::</div><div><br></div><div> if co_extra is None:</div><div> co_extra = (None,) * _next_extra_index;</div><div> return None</div><div> elif len(co_extra) < index - 1:</div><div> ... pad out tuple</div><div> return None</div><div> else:</div><div> return co_extra[index]</div><div><br></div><div>Is that going to save us enough to want to have a custom API for this?</div><div><br></div><div>-Brett</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Yury<br>
</blockquote></div></div>