|
32 | 32 | #include "py/mpstate.h" |
33 | 33 | #include "py/nlr.h" |
34 | 34 | #include "py/emitglue.h" |
| 35 | +#include "py/objtype.h" |
35 | 36 | #include "py/runtime.h" |
36 | 37 | #include "py/bc0.h" |
37 | 38 | #include "py/bc.h" |
@@ -248,26 +249,101 @@ mp_vm_return_kind_t mp_execute_bytecode(mp_code_state *code_state, volatile mp_o |
248 | 249 | goto load_check; |
249 | 250 | } |
250 | 251 |
|
| 252 | + #if !MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE |
251 | 253 | ENTRY(MP_BC_LOAD_NAME): { |
252 | 254 | MARK_EXC_IP_SELECTIVE(); |
253 | 255 | DECODE_QSTR; |
254 | 256 | PUSH(mp_load_name(qst)); |
255 | 257 | DISPATCH(); |
256 | 258 | } |
| 259 | + #else |
| 260 | + ENTRY(MP_BC_LOAD_NAME): { |
| 261 | + MARK_EXC_IP_SELECTIVE(); |
| 262 | + DECODE_QSTR; |
| 263 | + mp_obj_t key = MP_OBJ_NEW_QSTR(qst); |
| 264 | + mp_uint_t x = *ip; |
| 265 | + if (x < MP_STATE_CTX(dict_locals)->map.alloc && MP_STATE_CTX(dict_locals)->map.table[x].key == key) { |
| 266 | + PUSH(MP_STATE_CTX(dict_locals)->map.table[x].value); |
| 267 | + } else { |
| 268 | + mp_map_elem_t *elem = mp_map_lookup(&MP_STATE_CTX(dict_locals)->map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP); |
| 269 | + if (elem != NULL) { |
| 270 | + *(byte*)ip = (elem - &MP_STATE_CTX(dict_locals)->map.table[0]) & 0xff; |
| 271 | + PUSH(elem->value); |
| 272 | + } else { |
| 273 | + PUSH(mp_load_name(MP_OBJ_QSTR_VALUE(key))); |
| 274 | + } |
| 275 | + } |
| 276 | + ip++; |
| 277 | + DISPATCH(); |
| 278 | + } |
| 279 | + #endif |
257 | 280 |
|
| 281 | + #if !MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE |
258 | 282 | ENTRY(MP_BC_LOAD_GLOBAL): { |
259 | 283 | MARK_EXC_IP_SELECTIVE(); |
260 | 284 | DECODE_QSTR; |
261 | 285 | PUSH(mp_load_global(qst)); |
262 | 286 | DISPATCH(); |
263 | 287 | } |
| 288 | + #else |
| 289 | + ENTRY(MP_BC_LOAD_GLOBAL): { |
| 290 | + MARK_EXC_IP_SELECTIVE(); |
| 291 | + DECODE_QSTR; |
| 292 | + mp_obj_t key = MP_OBJ_NEW_QSTR(qst); |
| 293 | + mp_uint_t x = *ip; |
| 294 | + if (x < MP_STATE_CTX(dict_globals)->map.alloc && MP_STATE_CTX(dict_globals)->map.table[x].key == key) { |
| 295 | + PUSH(MP_STATE_CTX(dict_globals)->map.table[x].value); |
| 296 | + } else { |
| 297 | + mp_map_elem_t *elem = mp_map_lookup(&MP_STATE_CTX(dict_globals)->map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP); |
| 298 | + if (elem != NULL) { |
| 299 | + *(byte*)ip = (elem - &MP_STATE_CTX(dict_globals)->map.table[0]) & 0xff; |
| 300 | + PUSH(elem->value); |
| 301 | + } else { |
| 302 | + PUSH(mp_load_global(MP_OBJ_QSTR_VALUE(key))); |
| 303 | + } |
| 304 | + } |
| 305 | + ip++; |
| 306 | + DISPATCH(); |
| 307 | + } |
| 308 | + #endif |
264 | 309 |
|
| 310 | + #if !MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE |
265 | 311 | ENTRY(MP_BC_LOAD_ATTR): { |
266 | 312 | MARK_EXC_IP_SELECTIVE(); |
267 | 313 | DECODE_QSTR; |
268 | 314 | SET_TOP(mp_load_attr(TOP(), qst)); |
269 | 315 | DISPATCH(); |
270 | 316 | } |
| 317 | + #else |
| 318 | + ENTRY(MP_BC_LOAD_ATTR): { |
| 319 | + MARK_EXC_IP_SELECTIVE(); |
| 320 | + DECODE_QSTR; |
| 321 | + mp_obj_t top = TOP(); |
| 322 | + if (mp_obj_get_type(top)->load_attr == mp_obj_instance_load_attr) { |
| 323 | + mp_obj_instance_t *self = top; |
| 324 | + mp_uint_t x = *ip; |
| 325 | + mp_obj_t key = MP_OBJ_NEW_QSTR(qst); |
| 326 | + mp_map_elem_t *elem; |
| 327 | + if (x < self->members.alloc && self->members.table[x].key == key) { |
| 328 | + elem = &self->members.table[x]; |
| 329 | + } else { |
| 330 | + elem = mp_map_lookup(&self->members, key, MP_MAP_LOOKUP); |
| 331 | + if (elem != NULL) { |
| 332 | + *(byte*)ip = elem - &self->members.table[0]; |
| 333 | + } else { |
| 334 | + goto load_attr_cache_fail; |
| 335 | + } |
| 336 | + } |
| 337 | + SET_TOP(elem->value); |
| 338 | + ip++; |
| 339 | + DISPATCH(); |
| 340 | + } |
| 341 | + load_attr_cache_fail: |
| 342 | + SET_TOP(mp_load_attr(top, qst)); |
| 343 | + ip++; |
| 344 | + DISPATCH(); |
| 345 | + } |
| 346 | + #endif |
271 | 347 |
|
272 | 348 | ENTRY(MP_BC_LOAD_METHOD): { |
273 | 349 | MARK_EXC_IP_SELECTIVE(); |
@@ -315,13 +391,50 @@ mp_vm_return_kind_t mp_execute_bytecode(mp_code_state *code_state, volatile mp_o |
315 | 391 | DISPATCH(); |
316 | 392 | } |
317 | 393 |
|
| 394 | + #if !MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE |
318 | 395 | ENTRY(MP_BC_STORE_ATTR): { |
319 | 396 | MARK_EXC_IP_SELECTIVE(); |
320 | 397 | DECODE_QSTR; |
321 | 398 | mp_store_attr(sp[0], qst, sp[-1]); |
322 | 399 | sp -= 2; |
323 | 400 | DISPATCH(); |
324 | 401 | } |
| 402 | + #else |
| 403 | + // This caching code works with MICROPY_PY_BUILTINS_PROPERTY enabled because |
| 404 | + // if the attr exists in self->members then it can't be a property. A |
| 405 | + // consequence of this is that we can't use MP_MAP_LOOKUP_ADD_IF_NOT_FOUND |
| 406 | + // in the fast-path below, because that store could override a property. |
| 407 | + ENTRY(MP_BC_STORE_ATTR): { |
| 408 | + MARK_EXC_IP_SELECTIVE(); |
| 409 | + DECODE_QSTR; |
| 410 | + mp_obj_t top = TOP(); |
| 411 | + if (mp_obj_get_type(top)->store_attr == mp_obj_instance_store_attr && sp[-1] != MP_OBJ_NULL) { |
| 412 | + mp_obj_instance_t *self = top; |
| 413 | + mp_uint_t x = *ip; |
| 414 | + mp_obj_t key = MP_OBJ_NEW_QSTR(qst); |
| 415 | + mp_map_elem_t *elem; |
| 416 | + if (x < self->members.alloc && self->members.table[x].key == key) { |
| 417 | + elem = &self->members.table[x]; |
| 418 | + } else { |
| 419 | + elem = mp_map_lookup(&self->members, key, MP_MAP_LOOKUP); |
| 420 | + if (elem != NULL) { |
| 421 | + *(byte*)ip = elem - &self->members.table[0]; |
| 422 | + } else { |
| 423 | + goto store_attr_cache_fail; |
| 424 | + } |
| 425 | + } |
| 426 | + elem->value = sp[-1]; |
| 427 | + sp -= 2; |
| 428 | + ip++; |
| 429 | + DISPATCH(); |
| 430 | + } |
| 431 | + store_attr_cache_fail: |
| 432 | + mp_store_attr(sp[0], qst, sp[-1]); |
| 433 | + sp -= 2; |
| 434 | + ip++; |
| 435 | + DISPATCH(); |
| 436 | + } |
| 437 | + #endif |
325 | 438 |
|
326 | 439 | ENTRY(MP_BC_STORE_SUBSCR): |
327 | 440 | MARK_EXC_IP_SELECTIVE(); |
|
0 commit comments