1 #!/usr/bin/tcl 2 # 3 # This script makes modifications to the vdbe.c source file which reduce 4 # the amount of stack space required by the sqlite3VdbeExec() routine. 5 # 6 # The modifications performed by this script are optional. The vdbe.c 7 # source file will compile correctly with and without the modifications 8 # performed by this script. And all routines within vdbe.c will compute 9 # the same result. The modifications made by this script merely help 10 # the C compiler to generate code for sqlite3VdbeExec() that uses less 11 # stack space. 12 # 13 # Script usage: 14 # 15 # mv vdbe.c vdbe.c.template 16 # tclsh vdbe-compress.tcl <vdbe.c.template >vdbe.c 17 # 18 # Modifications made: 19 # 20 # All modifications are within the sqlite3VdbeExec() function. The 21 # modifications seek to reduce the amount of stack space allocated by 22 # this routine by moving local variable declarations out of individual 23 # opcode implementations and into a single large union. The union contains 24 # a separate structure for each opcode and that structure contains the 25 # local variables used by that opcode. In this way, the total amount 26 # of stack space required by sqlite3VdbeExec() is reduced from the 27 # sum of all local variables to the maximum of the local variable space 28 # required for any single opcode. 29 # 30 # In order to be recognized by this script, local variables must appear 31 # on the first line after the open curly-brace that begins a new opcode 32 # implementation. Local variables must not have initializers, though they 33 # may be commented. 34 # 35 # The union definition is inserted in place of a special marker comment 36 # in the preamble to the sqlite3VdbeExec() implementation. 37 # 38 ############################################################################# 39 # 40 set beforeUnion {} ;# C code before union 41 set unionDef {} ;# C code of the union 42 set afterUnion {} ;# C code after the union 43 set sCtr 0 ;# Context counter 44 45 # Read program text up to the spot where the union should be 46 # inserted. 47 # 48 while {![eof stdin]} { 49 set line [gets stdin] 50 if {[regexp {INSERT STACK UNION HERE} $line]} break 51 append beforeUnion $line\n 52 } 53 54 # Process the remaining text. Build up the union definition as we go. 55 # 56 set vlist {} 57 set seenDecl 0 58 set namechars {abcdefghijklmnopqrstuvwxyz} 59 set nnc [string length $namechars] 60 while {![eof stdin]} { 61 set line [gets stdin] 62 if {[regexp "^case (OP_\\w+): \173" $line all operator]} { 63 append afterUnion $line\n 64 set vlist {} 65 while {![eof stdin]} { 66 set line [gets stdin] 67 if {[regexp {^ +(const )?\w+ \**(\w+)(\[.*\])?;} $line \ 68 all constKeyword vname notused1]} { 69 if {!$seenDecl} { 70 set sname {} 71 append sname [string index $namechars [expr {$sCtr/$nnc}]] 72 append sname [string index $namechars [expr {$sCtr%$nnc}]] 73 incr sCtr 74 append unionDef " struct ${operator}_stack_vars \173\n" 75 append afterUnion \ 76 "#if 0 /* local variables moved into u.$sname */\n" 77 set seenDecl 1 78 } 79 append unionDef " $line\n" 80 append afterUnion $line\n 81 lappend vlist $vname 82 } else { 83 break 84 } 85 } 86 if {$seenDecl} { 87 append unionDef " \175 $sname;\n" 88 append afterUnion "#endif /* local variables moved into u.$sname */\n" 89 } 90 set seenDecl 0 91 } 92 if {[regexp "^\175" $line]} { 93 append afterUnion $line\n 94 set vlist {} 95 } elseif {[llength $vlist]>0} { 96 append line " " 97 foreach v $vlist { 98 regsub -all "(\[^a-zA-Z0-9>.\])${v}(\\W)" $line "\\1u.$sname.$v\\2" line 99 regsub -all "(\[^a-zA-Z0-9>.\])${v}(\\W)" $line "\\1u.$sname.$v\\2" line 100 } 101 append afterUnion [string trimright $line]\n 102 } elseif {$line=="" && [eof stdin]} { 103 # no-op 104 } else { 105 append afterUnion $line\n 106 } 107 } 108 109 # Output the resulting text. 110 # 111 puts -nonewline $beforeUnion 112 puts " /********************************************************************" 113 puts " ** Automatically generated code" 114 puts " **" 115 puts " ** The following union is automatically generated by the" 116 puts " ** vdbe-compress.tcl script. The purpose of this union is to" 117 puts " ** reduce the amount of stack space required by this function." 118 puts " ** See comments in the vdbe-compress.tcl script for details." 119 puts " */" 120 puts " union vdbeExecUnion \173" 121 puts -nonewline $unionDef 122 puts " \175 u;" 123 puts " /* End automatically generated code" 124 puts " ********************************************************************/" 125 puts -nonewline $afterUnion 126