diff options
| author | Vibhav Pant | 2017-02-09 12:18:54 +0530 |
|---|---|---|
| committer | Vibhav Pant | 2017-02-09 12:18:54 +0530 |
| commit | dde800c8c9ea198996229d03df1fc45c7d057339 (patch) | |
| tree | 5101a2f8260e141a64af96e84ca565dd8e49a568 /src/bytecode.c | |
| parent | 96c4e367f973626cbab38af55a2c448b7274eeee (diff) | |
| download | emacs-dde800c8c9ea198996229d03df1fc45c7d057339.tar.gz emacs-dde800c8c9ea198996229d03df1fc45c7d057339.zip | |
Improve byte-switch execution.
* lisp/emacs-lisp/byte-opt.el,
lisp/emacs-lisp/bytecomp.el (byte-decompile-bytecode-1),
(byte-compile-lapcode): Calculate the actual jump address while
compiling, store it in the jump table.
* src/bytecode.c: Jump to the looked up value directly, do a linear
search when the number of elements is <= 5.
Diffstat (limited to 'src/bytecode.c')
| -rw-r--r-- | src/bytecode.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/src/bytecode.c b/src/bytecode.c index f9531761b3c..9bb7bd4e685 100644 --- a/src/bytecode.c +++ b/src/bytecode.c | |||
| @@ -1415,20 +1415,39 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 1415 | 1415 | ||
| 1416 | CASE (Bswitch): | 1416 | CASE (Bswitch): |
| 1417 | { | 1417 | { |
| 1418 | /*TODO: Perhaps introduce another byte-code for switch when the | ||
| 1419 | number of cases is less, which uses a simple vector for linear | ||
| 1420 | search as the jump table. */ | ||
| 1418 | Lisp_Object jmp_table = POP; | 1421 | Lisp_Object jmp_table = POP; |
| 1419 | Lisp_Object v1 = POP; | 1422 | Lisp_Object v1 = POP; |
| 1420 | #ifdef BYTE_CODE_SAFE | 1423 | #ifdef BYTE_CODE_SAFE |
| 1421 | CHECK_TYPE (HASH_TABLE_P (jmp_table), Qhash_table_p, jmp_table); | 1424 | CHECK_TYPE (HASH_TABLE_P (jmp_table), Qhash_table_p, jmp_table); |
| 1422 | #endif | 1425 | #endif |
| 1426 | ptrdiff_t i; | ||
| 1423 | struct Lisp_Hash_Table *h = XHASH_TABLE(jmp_table); | 1427 | struct Lisp_Hash_Table *h = XHASH_TABLE(jmp_table); |
| 1424 | ptrdiff_t i = hash_lookup(h, v1, NULL); | 1428 | if (HASH_TABLE_SIZE (h) <= 5) |
| 1425 | if (i >= 0) { | 1429 | { /* Do a linear search if there are not many cases |
| 1426 | Lisp_Object dest = HASH_VALUE(h, i); | 1430 | FIXME: 5 is arbitrarily chosen. */ |
| 1427 | int car = XINT(XCAR(dest)); | 1431 | for (i = 0; i < HASH_TABLE_SIZE (h); i++) |
| 1428 | int cdr = XINT(XCDR(dest)); | 1432 | { |
| 1429 | op = car + (cdr << 8); /* Simulate FETCH2 */ | 1433 | if (!NILP (HASH_HASH (h, i)) && |
| 1430 | goto op_branch; | 1434 | (EQ (v1, HASH_KEY (h, i)) || |
| 1431 | } | 1435 | (h->test.cmpfn && |
| 1436 | h->test.cmpfn (&h->test, v1, HASH_KEY (h, i))))) | ||
| 1437 | { | ||
| 1438 | op = XINT (HASH_VALUE (h, i)); | ||
| 1439 | goto op_branch; | ||
| 1440 | } | ||
| 1441 | } | ||
| 1442 | } | ||
| 1443 | else | ||
| 1444 | { | ||
| 1445 | i = hash_lookup(h, v1, NULL); | ||
| 1446 | if (i >= 0) { | ||
| 1447 | op = XINT(HASH_VALUE (h, i)); | ||
| 1448 | goto op_branch; | ||
| 1449 | } | ||
| 1450 | } | ||
| 1432 | } | 1451 | } |
| 1433 | NEXT; | 1452 | NEXT; |
| 1434 | 1453 | ||