indirection typically makes it slower, though usually still faster than bytecode interpreters. Where the handler operands include both values and types, the space savings over direct-threaded code may be significant. Older FORTH systems typically produce indirect-threaded code. For example, if the goal is to execute "push A, push B, add", the following might be used. Here, ip is initialized to address &thread, each code fragment (push, add) is found by double-indirecting through ip and an indirect block; and any operands to the fragment are found in the indirect block following the fragment's address. This requires keeping the current subroutine in ip, unlike all previous examples where it contained the next subroutine to be called. start: ip = &thread // points to '&i_pushA' jump *(*ip) // follow pointers to 1st instruction of 'push', DO NOT advance ip yet thread: &i_pushA &i_pushB &i_add ... i_pushA: &push &A i_pushB: &push &B i_add: &add push: *sp++ = *(*ip + 1) // look 1 past start of indirect block for operand address jump *(*++ip) // advance ip in thread, jump through next indirect block to next subroutine add: addend1 = *--sp addend2 = *--sp *sp++ = addend1 + addend2 jump *(*++ip) Subroutine threading So-called "subroutine-threaded code" (also "call-threaded code") consists of a series of machine-language "call" instructions (or addresses of functions to "call", as opposed to direct threading's use of "jump"). Early compilers for ALGOL, Fortran, Cobol and some Forth systems often produced subroutine-threaded code. The code in many of these systems operated on a last-in-first-out (LIFO) stack of operands, for which compiler theory was well-developed. Most modern processors have special hardware support for subroutine "call" and "return" instructions, so the overhead of one extra machine instruction per dispatch is somewhat diminished. Anton Ertl, the Gforth compiler's co-creator, stated that "in contrast to popular myths, subroutine threading is usually slower than direct threading". However, Ertl's most recent tests show that subroutine threading is faster than direct threading in 15 out of 25 test cases. More specifically, he found that direct threading is the fastest threading model on Xeon, Opteron, and Athlon processors, indirect threading is fastest on Pentium M processors, and subroutine threading is fastest on Pentium 4, Pentium III, and PPC processors. As an example of call threading for "push A, push B, add": thread: call pushA call pushB call add ret pushA: *sp++ = A ret pushB: *sp++ = B ret add: addend1