| OLD | NEW |
| (Empty) |
| 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 | |
| OLD | NEW |