# HG changeset patch # User Adrian Wielgosik # Date 1480251985 -3600 # Sun Nov 27 14:06:25 2016 +0100 # Node ID 524b21435023bf1b98699847408c3c528beb16a5 # Parent 876bee0bd0ba55d64687e233021425f85fb57e05 const removal diff -r 876bee0bd0ba -r 524b21435023 Lib/test/test_dis.py --- a/Lib/test/test_dis.py Sat Nov 26 14:04:40 2016 -0800 +++ b/Lib/test/test_dis.py Sun Nov 27 14:06:25 2016 +0100 @@ -679,9 +679,9 @@ # End fodder for opinfo generation tests expected_outer_line = 1 _line_offset = outer.__code__.co_firstlineno - 1 -code_object_f = outer.__code__.co_consts[3] +code_object_f = outer.__code__.co_consts[1] expected_f_line = code_object_f.co_firstlineno - _line_offset -code_object_inner = code_object_f.co_consts[3] +code_object_inner = code_object_f.co_consts[1] expected_inner_line = code_object_inner.co_firstlineno - _line_offset expected_jumpy_line = 1 @@ -706,22 +706,22 @@ Instruction = dis.Instruction expected_opinfo_outer = [ - Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval=(3, 4), argrepr='(3, 4)', offset=0, starts_line=2, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval=(3, 4), argrepr='(3, 4)', offset=0, starts_line=2, is_jump_target=False), Instruction(opname='LOAD_CLOSURE', opcode=135, arg=0, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CLOSURE', opcode=135, arg=1, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False), Instruction(opname='BUILD_TUPLE', opcode=102, arg=2, argval=2, argrepr='', offset=6, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_f, argrepr=repr(code_object_f), offset=8, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='outer..f', argrepr="'outer..f'", offset=10, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=code_object_f, argrepr=repr(code_object_f), offset=8, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval='outer..f', argrepr="'outer..f'", offset=10, starts_line=None, is_jump_target=False), Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='', offset=12, starts_line=None, is_jump_target=False), Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='f', argrepr='f', offset=14, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=16, starts_line=7, is_jump_target=False), Instruction(opname='LOAD_DEREF', opcode=136, arg=0, argval='a', argrepr='a', offset=18, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_DEREF', opcode=136, arg=1, argval='b', argrepr='b', offset=20, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval='', argrepr="''", offset=22, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval=1, argrepr='1', offset=24, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval='', argrepr="''", offset=22, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval=1, argrepr='1', offset=24, starts_line=None, is_jump_target=False), Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=26, starts_line=None, is_jump_target=False), Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=28, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval='Hello world!', argrepr="'Hello world!'", offset=30, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval='Hello world!', argrepr="'Hello world!'", offset=30, starts_line=None, is_jump_target=False), Instruction(opname='CALL_FUNCTION', opcode=131, arg=7, argval=7, argrepr='', offset=32, starts_line=None, is_jump_target=False), Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=34, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=36, starts_line=8, is_jump_target=False), @@ -729,14 +729,14 @@ ] expected_opinfo_f = [ - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=(5, 6), argrepr='(5, 6)', offset=0, starts_line=3, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=(5, 6), argrepr='(5, 6)', offset=0, starts_line=3, is_jump_target=False), Instruction(opname='LOAD_CLOSURE', opcode=135, arg=2, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CLOSURE', opcode=135, arg=3, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CLOSURE', opcode=135, arg=0, argval='c', argrepr='c', offset=6, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CLOSURE', opcode=135, arg=1, argval='d', argrepr='d', offset=8, starts_line=None, is_jump_target=False), Instruction(opname='BUILD_TUPLE', opcode=102, arg=4, argval=4, argrepr='', offset=10, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_inner, argrepr=repr(code_object_inner), offset=12, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='outer..f..inner', argrepr="'outer..f..inner'", offset=14, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=code_object_inner, argrepr=repr(code_object_inner), offset=12, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval='outer..f..inner', argrepr="'outer..f..inner'", offset=14, starts_line=None, is_jump_target=False), Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='', offset=16, starts_line=None, is_jump_target=False), Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='inner', argrepr='inner', offset=18, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=20, starts_line=5, is_jump_target=False), diff -r 876bee0bd0ba -r 524b21435023 Python/peephole.c --- a/Python/peephole.c Sat Nov 26 14:04:40 2016 -0800 +++ b/Python/peephole.c Sun Nov 27 14:06:25 2016 +0100 @@ -22,37 +22,61 @@ #define ISBASICBLOCK(blocks, start, end) \ (blocks[start]==blocks[end]) +struct const_uses_entry { + unsigned int uses; + unsigned int relocation; +}; #define CONST_STACK_CREATE() { \ const_stack_size = 256; \ - const_stack = PyMem_New(PyObject *, const_stack_size); \ + const_stack = PyMem_New(unsigned int, const_stack_size); \ if (!const_stack) { \ PyErr_NoMemory(); \ goto exitError; \ } \ + const_uses_curr_size = const_uses_size = PyList_GET_SIZE(consts); \ + const_uses = PyMem_New(struct const_uses_entry, const_uses_size); \ + if (!const_uses) { \ + PyErr_NoMemory(); \ + goto exitError; \ + } \ + memset(const_uses, 0, const_uses_size * sizeof(struct const_uses_entry)); \ } #define CONST_STACK_DELETE() do { \ if (const_stack) \ PyMem_Free(const_stack); \ + PyMem_Free(const_uses); \ } while(0) #define CONST_STACK_LEN() ((unsigned)(const_stack_top + 1)) #define CONST_STACK_PUSH_OP(i) do { \ - PyObject *_x; \ assert(_Py_OPCODE(codestr[i]) == LOAD_CONST); \ assert(PyList_GET_SIZE(consts) > (Py_ssize_t)get_arg(codestr, i)); \ - _x = PyList_GET_ITEM(consts, get_arg(codestr, i)); \ if (++const_stack_top >= const_stack_size) { \ const_stack_size *= 2; \ - PyMem_Resize(const_stack, PyObject *, const_stack_size); \ + PyMem_Resize(const_stack, unsigned int, const_stack_size); \ if (!const_stack) { \ PyErr_NoMemory(); \ goto exitError; \ } \ } \ - const_stack[const_stack_top] = _x; \ + int arg = get_arg(codestr, i); \ + const_stack[const_stack_top] = arg; \ + if (arg >= const_uses_curr_size) {\ + const_uses_curr_size = arg + 1; \ + if (const_uses_curr_size > const_uses_size) {\ + const_uses_size *= 2; \ + PyMem_Resize(const_uses, struct const_uses_entry, const_uses_size); \ + if (!const_uses) { \ + PyErr_NoMemory(); \ + goto exitError; \ + } \ + for (int z = arg; z < const_uses_size; ++z) const_uses[z].uses = 0; \ + } \ + }\ + const_uses[arg].uses += 1; \ in_consts = 1; \ } while(0) @@ -66,8 +90,12 @@ #define CONST_STACK_POP(i) do { \ assert(CONST_STACK_LEN() >= i); \ const_stack_top -= i; \ + for (unsigned int z = 0; z < i; ++z) \ + const_uses[const_stack[const_stack_top+z+1]].uses -= 1; \ } while(0) +#define CONST_GET(i) (PyList_GET_ITEM((consts), (i))) + /* Scans back N consecutive LOAD_CONST instructions, skipping NOPs, returns index of the Nth last's LOAD_CONST's EXTENDED_ARG prefix. Callers are responsible to check CONST_STACK_LEN beforehand. @@ -179,7 +207,7 @@ static Py_ssize_t fold_tuple_on_constants(_Py_CODEUNIT *codestr, Py_ssize_t c_start, Py_ssize_t opcode_end, unsigned char opcode, - PyObject *consts, PyObject **objs, int n) + PyObject *consts, unsigned int *const_ids, int n) { PyObject *newconst, *constant; Py_ssize_t i, len_consts; @@ -193,7 +221,7 @@ return -1; } for (i=0 ; i