Message272324
| Author |
trex58 |
| Recipients |
trex58 |
| Date |
2016年08月10日.09:51:36 |
| SpamBayes Score |
-1.0 |
| Marked as misclassified |
Yes |
| Message-id |
<1470822697.33.0.602349991034.issue27725@psf.upfronthosting.co.za> |
| In-reply-to |
| Content |
I'm porting Python 2.7.* on AIX.
I am now using a version 13.1.3.2 of XLC.
I was previously using version 12.1.0.14 .
It appears that this new compiler shows a potential issue in Python v2 code. This issue seems to appear when -O2 is used.
I was porting Python 2.7.11 with -O2 instead of -O0 when I got it.
The issue appears when running tests involving power() with Decimals where the x_sub() routine is used.
The following Python code shows the issue:
from decimal import *
c = Context(7, ROUND_UP)
d = c.power(Decimal(0.7), Decimal(3.4))
print d
Good result is: 0.2973948 .
The bug returns: 2.440099
However, I have about 22 errors when running:
./python Lib/test/regrtest.py -v test_decimal
It is random in 64bit and quite constant in 32bit.
The issue deals with using x->ob-size.
There is a macro:
Include/object.h:#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
The issue appears in last lines of Objects/longobject.c:x_sub() routine, when changing the sign: z->ob_size = -(z->ob_size);
I have looked at version 2.7.12 and 2.7.10 of Python: they contain the same code as in 2.7.11.
And ->ob_size is used about 45 times, mainly in Objects/longobject.c. However, Py_SIZE(...) is used ten times more (475).
- Looking at version 3.5.1 of Python, I see that ->ob_size is now used only once, in: Objects/object.c .
And Py_SIZE(...) is now used 616 times.
And I also see that the Python 2.7.11-12 x_sub() code:
if (sign < 0)
z->ob_size = -(z->ob_size);
return long_normalize(z);
has been replaced in Python 3.5.1 by:
if (sign < 0) {
_PyLong_Negate(&z);
if (z == NULL)
return NULL;
}
return long_normalize(z);
/* If a freshly-allocated int is already shared, it must
be a small integer, so negating it must go to PyLong_FromLong */
Py_LOCAL_INLINE(void)
_PyLong_Negate(PyLongObject **x_p)
{
PyLongObject *x;
x = (PyLongObject *)*x_p;
if (Py_REFCNT(x) == 1) {
Py_SIZE(x) = -Py_SIZE(x);
return;
}
*x_p = (PyLongObject *)PyLong_FromLong(-MEDIUM_VALUE(x));
Py_DECREF(x);
}
So, it looks to me that Python v2 version should do the same that Python v3 has done: replace x->ob-size by Py_SIZE(x) everywhere, and improve the code of x_sub() by using some _PyLong_Negate() routine or macro. |
|
History
|
|---|
| Date |
User |
Action |
Args |
| 2016年08月10日 09:51:37 | trex58 | set | recipients:
+ trex58 |
| 2016年08月10日 09:51:37 | trex58 | set | messageid: <1470822697.33.0.602349991034.issue27725@psf.upfronthosting.co.za> |
| 2016年08月10日 09:51:37 | trex58 | link | issue27725 messages |
| 2016年08月10日 09:51:36 | trex58 | create |
|