@@ -160,6 +160,8 @@ struct compiler {
160160 int c_interactive ; /* true if in interactive mode */
161161 int c_nestlevel ;
162162
163+ PyObject * c_const_cache ; /* Python dict holding all constants,
164+ including names tuple */
163165 struct compiler_unit * u ; /* compiler state for current block */
164166 PyObject * c_stack ; /* Python list holding compiler_unit ptrs */
165167 PyArena * c_arena ; /* pointer to memory allocation arena */
@@ -285,9 +287,16 @@ compiler_init(struct compiler *c)
285287{
286288 memset (c , 0 , sizeof (struct compiler ));
287289
290+ c -> c_const_cache = PyDict_New ();
291+ if (!c -> c_const_cache ) {
292+ return 0 ;
293+ }
294+
288295 c -> c_stack = PyList_New (0 );
289- if (!c -> c_stack )
296+ if (!c -> c_stack ) {
297+ Py_CLEAR (c -> c_const_cache );
290298 return 0 ;
299+ }
291300
292301 return 1 ;
293302}
@@ -387,6 +396,7 @@ compiler_free(struct compiler *c)
387396 if (c -> c_future )
388397 PyObject_Free (c -> c_future );
389398 Py_XDECREF (c -> c_filename );
399+ Py_DECREF (c -> c_const_cache );
390400 Py_DECREF (c -> c_stack );
391401}
392402
@@ -1179,18 +1189,121 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o)
11791189 return arg ;
11801190}
11811191
1192+ // Merge const *o* recursively and return constant key object.
1193+ static PyObject *
1194+ merge_consts_recursive (struct compiler * c , PyObject * o )
1195+ {
1196+ // None and Ellipsis are singleton, and key is the singleton.
1197+ // No need to merge object and key.
1198+ if (o == Py_None || o == Py_Ellipsis ) {
1199+ Py_INCREF (o );
1200+ return o ;
1201+ }
1202+
1203+ PyObject * key = _PyCode_ConstantKey (o );
1204+ if (key == NULL ) {
1205+ return NULL ;
1206+ }
1207+
1208+ // t is borrowed reference
1209+ PyObject * t = PyDict_SetDefault (c -> c_const_cache , key , key );
1210+ if (t != key ) {
1211+ Py_INCREF (t );
1212+ Py_DECREF (key );
1213+ return t ;
1214+ }
1215+
1216+ if (PyTuple_CheckExact (o )) {
1217+ Py_ssize_t i , len = PyTuple_GET_SIZE (o );
1218+ for (i = 0 ; i < len ; i ++ ) {
1219+ PyObject * item = PyTuple_GET_ITEM (o , i );
1220+ PyObject * u = merge_consts_recursive (c , item );
1221+ if (u == NULL ) {
1222+ Py_DECREF (key );
1223+ return NULL ;
1224+ }
1225+
1226+ // See _PyCode_ConstantKey()
1227+ PyObject * v ; // borrowed
1228+ if (PyTuple_CheckExact (u )) {
1229+ v = PyTuple_GET_ITEM (u , 1 );
1230+ }
1231+ else {
1232+ v = u ;
1233+ }
1234+ if (v != item ) {
1235+ Py_INCREF (v );
1236+ PyTuple_SET_ITEM (o , i , v );
1237+ Py_DECREF (item );
1238+ }
1239+
1240+ Py_DECREF (u );
1241+ }
1242+ }
1243+ else if (PyFrozenSet_CheckExact (o )) {
1244+ // We register items in the frozenset, but don't rewrite
1245+ // the frozenset when the item is already registered
1246+ // because frozenset is rare and difficult.
1247+
1248+ // *key* is tuple. And it's first item is frozenset of
1249+ // constant keys.
1250+ // See _PyCode_ConstantKey() for detail.
1251+ assert (PyTuple_CheckExact (key ));
1252+ assert (PyTuple_GET_SIZE (key ) == 2 );
1253+
1254+ Py_ssize_t len = PySet_GET_SIZE (o );
1255+ if (len == 0 ) {
1256+ return key ;
1257+ }
1258+ PyObject * tuple = PyTuple_New (len );
1259+ if (tuple == NULL ) {
1260+ Py_DECREF (key );
1261+ return NULL ;
1262+ }
1263+ Py_ssize_t i = 0 , pos = 0 ;
1264+ PyObject * item ;
1265+ Py_hash_t hash ;
1266+ while (_PySet_NextEntry (o , & pos , & item , & hash )) {
1267+ PyObject * k = merge_consts_recursive (c , item );
1268+ if (k == NULL ) {
1269+ Py_DECREF (tuple );
1270+ Py_DECREF (key );
1271+ return NULL ;
1272+ }
1273+ PyObject * u ;
1274+ if (PyTuple_CheckExact (k )) {
1275+ u = PyTuple_GET_ITEM (k , 1 );
1276+ }
1277+ else {
1278+ u = k ;
1279+ }
1280+ Py_INCREF (u );
1281+ PyTuple_SET_ITEM (tuple , i , u );
1282+ i ++ ;
1283+ }
1284+
1285+ PyObject * new = PyFrozenSet_New (tuple );
1286+ Py_DECREF (tuple );
1287+ if (new == NULL ) {
1288+ Py_DECREF (key );
1289+ return NULL ;
1290+ }
1291+ PyTuple_SET_ITEM (key , 1 , new );
1292+ }
1293+
1294+ return key ;
1295+ }
1296+
11821297static Py_ssize_t
11831298compiler_add_const (struct compiler * c , PyObject * o )
11841299{
1185- PyObject * t ;
1186- Py_ssize_t arg ;
1187-
1188- t = _PyCode_ConstantKey (o );
1189- if (t == NULL )
1300+ PyObject * key = merge_consts_recursive (c , o );
1301+ if (key == NULL ) {
11901302 return -1 ;
1303+ }
11911304
1192- arg = compiler_add_o (c , c -> u -> u_consts , t );
1193- Py_DECREF (t );
1305+ Py_ssize_t arg = compiler_add_o (c , c -> u -> u_consts , key );
1306+ Py_DECREF (key );
11941307 return arg ;
11951308}
11961309
@@ -5380,6 +5493,35 @@ compute_code_flags(struct compiler *c)
53805493 return flags ;
53815494}
53825495
5496+ // Merge *tuple* with constant cache.
5497+ // Unlike merge_consts_recursive(), this function doesn't work recursively.
5498+ static int
5499+ merge_const_tuple (struct compiler * c , PyObject * * tuple )
5500+ {
5501+ assert (PyTuple_CheckExact (* tuple ));
5502+
5503+ PyObject * key = _PyCode_ConstantKey (* tuple );
5504+ if (key == NULL ) {
5505+ return 0 ;
5506+ }
5507+
5508+ // t is borrowed reference
5509+ PyObject * t = PyDict_SetDefault (c -> c_const_cache , key , key );
5510+ Py_DECREF (key );
5511+ if (t == NULL ) {
5512+ return 0 ;
5513+ }
5514+ if (t == key ) { // tuple is new constant.
5515+ return 1 ;
5516+ }
5517+
5518+ PyObject * u = PyTuple_GET_ITEM (t , 1 );
5519+ Py_INCREF (u );
5520+ Py_DECREF (* tuple );
5521+ * tuple = u ;
5522+ return 1 ;
5523+ }
5524+
53835525static PyCodeObject *
53845526makecode (struct compiler * c , struct assembler * a )
53855527{
@@ -5410,6 +5552,14 @@ makecode(struct compiler *c, struct assembler *a)
54105552 if (!freevars )
54115553 goto error ;
54125554
5555+ if (!merge_const_tuple (c , & names ) ||
5556+ !merge_const_tuple (c , & varnames ) ||
5557+ !merge_const_tuple (c , & cellvars ) ||
5558+ !merge_const_tuple (c , & freevars ))
5559+ {
5560+ goto error ;
5561+ }
5562+
54135563 nlocals = PyDict_GET_SIZE (c -> u -> u_varnames );
54145564 assert (nlocals < INT_MAX );
54155565 nlocals_int = Py_SAFE_DOWNCAST (nlocals , Py_ssize_t , int );
@@ -5427,6 +5577,9 @@ makecode(struct compiler *c, struct assembler *a)
54275577 goto error ;
54285578 Py_DECREF (consts );
54295579 consts = tmp ;
5580+ if (!merge_const_tuple (c , & consts )) {
5581+ goto error ;
5582+ }
54305583
54315584 argcount = Py_SAFE_DOWNCAST (c -> u -> u_argcount , Py_ssize_t , int );
54325585 kwonlyargcount = Py_SAFE_DOWNCAST (c -> u -> u_kwonlyargcount , Py_ssize_t , int );
0 commit comments