forked from vstinner/pysandbox
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cpython3_ceval.patch
279 lines (265 loc) · 13 KB
/
cpython3_ceval.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
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");