• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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#
40set beforeUnion {}   ;# C code before union
41set unionDef {}      ;# C code of the union
42set afterUnion {}    ;# C code after the union
43set sCtr 0           ;# Context counter
44
45# Read program text up to the spot where the union should be
46# inserted.
47#
48while {![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#
56set vlist {}
57set seenDecl 0
58set namechars {abcdefghijklmnopqrstuvwxyz}
59set nnc [string length $namechars]
60while {![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#
111puts -nonewline $beforeUnion
112puts "  /********************************************************************"
113puts "  ** Automatically generated code"
114puts "  **"
115puts "  ** The following union is automatically generated by the"
116puts "  ** vdbe-compress.tcl script.  The purpose of this union is to"
117puts "  ** reduce the amount of stack space required by this function."
118puts "  ** See comments in the vdbe-compress.tcl script for details."
119puts "  */"
120puts "  union vdbeExecUnion \173"
121puts -nonewline $unionDef
122puts "  \175 u;"
123puts "  /* End automatically generated code"
124puts "  ********************************************************************/"
125puts -nonewline $afterUnion
126