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 | |
| 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.
| -rw-r--r-- | lisp/emacs-lisp/byte-opt.el | 4 | ||||
| -rw-r--r-- | lisp/emacs-lisp/bytecomp.el | 9 | ||||
| -rw-r--r-- | src/bytecode.c | 35 |
3 files changed, 33 insertions, 15 deletions
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 888a5f85007..3bec3e61df9 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el | |||
| @@ -1411,10 +1411,8 @@ | |||
| 1411 | ;; Replace all addresses with TAGs. | 1411 | ;; Replace all addresses with TAGs. |
| 1412 | (maphash #'(lambda (value tag) | 1412 | (maphash #'(lambda (value tag) |
| 1413 | (let (newtag) | 1413 | (let (newtag) |
| 1414 | (cl-assert (consp tag) | ||
| 1415 | nil "Invalid address for byte-switch") | ||
| 1416 | (setq newtag (byte-compile-make-tag)) | 1414 | (setq newtag (byte-compile-make-tag)) |
| 1417 | (push (cons (+ (car tag) (lsh (cdr tag) 8)) newtag) tags) | 1415 | (push (cons tag newtag) tags) |
| 1418 | (puthash value newtag last-constant))) | 1416 | (puthash value newtag last-constant))) |
| 1419 | last-constant) | 1417 | last-constant) |
| 1420 | ;; Replace the hash table referenced in the lapcode with our | 1418 | ;; Replace the hash table referenced in the lapcode with our |
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index d5a163e5fdd..748a8cd01f3 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el | |||
| @@ -917,10 +917,11 @@ CONST2 may be evaluated multiple times." | |||
| 917 | (if (> (car bytes-tail) 255) (error "Bytecode overflow"))) | 917 | (if (> (car bytes-tail) 255) (error "Bytecode overflow"))) |
| 918 | 918 | ||
| 919 | (dolist (hash-table byte-compile-jump-tables) | 919 | (dolist (hash-table byte-compile-jump-tables) |
| 920 | (cl-loop for k being the hash-keys of hash-table do | 920 | (maphash #'(lambda (value tag) |
| 921 | (let ((tag (cdr (gethash k hash-table)))) | 921 | (setq pc (cadr tag)) |
| 922 | (setq pc (car tag)) | 922 | (puthash value (+ (logand pc 255) (lsh (lsh pc -8) 8)) |
| 923 | (puthash k (cons (logand pc 255) (lsh pc -8)) hash-table)))) | 923 | hash-table)) |
| 924 | hash-table)) | ||
| 924 | (apply 'unibyte-string (nreverse bytes)))) | 925 | (apply 'unibyte-string (nreverse bytes)))) |
| 925 | 926 | ||
| 926 | 927 | ||
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 | ||