Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(144)

Unified Diff: Python/ceval.c

Issue 20103: http://bugs.python.org/issue2459 -- speed up loops SVN Base: http://svn.python.org/view/*checkout*/python/trunk/
Patch Set: Created 9 months, 1 week ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side by-side-diff with in-line comments
Download patch
Index: Python/ceval.c
===================================================================
--- Python/ceval.c (revision 70087)
+++ Python/ceval.c (working copy)
@@ -111,7 +111,7 @@
PyFrameObject *, int, PyObject *);
static void call_exc_trace(Py_tracefunc, PyObject *, PyFrameObject *);
static int maybe_call_line_trace(Py_tracefunc, PyObject *,
- PyFrameObject *, int *, int *, int *);
+ PyFrameObject *, int *, int *, int *, int *);
static PyObject * apply_slice(PyObject *, PyObject *, PyObject *);
static int assign_slice(PyObject *, PyObject *,
@@ -688,12 +688,15 @@
/* when tracing we set things up so that
- not (instr_lb <= current_bytecode_offset < instr_ub)
+ instr_lb <= current_bytecode_offset < instr_ub
- is true when the line being executed has changed. The
- initial values are such as to make this false the first
- time it is tested. */
+ is false when the line being executed may have changed.
+ The initial values are such as to make this false the first
+ time it is tested. Then maybe_call_line_trace calls
+ PyCode_CheckLineNumber() to check if the line has actually
+ changed. */
int instr_ub = -1, instr_lb = 0, instr_prev = -1;
+ int cur_line = 0;
unsigned char *first_instr;
PyObject *names;
@@ -785,8 +788,11 @@
#ifdef DYNAMIC_EXECUTION_PROFILE
#define PREDICT(op) if (0) goto PRED_##op
+#define PREDICT_WITH_SIGNALS(op) if (0) goto PRED_##op
#else
#define PREDICT(op) if (*next_instr == op) goto PRED_##op
+#define PREDICT_WITH_SIGNALS(op) \
+ if (*next_instr == op && --_Py_Ticker > 0) goto PRED_##op
#endif
#define PREDICTED(op) PRED_##op: next_instr++
@@ -908,8 +914,8 @@
prediction effectively links the two codes together as if they
were a single new opcode; accordingly,f->f_lasti will point to
the first code in the pair (for instance, GET_ITER followed by
- FOR_ITER is effectively a single opcode and f->f_lasti will point
- at to the beginning of the combined pair.)
+ JUMP_FORWARD is effectively a single opcode and f->f_lasti will
+ point at to the beginning of the combined pair.)
*/
next_instr = first_instr + f->f_lasti + 1;
stack_pointer = f->f_stacktop;
@@ -1027,7 +1033,7 @@
err = maybe_call_line_trace(tstate->c_tracefunc,
tstate->c_traceobj,
f, &instr_lb, &instr_ub,
- &instr_prev);
+ &instr_prev, &cur_line);
/* Reload possibly changed frame fields */
JUMPTO(f->f_lasti);
if (f->f_stacktop != NULL) {
@@ -1425,7 +1431,7 @@
err = PyList_Append(v, w);
Py_DECREF(w);
if (err == 0) {
- PREDICT(JUMP_ABSOLUTE);
+ PREDICT(FOR_ITER);
continue;
}
break;
@@ -2293,6 +2299,7 @@
if (x != NULL) continue;
break;
+ PREDICTED_WITH_ARG(JUMP_FORWARD);
case JUMP_FORWARD:
JUMPBY(oparg);
goto fast_next_opcode;
@@ -2307,14 +2314,22 @@
if (w == Py_False) {
Py_DECREF(w);
JUMPTO(oparg);
+#if FAST_LOOPS /* See JUMP_ABSOLUTE for a description of this define */
goto fast_next_opcode;
+#else
+ continue;
+#endif
}
err = PyObject_IsTrue(w);
Py_DECREF(w);
if (err > 0)
err = 0;
- else if (err == 0)
+ else if (err == 0) {
JUMPTO(oparg);
+#if FAST_LOOPS /* See JUMP_ABSOLUTE for a description of this define */
+ goto fast_next_opcode;
+#endif
+ }
else
break;
continue;
@@ -2329,13 +2344,20 @@
if (w == Py_True) {
Py_DECREF(w);
JUMPTO(oparg);
+#if FAST_LOOPS /* See JUMP_ABSOLUTE for a description of this define */
goto fast_next_opcode;
+#else
+ continue;
+#endif
}
err = PyObject_IsTrue(w);
Py_DECREF(w);
if (err > 0) {
err = 0;
JUMPTO(oparg);
+#if FAST_LOOPS /* See JUMP_ABSOLUTE for a description of this define */
+ goto fast_next_opcode;
+#endif
}
else if (err == 0)
;
@@ -2390,7 +2412,6 @@
break;
continue;
- PREDICTED_WITH_ARG(JUMP_ABSOLUTE);
case JUMP_ABSOLUTE:
JUMPTO(oparg);
#if FAST_LOOPS
@@ -2413,7 +2434,7 @@
Py_DECREF(v);
if (x != NULL) {
SET_TOP(x);
- PREDICT(FOR_ITER);
+ PREDICT(JUMP_FORWARD);
continue;
}
STACKADJ(-1);
@@ -2426,7 +2447,10 @@
x = (*v->ob_type->tp_iternext)(v);
if (x != NULL) {
PUSH(x);
- PREDICT(STORE_FAST);
+ JUMPTO(oparg);
+ /* STORE_FAST is a fast_next_opcode so we must be careful
+ about not blocking signals in an empty loop. */
+ PREDICT_WITH_SIGNALS(STORE_FAST);
PREDICT(UNPACK_SEQUENCE);
continue;
}
@@ -2437,9 +2461,8 @@
PyErr_Clear();
}
/* iterator ended normally */
- x = v = POP();
+ x = v = POP();
Py_DECREF(v);
- JUMPBY(oparg);
continue;
case BREAK_LOOP:
@@ -3594,7 +3617,7 @@
static int
maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
PyFrameObject *frame, int *instr_lb, int *instr_ub,
- int *instr_prev)
+ int *instr_prev, int *cur_line)
{
int result = 0;
@@ -3609,13 +3632,14 @@
line = PyCode_CheckLineNumber(frame->f_code, frame->f_lasti,
&bounds);
- if (line >= 0) {
+ if (line >= 0 && line != *cur_line) {
frame->f_lineno = line;
result = call_trace(func, obj, frame,
PyTrace_LINE, Py_None);
}
*instr_lb = bounds.ap_lower;
*instr_ub = bounds.ap_upper;
+ *cur_line = line;
}
else if (frame->f_lasti <= *instr_prev) {
result = call_trace(func, obj, frame, PyTrace_LINE, Py_None);

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld r497