diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2005-11-30 14:59:39 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2005-11-30 14:59:39 (GMT) |
commit | 53c04f83d2b2ef25f90e34e7d05273f965790caa (patch) | |
tree | 1b07469f13d8ee2956bcb114e0992788298dc395 /generic/tclExecute.c | |
parent | c3ae410bfd9c50b4b93c65bb20d96aca055c8c81 (diff) | |
download | tcl-53c04f83d2b2ef25f90e34e7d05273f965790caa.zip tcl-53c04f83d2b2ef25f90e34e7d05273f965790caa.tar.gz tcl-53c04f83d2b2ef25f90e34e7d05273f965790caa.tar.bz2 |
New TEBC opcode, INST_JUMP_TABLE, for compiling the simple (and common) case of
[switch] into a jump-table. Much faster for long switches.
Also compiler support for generating the new instruction where appropriate.
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r-- | generic/tclExecute.c | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 38a7a6e..31870b5 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclExecute.c,v 1.221 2005/11/27 02:33:49 das Exp $ + * RCS: @(#) $Id: tclExecute.c,v 1.222 2005/11/30 14:59:40 dkf Exp $ */ #include "tclInt.h" @@ -2601,25 +2601,23 @@ TclExecuteByteCode( * --------------------------------------------------------- */ - case INST_JUMP1: - { - int opnd; + case INST_JUMP1: { + int opnd; - opnd = TclGetInt1AtPtr(pc+1); - TRACE(("%d => new pc %u\n", opnd, - (unsigned int)(pc + opnd - codePtr->codeStart))); - NEXT_INST_F(opnd, 0, 0); - } + opnd = TclGetInt1AtPtr(pc+1); + TRACE(("%d => new pc %u\n", opnd, + (unsigned int)(pc + opnd - codePtr->codeStart))); + NEXT_INST_F(opnd, 0, 0); + } - case INST_JUMP4: - { - int opnd; + case INST_JUMP4: { + int opnd; - opnd = TclGetInt4AtPtr(pc+1); - TRACE(("%d => new pc %u\n", opnd, - (unsigned int)(pc + opnd - codePtr->codeStart))); - NEXT_INST_F(opnd, 0, 0); - } + opnd = TclGetInt4AtPtr(pc+1); + TRACE(("%d => new pc %u\n", opnd, + (unsigned int)(pc + opnd - codePtr->codeStart))); + NEXT_INST_F(opnd, 0, 0); + } { int jmpOffset[2]; @@ -2680,6 +2678,32 @@ TclExecuteByteCode( NEXT_INST_F(jmpOffset[b], 1, 0); } + case INST_JUMP_TABLE: { + Tcl_HashEntry *hPtr; + JumptableInfo *jtPtr; + int opnd; + + /* + * Jump to location looked up in a hashtable; fall through to next + * instr if lookup fails. + */ + + opnd = TclGetInt4AtPtr(pc+1); + jtPtr = (JumptableInfo *) codePtr->auxDataArrayPtr[opnd].clientData; + TRACE(("%d => %.20s ", opnd, O2S(*tosPtr))); + hPtr = Tcl_FindHashEntry(&jtPtr->hashTable, Tcl_GetString(*tosPtr)); + if (hPtr != NULL) { + int jumpOffset = (int) Tcl_GetHashValue(hPtr); + + TRACE_APPEND(("found in table, new pc %u\n", + (unsigned int)(pc - codePtr->codeStart + jumpOffset))); + NEXT_INST_F(jumpOffset, 1, 0); + } else { + TRACE_APPEND(("not found in table\n")); + NEXT_INST_F(5, 1, 0); + } + } + /* * These two instructions are now redundant: the complete logic of the LOR * and LAND is now handled by the expression compiler. |