mirror of https://github.com/python/cpython
GH-101291: Refactor the `PyLongObject` struct into object header and PyLongValue struct. (GH-101292)
This commit is contained in:
parent
f5a3d91b6c
commit
c1b1f51cd1
|
@ -79,9 +79,14 @@ typedef long stwodigits; /* signed variant of twodigits */
|
||||||
aware that ints abuse ob_size's sign bit.
|
aware that ints abuse ob_size's sign bit.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct _longobject {
|
typedef struct _PyLongValue {
|
||||||
PyObject_VAR_HEAD
|
Py_ssize_t ob_size; /* Number of items in variable part */
|
||||||
digit ob_digit[1];
|
digit ob_digit[1];
|
||||||
|
} _PyLongValue;
|
||||||
|
|
||||||
|
struct _longobject {
|
||||||
|
PyObject_HEAD
|
||||||
|
_PyLongValue long_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
PyAPI_FUNC(PyLongObject *) _PyLong_New(Py_ssize_t);
|
PyAPI_FUNC(PyLongObject *) _PyLong_New(Py_ssize_t);
|
||||||
|
|
|
@ -149,9 +149,11 @@ extern "C" {
|
||||||
|
|
||||||
#define _PyLong_DIGIT_INIT(val) \
|
#define _PyLong_DIGIT_INIT(val) \
|
||||||
{ \
|
{ \
|
||||||
_PyVarObject_IMMORTAL_INIT(&PyLong_Type, \
|
.ob_base = _PyObject_IMMORTAL_INIT(&PyLong_Type), \
|
||||||
((val) == 0 ? 0 : ((val) > 0 ? 1 : -1))), \
|
.long_value = { \
|
||||||
.ob_digit = { ((val) >= 0 ? (val) : -(val)) }, \
|
((val) == 0 ? 0 : ((val) > 0 ? 1 : -1)), \
|
||||||
|
{ ((val) >= 0 ? (val) : -(val)) }, \
|
||||||
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _PyBytes_SIMPLE_INIT(CH, LEN) \
|
#define _PyBytes_SIMPLE_INIT(CH, LEN) \
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Refactor the ``PyLongObject`` struct into a normal Python object header and
|
||||||
|
a ``PyLongValue`` struct.
|
|
@ -2171,16 +2171,16 @@ dec_from_long(PyTypeObject *type, PyObject *v,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len == 1) {
|
if (len == 1) {
|
||||||
_dec_settriple(dec, sign, *l->ob_digit, 0);
|
_dec_settriple(dec, sign, *l->long_value.ob_digit, 0);
|
||||||
mpd_qfinalize(MPD(dec), ctx, status);
|
mpd_qfinalize(MPD(dec), ctx, status);
|
||||||
return dec;
|
return dec;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PYLONG_BITS_IN_DIGIT == 30
|
#if PYLONG_BITS_IN_DIGIT == 30
|
||||||
mpd_qimport_u32(MPD(dec), l->ob_digit, len, sign, PyLong_BASE,
|
mpd_qimport_u32(MPD(dec), l->long_value.ob_digit, len, sign, PyLong_BASE,
|
||||||
ctx, status);
|
ctx, status);
|
||||||
#elif PYLONG_BITS_IN_DIGIT == 15
|
#elif PYLONG_BITS_IN_DIGIT == 15
|
||||||
mpd_qimport_u16(MPD(dec), l->ob_digit, len, sign, PyLong_BASE,
|
mpd_qimport_u16(MPD(dec), l->long_value.ob_digit, len, sign, PyLong_BASE,
|
||||||
ctx, status);
|
ctx, status);
|
||||||
#else
|
#else
|
||||||
#error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
|
#error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
|
||||||
|
@ -3543,11 +3543,11 @@ dec_as_long(PyObject *dec, PyObject *context, int round)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(pylong->ob_digit, ob_digit, n * sizeof(digit));
|
memcpy(pylong->long_value.ob_digit, ob_digit, n * sizeof(digit));
|
||||||
mpd_free(ob_digit);
|
mpd_free(ob_digit);
|
||||||
|
|
||||||
i = n;
|
i = n;
|
||||||
while ((i > 0) && (pylong->ob_digit[i-1] == 0)) {
|
while ((i > 0) && (pylong->long_value.ob_digit[i-1] == 0)) {
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -195,11 +195,11 @@ PyTypeObject PyBool_Type = {
|
||||||
/* The objects representing bool values False and True */
|
/* The objects representing bool values False and True */
|
||||||
|
|
||||||
struct _longobject _Py_FalseStruct = {
|
struct _longobject _Py_FalseStruct = {
|
||||||
PyVarObject_HEAD_INIT(&PyBool_Type, 0)
|
PyObject_HEAD_INIT(&PyBool_Type)
|
||||||
{ 0 }
|
{ 0, { 0 } }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _longobject _Py_TrueStruct = {
|
struct _longobject _Py_TrueStruct = {
|
||||||
PyVarObject_HEAD_INIT(&PyBool_Type, 1)
|
PyObject_HEAD_INIT(&PyBool_Type)
|
||||||
{ 1 }
|
{ 1, { 1 } }
|
||||||
};
|
};
|
||||||
|
|
|
@ -2155,8 +2155,8 @@ unsafe_long_compare(PyObject *v, PyObject *w, MergeState *ms)
|
||||||
vl = (PyLongObject*)v;
|
vl = (PyLongObject*)v;
|
||||||
wl = (PyLongObject*)w;
|
wl = (PyLongObject*)w;
|
||||||
|
|
||||||
v0 = Py_SIZE(vl) == 0 ? 0 : (sdigit)vl->ob_digit[0];
|
v0 = Py_SIZE(vl) == 0 ? 0 : (sdigit)vl->long_value.ob_digit[0];
|
||||||
w0 = Py_SIZE(wl) == 0 ? 0 : (sdigit)wl->ob_digit[0];
|
w0 = Py_SIZE(wl) == 0 ? 0 : (sdigit)wl->long_value.ob_digit[0];
|
||||||
|
|
||||||
if (Py_SIZE(vl) < 0)
|
if (Py_SIZE(vl) < 0)
|
||||||
v0 = -v0;
|
v0 = -v0;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2507,10 +2507,10 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
|
||||||
overflow = 0;
|
overflow = 0;
|
||||||
/* Single digits are common, fast, and cannot overflow on unpacking. */
|
/* Single digits are common, fast, and cannot overflow on unpacking. */
|
||||||
switch (Py_SIZE(item)) {
|
switch (Py_SIZE(item)) {
|
||||||
case -1: b = -(sdigit) ((PyLongObject*)item)->ob_digit[0]; break;
|
case -1: b = -(sdigit) ((PyLongObject*)item)->long_value.ob_digit[0]; break;
|
||||||
// Note: the continue goes to the top of the "while" loop that iterates over the elements
|
// Note: the continue goes to the top of the "while" loop that iterates over the elements
|
||||||
case 0: Py_DECREF(item); continue;
|
case 0: Py_DECREF(item); continue;
|
||||||
case 1: b = ((PyLongObject*)item)->ob_digit[0]; break;
|
case 1: b = ((PyLongObject*)item)->long_value.ob_digit[0]; break;
|
||||||
default: b = PyLong_AsLongAndOverflow(item, &overflow); break;
|
default: b = PyLong_AsLongAndOverflow(item, &overflow); break;
|
||||||
}
|
}
|
||||||
if (overflow == 0 &&
|
if (overflow == 0 &&
|
||||||
|
|
|
@ -357,8 +357,8 @@ dummy_func(
|
||||||
|
|
||||||
// Deopt unless 0 <= sub < PyList_Size(list)
|
// Deopt unless 0 <= sub < PyList_Size(list)
|
||||||
DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), BINARY_SUBSCR);
|
DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), BINARY_SUBSCR);
|
||||||
assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0);
|
assert(((PyLongObject *)_PyLong_GetZero())->long_value.ob_digit[0] == 0);
|
||||||
Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0];
|
Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0];
|
||||||
DEOPT_IF(index >= PyList_GET_SIZE(list), BINARY_SUBSCR);
|
DEOPT_IF(index >= PyList_GET_SIZE(list), BINARY_SUBSCR);
|
||||||
STAT_INC(BINARY_SUBSCR, hit);
|
STAT_INC(BINARY_SUBSCR, hit);
|
||||||
res = PyList_GET_ITEM(list, index);
|
res = PyList_GET_ITEM(list, index);
|
||||||
|
@ -375,8 +375,8 @@ dummy_func(
|
||||||
|
|
||||||
// Deopt unless 0 <= sub < PyTuple_Size(list)
|
// Deopt unless 0 <= sub < PyTuple_Size(list)
|
||||||
DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), BINARY_SUBSCR);
|
DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), BINARY_SUBSCR);
|
||||||
assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0);
|
assert(((PyLongObject *)_PyLong_GetZero())->long_value.ob_digit[0] == 0);
|
||||||
Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0];
|
Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0];
|
||||||
DEOPT_IF(index >= PyTuple_GET_SIZE(tuple), BINARY_SUBSCR);
|
DEOPT_IF(index >= PyTuple_GET_SIZE(tuple), BINARY_SUBSCR);
|
||||||
STAT_INC(BINARY_SUBSCR, hit);
|
STAT_INC(BINARY_SUBSCR, hit);
|
||||||
res = PyTuple_GET_ITEM(tuple, index);
|
res = PyTuple_GET_ITEM(tuple, index);
|
||||||
|
@ -469,7 +469,7 @@ dummy_func(
|
||||||
|
|
||||||
// Ensure nonnegative, zero-or-one-digit ints.
|
// Ensure nonnegative, zero-or-one-digit ints.
|
||||||
DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), STORE_SUBSCR);
|
DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), STORE_SUBSCR);
|
||||||
Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0];
|
Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0];
|
||||||
// Ensure index < len(list)
|
// Ensure index < len(list)
|
||||||
DEOPT_IF(index >= PyList_GET_SIZE(list), STORE_SUBSCR);
|
DEOPT_IF(index >= PyList_GET_SIZE(list), STORE_SUBSCR);
|
||||||
STAT_INC(STORE_SUBSCR, hit);
|
STAT_INC(STORE_SUBSCR, hit);
|
||||||
|
@ -1834,8 +1834,8 @@ dummy_func(
|
||||||
DEOPT_IF((size_t)(Py_SIZE(right) + 1) > 2, COMPARE_AND_BRANCH);
|
DEOPT_IF((size_t)(Py_SIZE(right) + 1) > 2, COMPARE_AND_BRANCH);
|
||||||
STAT_INC(COMPARE_AND_BRANCH, hit);
|
STAT_INC(COMPARE_AND_BRANCH, hit);
|
||||||
assert(Py_ABS(Py_SIZE(left)) <= 1 && Py_ABS(Py_SIZE(right)) <= 1);
|
assert(Py_ABS(Py_SIZE(left)) <= 1 && Py_ABS(Py_SIZE(right)) <= 1);
|
||||||
Py_ssize_t ileft = Py_SIZE(left) * ((PyLongObject *)left)->ob_digit[0];
|
Py_ssize_t ileft = Py_SIZE(left) * ((PyLongObject *)left)->long_value.ob_digit[0];
|
||||||
Py_ssize_t iright = Py_SIZE(right) * ((PyLongObject *)right)->ob_digit[0];
|
Py_ssize_t iright = Py_SIZE(right) * ((PyLongObject *)right)->long_value.ob_digit[0];
|
||||||
// 2 if <, 4 if >, 8 if ==; this matches the low 4 bits of the oparg
|
// 2 if <, 4 if >, 8 if ==; this matches the low 4 bits of the oparg
|
||||||
int sign_ish = COMPARISON_BIT(ileft, iright);
|
int sign_ish = COMPARISON_BIT(ileft, iright);
|
||||||
_Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free);
|
_Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free);
|
||||||
|
|
|
@ -484,8 +484,8 @@
|
||||||
|
|
||||||
// Deopt unless 0 <= sub < PyList_Size(list)
|
// Deopt unless 0 <= sub < PyList_Size(list)
|
||||||
DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), BINARY_SUBSCR);
|
DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), BINARY_SUBSCR);
|
||||||
assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0);
|
assert(((PyLongObject *)_PyLong_GetZero())->long_value.ob_digit[0] == 0);
|
||||||
Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0];
|
Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0];
|
||||||
DEOPT_IF(index >= PyList_GET_SIZE(list), BINARY_SUBSCR);
|
DEOPT_IF(index >= PyList_GET_SIZE(list), BINARY_SUBSCR);
|
||||||
STAT_INC(BINARY_SUBSCR, hit);
|
STAT_INC(BINARY_SUBSCR, hit);
|
||||||
res = PyList_GET_ITEM(list, index);
|
res = PyList_GET_ITEM(list, index);
|
||||||
|
@ -509,8 +509,8 @@
|
||||||
|
|
||||||
// Deopt unless 0 <= sub < PyTuple_Size(list)
|
// Deopt unless 0 <= sub < PyTuple_Size(list)
|
||||||
DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), BINARY_SUBSCR);
|
DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), BINARY_SUBSCR);
|
||||||
assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0);
|
assert(((PyLongObject *)_PyLong_GetZero())->long_value.ob_digit[0] == 0);
|
||||||
Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0];
|
Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0];
|
||||||
DEOPT_IF(index >= PyTuple_GET_SIZE(tuple), BINARY_SUBSCR);
|
DEOPT_IF(index >= PyTuple_GET_SIZE(tuple), BINARY_SUBSCR);
|
||||||
STAT_INC(BINARY_SUBSCR, hit);
|
STAT_INC(BINARY_SUBSCR, hit);
|
||||||
res = PyTuple_GET_ITEM(tuple, index);
|
res = PyTuple_GET_ITEM(tuple, index);
|
||||||
|
@ -634,7 +634,7 @@
|
||||||
|
|
||||||
// Ensure nonnegative, zero-or-one-digit ints.
|
// Ensure nonnegative, zero-or-one-digit ints.
|
||||||
DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), STORE_SUBSCR);
|
DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), STORE_SUBSCR);
|
||||||
Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0];
|
Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0];
|
||||||
// Ensure index < len(list)
|
// Ensure index < len(list)
|
||||||
DEOPT_IF(index >= PyList_GET_SIZE(list), STORE_SUBSCR);
|
DEOPT_IF(index >= PyList_GET_SIZE(list), STORE_SUBSCR);
|
||||||
STAT_INC(STORE_SUBSCR, hit);
|
STAT_INC(STORE_SUBSCR, hit);
|
||||||
|
@ -2179,8 +2179,8 @@
|
||||||
DEOPT_IF((size_t)(Py_SIZE(right) + 1) > 2, COMPARE_AND_BRANCH);
|
DEOPT_IF((size_t)(Py_SIZE(right) + 1) > 2, COMPARE_AND_BRANCH);
|
||||||
STAT_INC(COMPARE_AND_BRANCH, hit);
|
STAT_INC(COMPARE_AND_BRANCH, hit);
|
||||||
assert(Py_ABS(Py_SIZE(left)) <= 1 && Py_ABS(Py_SIZE(right)) <= 1);
|
assert(Py_ABS(Py_SIZE(left)) <= 1 && Py_ABS(Py_SIZE(right)) <= 1);
|
||||||
Py_ssize_t ileft = Py_SIZE(left) * ((PyLongObject *)left)->ob_digit[0];
|
Py_ssize_t ileft = Py_SIZE(left) * ((PyLongObject *)left)->long_value.ob_digit[0];
|
||||||
Py_ssize_t iright = Py_SIZE(right) * ((PyLongObject *)right)->ob_digit[0];
|
Py_ssize_t iright = Py_SIZE(right) * ((PyLongObject *)right)->long_value.ob_digit[0];
|
||||||
// 2 if <, 4 if >, 8 if ==; this matches the low 4 bits of the oparg
|
// 2 if <, 4 if >, 8 if ==; this matches the low 4 bits of the oparg
|
||||||
int sign_ish = COMPARISON_BIT(ileft, iright);
|
int sign_ish = COMPARISON_BIT(ileft, iright);
|
||||||
_Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free);
|
_Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free);
|
||||||
|
|
|
@ -240,7 +240,7 @@ w_PyLong(const PyLongObject *ob, char flag, WFILE *p)
|
||||||
/* set l to number of base PyLong_MARSHAL_BASE digits */
|
/* set l to number of base PyLong_MARSHAL_BASE digits */
|
||||||
n = Py_ABS(Py_SIZE(ob));
|
n = Py_ABS(Py_SIZE(ob));
|
||||||
l = (n-1) * PyLong_MARSHAL_RATIO;
|
l = (n-1) * PyLong_MARSHAL_RATIO;
|
||||||
d = ob->ob_digit[n-1];
|
d = ob->long_value.ob_digit[n-1];
|
||||||
assert(d != 0); /* a PyLong is always normalized */
|
assert(d != 0); /* a PyLong is always normalized */
|
||||||
do {
|
do {
|
||||||
d >>= PyLong_MARSHAL_SHIFT;
|
d >>= PyLong_MARSHAL_SHIFT;
|
||||||
|
@ -254,14 +254,14 @@ w_PyLong(const PyLongObject *ob, char flag, WFILE *p)
|
||||||
w_long((long)(Py_SIZE(ob) > 0 ? l : -l), p);
|
w_long((long)(Py_SIZE(ob) > 0 ? l : -l), p);
|
||||||
|
|
||||||
for (i=0; i < n-1; i++) {
|
for (i=0; i < n-1; i++) {
|
||||||
d = ob->ob_digit[i];
|
d = ob->long_value.ob_digit[i];
|
||||||
for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
|
for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
|
||||||
w_short(d & PyLong_MARSHAL_MASK, p);
|
w_short(d & PyLong_MARSHAL_MASK, p);
|
||||||
d >>= PyLong_MARSHAL_SHIFT;
|
d >>= PyLong_MARSHAL_SHIFT;
|
||||||
}
|
}
|
||||||
assert (d == 0);
|
assert (d == 0);
|
||||||
}
|
}
|
||||||
d = ob->ob_digit[n-1];
|
d = ob->long_value.ob_digit[n-1];
|
||||||
do {
|
do {
|
||||||
w_short(d & PyLong_MARSHAL_MASK, p);
|
w_short(d & PyLong_MARSHAL_MASK, p);
|
||||||
d >>= PyLong_MARSHAL_SHIFT;
|
d >>= PyLong_MARSHAL_SHIFT;
|
||||||
|
@ -853,7 +853,7 @@ r_PyLong(RFILE *p)
|
||||||
goto bad_digit;
|
goto bad_digit;
|
||||||
d += (digit)md << j*PyLong_MARSHAL_SHIFT;
|
d += (digit)md << j*PyLong_MARSHAL_SHIFT;
|
||||||
}
|
}
|
||||||
ob->ob_digit[i] = d;
|
ob->long_value.ob_digit[i] = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
d = 0;
|
d = 0;
|
||||||
|
@ -880,7 +880,7 @@ r_PyLong(RFILE *p)
|
||||||
}
|
}
|
||||||
/* top digit should be nonzero, else the resulting PyLong won't be
|
/* top digit should be nonzero, else the resulting PyLong won't be
|
||||||
normalized */
|
normalized */
|
||||||
ob->ob_digit[size-1] = d;
|
ob->long_value.ob_digit[size-1] = d;
|
||||||
return (PyObject *)ob;
|
return (PyObject *)ob;
|
||||||
bad_digit:
|
bad_digit:
|
||||||
Py_DECREF(ob);
|
Py_DECREF(ob);
|
||||||
|
|
|
@ -1411,7 +1411,7 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins
|
||||||
if (container_type == &PyList_Type) {
|
if (container_type == &PyList_Type) {
|
||||||
if (PyLong_CheckExact(sub)) {
|
if (PyLong_CheckExact(sub)) {
|
||||||
if ((Py_SIZE(sub) == 0 || Py_SIZE(sub) == 1)
|
if ((Py_SIZE(sub) == 0 || Py_SIZE(sub) == 1)
|
||||||
&& ((PyLongObject *)sub)->ob_digit[0] < (size_t)PyList_GET_SIZE(container))
|
&& ((PyLongObject *)sub)->long_value.ob_digit[0] < (size_t)PyList_GET_SIZE(container))
|
||||||
{
|
{
|
||||||
_py_set_opcode(instr, STORE_SUBSCR_LIST_INT);
|
_py_set_opcode(instr, STORE_SUBSCR_LIST_INT);
|
||||||
goto success;
|
goto success;
|
||||||
|
|
|
@ -901,7 +901,7 @@ class PyLongObjectPtr(PyObjectPtr):
|
||||||
if ob_size == 0:
|
if ob_size == 0:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
ob_digit = self.field('ob_digit')
|
ob_digit = self.field('long_value')['ob_digit']
|
||||||
|
|
||||||
if gdb.lookup_type('digit').sizeof == 2:
|
if gdb.lookup_type('digit').sizeof == 2:
|
||||||
SHIFT = 15
|
SHIFT = 15
|
||||||
|
|
Loading…
Reference in New Issue