summaryrefslogtreecommitdiff
path: root/Python/peephole.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2016-04-06 09:50:03 +0300
committerSerhiy Storchaka <storchaka@gmail.com>2016-04-06 09:50:03 +0300
commit6d080f12a4ea2b60d07541af6cc363e491e5aa34 (patch)
treec22a0f8591e4fb5ea4310c33653830a0c84c3a3c /Python/peephole.c
parent58455ad4ed5e6f1eda17ceb0dd7f5612a980e48d (diff)
parent850c5fb7f500033305e142b3c47fd744fc6a62e5 (diff)
downloadcpython-6d080f12a4ea2b60d07541af6cc363e491e5aa34.tar.gz
Issue #22570: Renamed Py_SETREF to Py_XSETREF.
Diffstat (limited to 'Python/peephole.c')
-rw-r--r--Python/peephole.c55
1 files changed, 29 insertions, 26 deletions
diff --git a/Python/peephole.c b/Python/peephole.c
index 59ad3b762f..2b2e4c420a 100644
--- a/Python/peephole.c
+++ b/Python/peephole.c
@@ -118,9 +118,7 @@ tuple_of_constants(unsigned char *codestr, Py_ssize_t n,
/* If it's a BUILD_SET, use the PyTuple we just built to create a
PyFrozenSet, and use that as the constant instead: */
if (codestr[0] == BUILD_SET) {
- PyObject *tuple = newconst;
- newconst = PyFrozenSet_New(tuple);
- Py_DECREF(tuple);
+ Py_XSETREF(newconst, PyFrozenSet_New(newconst));
if (newconst == NULL)
return 0;
}
@@ -348,19 +346,19 @@ markblocks(unsigned char *code, Py_ssize_t len)
single basic block. All transformations keep the code size the same or
smaller. For those that reduce size, the gaps are initially filled with
NOPs. Later those NOPs are removed and the jump addresses retargeted in
- a single pass. Line numbering is adjusted accordingly. */
+ a single pass. Code offset is adjusted accordingly. */
PyObject *
PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
- PyObject *lineno_obj)
+ PyObject *lnotab_obj)
{
Py_ssize_t i, j, codelen;
int nops, h, adj;
int tgt, tgttgt, opcode;
unsigned char *codestr = NULL;
- unsigned char *lineno;
+ unsigned char *lnotab;
int *addrmap = NULL;
- int new_line, cum_orig_line, last_line;
+ int cum_orig_offset, last_offset;
Py_ssize_t tabsiz;
PyObject **const_stack = NULL;
Py_ssize_t *load_const_stack = NULL;
@@ -373,12 +371,17 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
if (PyErr_Occurred())
goto exitError;
- /* Bypass optimization when the lineno table is too complex */
- assert(PyBytes_Check(lineno_obj));
- lineno = (unsigned char*)PyBytes_AS_STRING(lineno_obj);
- tabsiz = PyBytes_GET_SIZE(lineno_obj);
- if (memchr(lineno, 255, tabsiz) != NULL)
+ /* Bypass optimization when the lnotab table is too complex */
+ assert(PyBytes_Check(lnotab_obj));
+ lnotab = (unsigned char*)PyBytes_AS_STRING(lnotab_obj);
+ tabsiz = PyBytes_GET_SIZE(lnotab_obj);
+ assert(tabsiz == 0 || Py_REFCNT(lnotab_obj) == 1);
+ if (memchr(lnotab, 255, tabsiz) != NULL) {
+ /* 255 value are used for multibyte bytecode instructions */
goto exitUnchanged;
+ }
+ /* Note: -128 and 127 special values for line number delta are ok,
+ the peephole optimizer doesn't modify line numbers. */
/* Avoid situations where jump retargeting could overflow */
assert(PyBytes_Check(code));
@@ -665,21 +668,24 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
}
}
- /* Fixup linenotab */
+ /* Fixup lnotab */
for (i=0, nops=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
assert(i - nops <= INT_MAX);
+ /* original code offset => new code offset */
addrmap[i] = (int)(i - nops);
if (codestr[i] == NOP)
nops++;
}
- cum_orig_line = 0;
- last_line = 0;
+ cum_orig_offset = 0;
+ last_offset = 0;
for (i=0 ; i < tabsiz ; i+=2) {
- cum_orig_line += lineno[i];
- new_line = addrmap[cum_orig_line];
- assert (new_line - last_line < 255);
- lineno[i] =((unsigned char)(new_line - last_line));
- last_line = new_line;
+ int offset_delta, new_offset;
+ cum_orig_offset += lnotab[i];
+ new_offset = addrmap[cum_orig_offset];
+ offset_delta = new_offset - last_offset;
+ assert(0 <= offset_delta && offset_delta <= 255);
+ lnotab[i] = (unsigned char)offset_delta;
+ last_offset = new_offset;
}
/* Remove NOPs and fixup jump targets */
@@ -729,12 +735,9 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
exitUnchanged:
CONST_STACK_DELETE();
- if (blocks != NULL)
- PyMem_Free(blocks);
- if (addrmap != NULL)
- PyMem_Free(addrmap);
- if (codestr != NULL)
- PyMem_Free(codestr);
+ PyMem_Free(blocks);
+ PyMem_Free(addrmap);
+ PyMem_Free(codestr);
Py_XINCREF(code);
return code;
}