Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add cpython patches

  • Loading branch information...
commit 4f5a9be3ae7dcda6b9e3a1709aead398dd628e16 1 parent b84c20f
Victor Stinner authored
Showing with 452 additions and 0 deletions.
  1. +173 −0 cpython2_ceval.patch
  2. +279 −0 cpython3_ceval.patch
View
173 cpython2_ceval.patch
@@ -0,0 +1,173 @@
+Index: Python/ceval.c
+===================================================================
+--- Python/ceval.c (révision 84785)
++++ Python/ceval.c (copie de travail)
+@@ -119,6 +119,7 @@
+ #define CALL_FLAG_VAR 1
+ #define CALL_FLAG_KW 2
+
++static PyObject *import_str = NULL;
+ #ifdef LLTRACE
+ static int lltrace;
+ static int prtrace(PyObject *, char *);
+@@ -2054,7 +2055,10 @@
+ if (x == NULL) {
+ x = PyDict_GetItem(f->f_globals, w);
+ if (x == NULL) {
+- x = PyDict_GetItem(f->f_builtins, w);
++ if (PyDict_CheckExact(f->f_builtins))
++ x = PyDict_GetItem(f->f_builtins, w);
++ else
++ x = PyObject_GetItem(f->f_builtins, w);
+ if (x == NULL) {
+ format_exc_check_arg(
+ PyExc_NameError,
+@@ -2069,57 +2073,67 @@
+
+ case LOAD_GLOBAL:
+ w = GETITEM(names, oparg);
+- if (PyString_CheckExact(w)) {
+- /* Inline the PyDict_GetItem() calls.
+- WARNING: this is an extreme speed hack.
+- Do not try this at home. */
+- long hash = ((PyStringObject *)w)->ob_shash;
+- if (hash != -1) {
+- PyDictObject *d;
+- PyDictEntry *e;
+- d = (PyDictObject *)(f->f_globals);
+- e = d->ma_lookup(d, w, hash);
+- if (e == NULL) {
+- x = NULL;
+- break;
++ if (PyDict_CheckExact(f->f_builtins)) {
++ if (PyString_CheckExact(w)) {
++ /* Inline the PyDict_GetItem() calls.
++ WARNING: this is an extreme speed hack.
++ Do not try this at home. */
++ long hash = ((PyStringObject *)w)->ob_shash;
++ if (hash != -1) {
++ PyDictObject *d;
++ PyDictEntry *e;
++ d = (PyDictObject *)(f->f_globals);
++ e = d->ma_lookup(d, w, hash);
++ if (e == NULL) {
++ x = NULL;
++ break;
++ }
++ x = e->me_value;
++ if (x != NULL) {
++ Py_INCREF(x);
++ PUSH(x);
++ continue;
++ }
++ d = (PyDictObject *)(f->f_builtins);
++ e = d->ma_lookup(d, w, hash);
++ if (e == NULL) {
++ x = NULL;
++ break;
++ }
++ x = e->me_value;
++ if (x != NULL) {
++ Py_INCREF(x);
++ PUSH(x);
++ continue;
++ }
++ goto load_global_error;
+ }
+- x = e->me_value;
+- if (x != NULL) {
+- Py_INCREF(x);
+- PUSH(x);
+- continue;
+- }
+- d = (PyDictObject *)(f->f_builtins);
+- e = d->ma_lookup(d, w, hash);
+- if (e == NULL) {
+- x = NULL;
+- break;
+- }
+- x = e->me_value;
+- if (x != NULL) {
+- Py_INCREF(x);
+- PUSH(x);
+- continue;
+- }
+- goto load_global_error;
+ }
+- }
+- /* This is the un-inlined version of the code above */
+- x = PyDict_GetItem(f->f_globals, w);
+- if (x == NULL) {
+- x = PyDict_GetItem(f->f_builtins, w);
++ /* This is the un-inlined version of the code above */
++ x = PyDict_GetItem(f->f_globals, w);
+ if (x == NULL) {
+- load_global_error:
+- format_exc_check_arg(
+- PyExc_NameError,
+- GLOBAL_NAME_ERROR_MSG, w);
+- break;
++ x = PyDict_GetItem(f->f_builtins, w);
++ if (x == NULL)
++ goto load_global_error;
+ }
++ } else {
++ x = PyDict_GetItem(f->f_globals, w);
++ if (x == NULL) {
++ x = PyObject_GetItem(f->f_builtins, w);
++ if (x == NULL)
++ goto load_global_error;
++ }
+ }
+ Py_INCREF(x);
+ PUSH(x);
+ continue;
+
++load_global_error:
++ format_exc_check_arg(
++ PyExc_NameError,
++ GLOBAL_NAME_ERROR_MSG, w);
++ break;
++
+ case DELETE_FAST:
+ x = GETLOCAL(oparg);
+ if (x != NULL) {
+@@ -2295,7 +2309,16 @@
+
+ case IMPORT_NAME:
+ w = GETITEM(names, oparg);
+- x = PyDict_GetItemString(f->f_builtins, "__import__");
++ if (PyDict_CheckExact(f->f_builtins))
++ x = PyDict_GetItemString(f->f_builtins, "__import__");
++ else {
++ if (import_str == NULL) {
++ import_str = PyString_FromString("__import__");
++ if (import_str == NULL)
++ break;
++ }
++ x = PyObject_GetItem(f->f_builtins, import_str);
++ }
+ if (x == NULL) {
+ PyErr_SetString(PyExc_ImportError,
+ "__import__ not found");
+Index: Objects/frameobject.c
+===================================================================
+--- Objects/frameobject.c (révision 84785)
++++ Objects/frameobject.c (copie de travail)
+@@ -641,8 +641,6 @@
+ builtins = PyModule_GetDict(builtins);
+ assert(!builtins || PyDict_Check(builtins));
+ }
+- else if (!PyDict_Check(builtins))
+- builtins = NULL;
+ }
+ if (builtins == NULL) {
+ /* No builtins! Make up a minimal one
+@@ -661,7 +659,6 @@
+ /* If we share the globals, we share the builtins.
+ Save a lookup and a call. */
+ builtins = back->f_builtins;
+- assert(builtins != NULL && PyDict_Check(builtins));
+ Py_INCREF(builtins);
+ }
+ if (code->co_zombieframe != NULL) {
View
279 cpython3_ceval.patch
@@ -0,0 +1,279 @@
+Patch LOAD_BUILD_CLASS, LOAD_GLOBAL, LOAD_NAME, IMPORT_NAME bytecodes to
+support frame->f_builtins of other type than dict.
+
+Patch PyFrame_New(): don't check globals()['__builtins__'] or back->f_builtins
+type.
+
+The overhead is approximativelly 0,1%. pybench output (py3k compiled in pydebug
+mode):
+
+-------------------------------------------------------------------------------
+
+ Rounds: 3
+ Warp: 10
+ Timer: time.time
+
+ Machine Details:
+ Platform ID: Linux-2.6.30.10-105.2.23.fc11.i586-i686-with-fedora-11-Leonidas
+ Processor: i686
+
+ Python:
+ Implementation: CPython
+ Executable: /home/haypo/prog/GIT/py3k/python
+ Version: 3.2a2+.0
+ Compiler: GCC 4.4.1 20090725 (Red Hat 4.4.1-2)
+ Bits: 32bit
+ Build: Sep 21 2010 18:49:12 (#unknown)
+ Unicode: UCS2
+
+
+Test minimum run-time average run-time
+ this other diff this other diff
+-------------------------------------------------------------------------------
+ BuiltinFunctionCalls: 1258ms 1246ms +1.0% 1318ms 1268ms +3.9%
+ BuiltinMethodLookup: 730ms 737ms -1.0% 746ms 763ms -2.3%
+ CompareFloats: 779ms 803ms -3.1% 821ms 822ms -0.1%
+ CompareFloatsIntegers: 1483ms 1470ms +0.9% 1490ms 1486ms +0.3%
+ CompareIntegers: 1223ms 1249ms -2.1% 1265ms 1255ms +0.9%
+ CompareInternedStrings: 864ms 884ms -2.3% 868ms 891ms -2.5%
+ CompareLongs: 701ms 720ms -2.5% 708ms 724ms -2.1%
+ CompareStrings: 779ms 802ms -2.9% 784ms 806ms -2.7%
+ ComplexPythonFunctionCalls: 1764ms 1738ms +1.5% 1798ms 1748ms +2.8%
+ ConcatStrings: 1471ms 1453ms +1.3% 1478ms 1475ms +0.2%
+ CreateInstances: 1824ms 1835ms -0.6% 1849ms 1859ms -0.5%
+ CreateNewInstances: 1366ms 1376ms -0.7% 1375ms 1382ms -0.5%
+ CreateStringsWithConcat: 1613ms 1589ms +1.6% 1617ms 1602ms +0.9%
+ DictCreation: 517ms 525ms -1.4% 523ms 538ms -2.9%
+ DictWithFloatKeys: 836ms 829ms +0.8% 849ms 868ms -2.2%
+ DictWithIntegerKeys: 701ms 686ms +2.2% 708ms 697ms +1.6%
+ DictWithStringKeys: 643ms 635ms +1.2% 654ms 661ms -1.0%
+ ForLoops: 883ms 884ms -0.1% 886ms 888ms -0.2%
+ IfThenElse: 954ms 947ms +0.8% 971ms 953ms +1.9%
+ ListSlicing: 1110ms 1105ms +0.5% 1122ms 1152ms -2.6%
+ NestedForLoops: 1297ms 1308ms -0.9% 1315ms 1315ms +0.0%
+ NestedListComprehensions: 1381ms 1352ms +2.2% 1385ms 1387ms -0.1%
+ NormalClassAttribute: 1380ms 1411ms -2.2% 1395ms 1430ms -2.5%
+ NormalInstanceAttribute: 904ms 935ms -3.2% 917ms 965ms -5.1%
+ PythonFunctionCalls: 2126ms 2123ms +0.1% 2128ms 2143ms -0.7%
+ PythonMethodCalls: 2046ms 2051ms -0.3% 2191ms 2114ms +3.6%
+ Recursion: 3570ms 3651ms -2.2% 3669ms 3776ms -2.8%
+ SecondImport: 1113ms 1083ms +2.8% 1116ms 1089ms +2.4%
+ SecondPackageImport: 1124ms 1094ms +2.8% 1128ms 1109ms +1.7%
+ SecondSubmoduleImport: 1438ms 1455ms -1.2% 1440ms 1478ms -2.6%
+ SimpleComplexArithmetic: 1269ms 1269ms +0.0% 1274ms 1289ms -1.2%
+ SimpleDictManipulation: 2593ms 2594ms -0.1% 2641ms 2650ms -0.3%
+ SimpleFloatArithmetic: 736ms 753ms -2.2% 739ms 766ms -3.5%
+ SimpleIntFloatArithmetic: 816ms 804ms +1.5% 820ms 820ms -0.0%
+ SimpleIntegerArithmetic: 817ms 802ms +1.8% 819ms 834ms -1.7%
+ SimpleListComprehensions: 1070ms 1058ms +1.1% 1084ms 1088ms -0.4%
+ SimpleListManipulation: 811ms 793ms +2.3% 813ms 803ms +1.3%
+ SimpleLongArithmetic: 932ms 935ms -0.3% 962ms 950ms +1.3%
+ SmallLists: 1267ms 1247ms +1.6% 1414ms 1302ms +8.5%
+ SmallTuples: 1411ms 1425ms -0.9% 1426ms 1434ms -0.6%
+ SpecialClassAttribute: 2245ms 2221ms +1.1% 2276ms 2249ms +1.2%
+ SpecialInstanceAttribute: 896ms 906ms -1.1% 1008ms 961ms +4.9%
+ StringMappings: 2383ms 2383ms +0.0% 2408ms 2428ms -0.8%
+ StringPredicates: 1077ms 1096ms -1.7% 1110ms 1100ms +0.9%
+ StringSlicing: 2054ms 2035ms +0.9% 2070ms 2085ms -0.7%
+ TryExcept: 598ms 599ms -0.1% 601ms 616ms -2.4%
+ TryFinally: 2059ms 2032ms +1.3% 2066ms 2103ms -1.8%
+ TryRaiseExcept: 603ms 625ms -3.6% 604ms 631ms -4.2%
+ TupleSlicing: 1541ms 1516ms +1.6% 1548ms 1532ms +1.1%
+ WithFinally: 2566ms 2572ms -0.3% 2594ms 2675ms -3.1%
+ WithRaiseExcept: 2464ms 2496ms -1.3% 2474ms 2526ms -2.1%
+-------------------------------------------------------------------------------
+Totals: 68086ms 68135ms -0.1% 69266ms 69487ms -0.3%
+
+diff --git a/Objects/frameobject.c b/Objects/frameobject.c
+index 10fb8b3..9527359 100644
+--- a/Objects/frameobject.c
++++ b/Objects/frameobject.c
+@@ -614,8 +614,6 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
+ builtins = PyModule_GetDict(builtins);
+ assert(!builtins || PyDict_Check(builtins));
+ }
+- else if (!PyDict_Check(builtins))
+- builtins = NULL;
+ }
+ if (builtins == NULL) {
+ /* No builtins! Make up a minimal one
+@@ -634,7 +632,6 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
+ /* If we share the globals, we share the builtins.
+ Save a lookup and a call. */
+ builtins = back->f_builtins;
+- assert(builtins != NULL && PyDict_Check(builtins));
+ Py_INCREF(builtins);
+ }
+ if (code->co_zombieframe != NULL) {
+diff --git a/Python/ceval.c b/Python/ceval.c
+index 48b5678..f1b50a1 100644
+--- a/Python/ceval.c
++++ b/Python/ceval.c
+@@ -119,6 +119,8 @@ static PyObject * load_args(PyObject ***, int);
+ #define CALL_FLAG_VAR 1
+ #define CALL_FLAG_KW 2
+
++static PyObject *import_str = NULL;
++static PyObject *build_class_str = NULL;
+ #ifdef LLTRACE
+ static int lltrace;
+ static int prtrace(PyObject *, char *);
+@@ -1933,8 +1935,16 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
+ break;
+
+ TARGET(LOAD_BUILD_CLASS)
+- x = PyDict_GetItemString(f->f_builtins,
+- "__build_class__");
++ if (PyDict_CheckExact(f->f_builtins))
++ x = PyDict_GetItemString(f->f_builtins, "__build_class__");
++ else {
++ if (build_class_str == NULL) {
++ build_class_str = PyUnicode_FromString("__build_class__");
++ if (build_class_str == NULL)
++ break;
++ }
++ x = PyObject_GetItem(f->f_builtins, build_class_str);
++ }
+ if (x == NULL) {
+ PyErr_SetString(PyExc_ImportError,
+ "__build_class__ not found");
+@@ -2079,7 +2089,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
+ if (x == NULL) {
+ x = PyDict_GetItem(f->f_globals, w);
+ if (x == NULL) {
+- x = PyDict_GetItem(f->f_builtins, w);
++ if (PyDict_CheckExact(f->f_builtins))
++ x = PyDict_GetItem(f->f_builtins, w);
++ else
++ x = PyObject_GetItem(f->f_builtins, w);
+ if (x == NULL) {
+ format_exc_check_arg(
+ PyExc_NameError,
+@@ -2094,57 +2107,68 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
+
+ TARGET(LOAD_GLOBAL)
+ w = GETITEM(names, oparg);
+- if (PyUnicode_CheckExact(w)) {
+- /* Inline the PyDict_GetItem() calls.
+- WARNING: this is an extreme speed hack.
+- Do not try this at home. */
+- long hash = ((PyUnicodeObject *)w)->hash;
+- if (hash != -1) {
+- PyDictObject *d;
+- PyDictEntry *e;
+- d = (PyDictObject *)(f->f_globals);
+- e = d->ma_lookup(d, w, hash);
+- if (e == NULL) {
+- x = NULL;
+- break;
+- }
+- x = e->me_value;
+- if (x != NULL) {
+- Py_INCREF(x);
+- PUSH(x);
+- DISPATCH();
++ if (PyDict_CheckExact(f->f_builtins)) {
++ if (PyUnicode_CheckExact(w)) {
++ /* Inline the PyDict_GetItem() calls.
++ WARNING: this is an extreme speed hack.
++ Do not try this at home. */
++ long hash = ((PyUnicodeObject *)w)->hash;
++ if (hash != -1) {
++ PyDictObject *d;
++ PyDictEntry *e;
++ d = (PyDictObject *)(f->f_globals);
++ e = d->ma_lookup(d, w, hash);
++ if (e == NULL) {
++ x = NULL;
++ break;
++ }
++ x = e->me_value;
++ if (x != NULL) {
++ Py_INCREF(x);
++ PUSH(x);
++ DISPATCH();
++ }
++ d = (PyDictObject *)(f->f_builtins);
++ e = d->ma_lookup(d, w, hash);
++ if (e == NULL) {
++ x = NULL;
++ break;
++ }
++ x = e->me_value;
++ if (x != NULL) {
++ Py_INCREF(x);
++ PUSH(x);
++ DISPATCH();
++ }
++ goto load_global_error;
+ }
+- d = (PyDictObject *)(f->f_builtins);
+- e = d->ma_lookup(d, w, hash);
+- if (e == NULL) {
+- x = NULL;
+- break;
+- }
+- x = e->me_value;
+- if (x != NULL) {
+- Py_INCREF(x);
+- PUSH(x);
+- DISPATCH();
+- }
+- goto load_global_error;
++ }
++ /* This is the un-inlined version of the code above */
++ x = PyDict_GetItem(f->f_globals, w);
++ if (x == NULL) {
++ x = PyDict_GetItem(f->f_builtins, w);
++ if (x == NULL)
++ goto load_global_error;
+ }
+ }
+- /* This is the un-inlined version of the code above */
+- x = PyDict_GetItem(f->f_globals, w);
+- if (x == NULL) {
+- x = PyDict_GetItem(f->f_builtins, w);
++ else {
++ x = PyDict_GetItem(f->f_globals, w);
+ if (x == NULL) {
+- load_global_error:
+- format_exc_check_arg(
+- PyExc_NameError,
+- GLOBAL_NAME_ERROR_MSG, w);
+- break;
++ x = PyObject_GetItem(f->f_builtins, w);
++ if (x == NULL)
++ goto load_global_error;
+ }
+ }
+ Py_INCREF(x);
+ PUSH(x);
+ DISPATCH();
+
++load_global_error:
++ format_exc_check_arg(
++ PyExc_NameError,
++ GLOBAL_NAME_ERROR_MSG, w);
++ break;
++
+ TARGET(DELETE_FAST)
+ x = GETLOCAL(oparg);
+ if (x != NULL) {
+@@ -2291,7 +2315,16 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
+
+ TARGET(IMPORT_NAME)
+ w = GETITEM(names, oparg);
+- x = PyDict_GetItemString(f->f_builtins, "__import__");
++ if (PyDict_CheckExact(f->f_builtins))
++ x = PyDict_GetItemString(f->f_builtins, "__import__");
++ else {
++ if (import_str == NULL) {
++ import_str = PyUnicode_FromString("__import__");
++ if (import_str == NULL)
++ break;
++ }
++ x = PyObject_GetItem(f->f_builtins, import_str);
++ }
+ if (x == NULL) {
+ PyErr_SetString(PyExc_ImportError,
+ "__import__ not found");
Please sign in to comment.
Something went wrong with that request. Please try again.