mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-24 06:20:43 -08:00
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.
This commit is contained in:
parent
96c4e367f9
commit
dde800c8c9
3 changed files with 33 additions and 15 deletions
|
|
@ -1411,10 +1411,8 @@
|
||||||
;; Replace all addresses with TAGs.
|
;; Replace all addresses with TAGs.
|
||||||
(maphash #'(lambda (value tag)
|
(maphash #'(lambda (value tag)
|
||||||
(let (newtag)
|
(let (newtag)
|
||||||
(cl-assert (consp tag)
|
|
||||||
nil "Invalid address for byte-switch")
|
|
||||||
(setq newtag (byte-compile-make-tag))
|
(setq newtag (byte-compile-make-tag))
|
||||||
(push (cons (+ (car tag) (lsh (cdr tag) 8)) newtag) tags)
|
(push (cons tag newtag) tags)
|
||||||
(puthash value newtag last-constant)))
|
(puthash value newtag last-constant)))
|
||||||
last-constant)
|
last-constant)
|
||||||
;; Replace the hash table referenced in the lapcode with our
|
;; Replace the hash table referenced in the lapcode with our
|
||||||
|
|
|
||||||
|
|
@ -917,10 +917,11 @@ CONST2 may be evaluated multiple times."
|
||||||
(if (> (car bytes-tail) 255) (error "Bytecode overflow")))
|
(if (> (car bytes-tail) 255) (error "Bytecode overflow")))
|
||||||
|
|
||||||
(dolist (hash-table byte-compile-jump-tables)
|
(dolist (hash-table byte-compile-jump-tables)
|
||||||
(cl-loop for k being the hash-keys of hash-table do
|
(maphash #'(lambda (value tag)
|
||||||
(let ((tag (cdr (gethash k hash-table))))
|
(setq pc (cadr tag))
|
||||||
(setq pc (car tag))
|
(puthash value (+ (logand pc 255) (lsh (lsh pc -8) 8))
|
||||||
(puthash k (cons (logand pc 255) (lsh pc -8)) hash-table))))
|
hash-table))
|
||||||
|
hash-table))
|
||||||
(apply 'unibyte-string (nreverse bytes))))
|
(apply 'unibyte-string (nreverse bytes))))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1415,20 +1415,39 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
|
||||||
|
|
||||||
CASE (Bswitch):
|
CASE (Bswitch):
|
||||||
{
|
{
|
||||||
|
/*TODO: Perhaps introduce another byte-code for switch when the
|
||||||
|
number of cases is less, which uses a simple vector for linear
|
||||||
|
search as the jump table. */
|
||||||
Lisp_Object jmp_table = POP;
|
Lisp_Object jmp_table = POP;
|
||||||
Lisp_Object v1 = POP;
|
Lisp_Object v1 = POP;
|
||||||
#ifdef BYTE_CODE_SAFE
|
#ifdef BYTE_CODE_SAFE
|
||||||
CHECK_TYPE (HASH_TABLE_P (jmp_table), Qhash_table_p, jmp_table);
|
CHECK_TYPE (HASH_TABLE_P (jmp_table), Qhash_table_p, jmp_table);
|
||||||
#endif
|
#endif
|
||||||
|
ptrdiff_t i;
|
||||||
struct Lisp_Hash_Table *h = XHASH_TABLE(jmp_table);
|
struct Lisp_Hash_Table *h = XHASH_TABLE(jmp_table);
|
||||||
ptrdiff_t i = hash_lookup(h, v1, NULL);
|
if (HASH_TABLE_SIZE (h) <= 5)
|
||||||
if (i >= 0) {
|
{ /* Do a linear search if there are not many cases
|
||||||
Lisp_Object dest = HASH_VALUE(h, i);
|
FIXME: 5 is arbitrarily chosen. */
|
||||||
int car = XINT(XCAR(dest));
|
for (i = 0; i < HASH_TABLE_SIZE (h); i++)
|
||||||
int cdr = XINT(XCDR(dest));
|
{
|
||||||
op = car + (cdr << 8); /* Simulate FETCH2 */
|
if (!NILP (HASH_HASH (h, i)) &&
|
||||||
goto op_branch;
|
(EQ (v1, HASH_KEY (h, i)) ||
|
||||||
}
|
(h->test.cmpfn &&
|
||||||
|
h->test.cmpfn (&h->test, v1, HASH_KEY (h, i)))))
|
||||||
|
{
|
||||||
|
op = XINT (HASH_VALUE (h, i));
|
||||||
|
goto op_branch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i = hash_lookup(h, v1, NULL);
|
||||||
|
if (i >= 0) {
|
||||||
|
op = XINT(HASH_VALUE (h, i));
|
||||||
|
goto op_branch;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
NEXT;
|
NEXT;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue