Difference between revisions of "User:Pedro Oval/Mono code memory usage/CIL"

From Second Life Wiki
Jump to navigation Jump to search
(Created page. More additions coming.)
 
(All at once)
Line 1: Line 1:
Here's the CIL code generated by certain code snippets, which gives some insight of what's happening under the hood. Conventions: x and y are local integer variables; f and g are local floats; v is a local vector; a is a local list.
Here's the CIL code generated by the script below, which gives some insight of what's happening under the hood.


{| {{Prettytable}}
Compilation was done using the viewer's built-in compiler as suggested by [[User:Becky Pippen/LSL Performance]]. Assembly was done using <code>ilasm</code> from the Mono suite.
|-
 
| LSL || width=600|<code>return;</code>
Script that gets compiled:
|-
 
| CIL || <pre>
<lsl>
2A                            ret
integer i;
u(){}
 
default
{
    state_entry()
    {
        integer x;
        integer y = 0;
        integer z;
        float f;
        float g;
        vector v;
        list a;
 
        ;;;;;;;;;{{{{{{{{}}}}}}}}
        return;
        x;
        (x);
        (integer)x;
        (float)x;
        f;
        (float)f;
        (integer)f;
        v;
        v.z;
        -x;
        ~x;
        !x;
        --x;
        ++x;
        x--;
        x++;
        x=y;
        x==y;
        x=y=z;
        f=x;
        f=(float)x;
        x!=y;
        x+y;
        x-y;
        x+-y;
        x*y;
        x/y;
        x%y;
        x&y;
        x&&y;
        x|y;
        x||y;
        x^y;
        x<<y;
        x>>y;
        x<y;
        x>y;
        x<=y;
        x>=y;
        x+=y;
        x-=y;
        x+=-y;
        x*=y;
        x/=y;
        x%=y;
        if (x) ;
        if (x) ; else ;
        0;
        x^x;
        1;
        -1;
        0xffffffff;
        ALL_SIDES;
        x|~x;
        x+1;
        -~x;
        x-1;
        x+-1;
        ~-x;
        x*y+y-1;
        (x+1)*y-1;
        ~(~x*y)
        while (x) ;
        do ; while (x);
        for (;x;) ;
        @label; if (x) jump label;
        0.0;
        f=0.0;
        f=0;
        <0.0, 0.0, 0.0>;
        ZERO_VECTOR;
        <0, 0, 0>;
        <-1.0, -1.0, 0.0>;
        TOUCH_INVALID_TEXCOORD;
        <-1, -1, 0>;
        <0xffffffff, 0xffffffff, 0>;
        v+v;
        v-v;
        v*v;
        v%v;
        [];
        a=[];
        a+[x];
        a+x;
        [x]+a;
        x+a;
        [x];
        []+x;
        (list)x;
        [x,y];
        []+x+y;
        (string)a;
        i;
        u();
    }
}
</lsl>
 
Compiled and annotated result:
 
<pre>
.assembly extern mscorlib {.ver 1:0:5000:0}
.assembly extern LslLibrary {.ver 0:1:0:0}
.assembly extern LslUserScript {.ver 0:1:0:0}
.assembly extern ScriptTypes {.ver 0:1:0:0}
.assembly 'LSL_y' {.ver 0:0:0:0}
.class public auto ansi serializable beforefieldinit LSL_y extends [LslUserScript]LindenLab.SecondLife.LslUserScript
{
  .field public int32 'i'
  .method public hidebysig  specialname  rtspecialname instance default void .ctor ()  cil managed
  {
    .maxstack 500
    // Globals:
    // integer i;
    ldarg.0
    ldc.i4.0
    stfld int32 LSL_y::'i'
 
    ldarg.0
    call instance void [LslUserScript]LindenLab.SecondLife.LslUserScript::.ctor()
    ret
  }
  .method public hidebysig instance default void 'gu'() cil managed
  {
    .maxstack 500
    ret
  }
 
 
  .method public hidebysig instance default void edefaultstate_entry() cil managed
  {
    .maxstack 500
    .locals init (int32, int32, int32, float32, float32, class [ScriptTypes]LindenLab.SecondLife.Vector, class [mscorlib]System.Collections.ArrayList)
    // integer x;
    ldc.i4.0
    stloc.s 0
    // integer y;
    ldc.i4 0
    stloc.s 1
    // integer z;
    ldc.i4.0
    stloc.s 2
    // float f;
    ldc.r8 0
    stloc.s 3
    // float g;
    ldc.r8 0
    stloc.s 4
    // vector v;
    ldc.r8 0
    ldc.r8 0
    ldc.r8 0
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
    stloc.s 5
    // list a;
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
    stloc.s 6
 
    // ;;; {{{ }}} generate no code
 
    // return;
    ret
 
    // x;
    ldloc.s 0
    pop
 
    // (x);
    ldloc.s 0
    pop
 
    // (integer)x;
    ldloc.s 0
    pop
 
    // (float)x;
    ldloc.s 0
    conv.r8
    pop
 
    // f;
    ldloc.s 3
    pop
 
    // (float)f;
    ldloc.s 3
    pop
 
    // (integer)f;
    ldloc.s 3
    call int32 [LslLibrary]LindenLab.SecondLife.LslRunTime::ToInteger(float32)
    pop
 
    // v;
    ldloc.s 5
    pop
 
    // v.z;
    ldloca.s 5
    ldfld float32 class [ScriptTypes]LindenLab.SecondLife.Vector::z
    pop
 
    // -x;
    ldloc.s 0
    neg
    pop
 
    // ~x;
    ldloc.s 0
    not
    pop
 
    // !x;
    ldloc.s 0
    ldc.i4.0
    ceq
    pop
 
    // --x;
    ldloc.s 0
    ldc.i4.1
    sub
    dup
    stloc.s 0
    pop
 
    // ++x;
    ldloc.s 0
    ldc.i4.1
    add
    dup
    stloc.s 0
    pop
 
    // x--;
    ldloc.s 0
    ldloc.s 0
    ldc.i4.1
    sub
    dup
    stloc.s 0
    pop
    pop
 
    // x++;
    ldloc.s 0
    ldloc.s 0
    ldc.i4.1
    add
    dup
    stloc.s 0
    pop
    pop
 
    // x = y;
    ldloc.s 1
    dup
    stloc.s 0
    pop
 
    // x == y;
    ldloc.s 1
    ldloc.s 0
    ceq
    pop
 
    // x = y = z;
    ldloc.s 2
    dup
    stloc.s 1
    dup
    stloc.s 0
    pop
 
    // f = x;
    ldloc.s 0
    conv.r8
    dup
    stloc.s 3
    pop
 
    // f = (float)x;
    ldloc.s 0
    conv.r8
    dup
    stloc.s 3
    pop
 
    // x != y; implemented as: !(x==y)
    ldloc.s 1  // this part is x == y
    ldloc.s 0
    ceq
    ldc.i4.0  // this part is 'not'
    ceq
    pop
 
    // x + y;
    ldloc.s 1
    ldloc.s 0
    add
    pop
 
    // x - y;
    ldloc.s 1
    ldloc.s 0
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Subtract(int32, int32)
    pop
 
    // x + -y;
    ldloc.s 1
    neg
    ldloc.s 0
    add
    pop
 
    // x * y;
    ldloc.s 1
    ldloc.s 0
    mul
    pop
 
    // x / y;
    ldloc.s 1
    ldloc.s 0
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Divide(int32, int32)
    pop
 
    // x % y;
    ldloc.s 1
    ldloc.s 0
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Modulo(int32, int32)
    pop
 
    // x & y;
    ldloc.s 1
    ldloc.s 0
    and
    pop
 
    // x && y; implemented as: !(!x | !y)
    ldloc.s 1    // !x
    ldc.i4.0
    ceq
    ldloc.s 0    // !y
    ldc.i4.0
    ceq
    or          // !x | !y
    ldc.i4.0    // !(!x | !y)
    ceq
    pop
 
    // x | y;
    ldloc.s 1
    ldloc.s 0
    or
    pop
 
    // x || y; implemented as: !!(x | y)
    ldloc.s 1    // x | y
    ldloc.s 0
    or
    ldc.i4.0    // !(x | y)
    ceq
    ldc.i4.0    // !!(x | y)
    ceq
    pop
 
    // x ^ y;
    ldloc.s 1
    ldloc.s 0
    xor
    pop
 
    // x << y;
    ldloc.s 1
    ldloc.s 0
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::ShiftLeft(int32, int32)
    pop
 
    // x >> y;
    ldloc.s 1
    ldloc.s 0
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::ShiftRight(int32, int32)
    pop
 
    // x < y; implemented as: y > x
    ldloc.s 1
    ldloc.s 0
    cgt
    pop
 
    // x > y; implemented as: y < x;
    ldloc.s 1
    ldloc.s 0
    clt
    pop
 
    // x <= y; implemented as: !(y < x)
    ldloc.s 1
    ldloc.s 0
    clt
    ldc.i4.0
    ceq
    pop
 
    // x >= y; implemented as: !(y > x)
    ldloc.s 1
    ldloc.s 0
    cgt
    ldc.i4.0
    ceq
    pop
 
    // x += y;
    ldloc.s 1
    ldloc.s 0
    add
    dup
    stloc.s 0
    pop
 
    // x -= y;
    ldloc.s 1
    ldloc.s 0
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Subtract(int32, int32)
    dup
    stloc.s 0
    pop
 
    // x += -y;
    ldloc.s 1
    neg
    ldloc.s 0
    add
    dup
    stloc.s 0
    pop
 
    // x *= y;
    ldloc.s 1
    ldloc.s 0
    mul
    dup
    stloc.s 0
    pop
 
    // x /= y;
    ldloc.s 1
    ldloc.s 0
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Divide(int32, int32)
    dup
    stloc.s 0
    pop
 
    // x %= y;
    ldloc.s 1
    ldloc.s 0
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Modulo(int32, int32)
    dup
    stloc.s 0
    pop
 
    // if (x) ;
    ldloc.s 0
    brfalse LabelTempJump0
    // THEN branch code would go here
LabelTempJump0:
 
    // if (x) ; else ;
    ldloc.s 0
    brfalse LabelTempJump1
    // THEN branch code would go here
    br LabelTempJump2
LabelTempJump1:
    // ELSE branch code would go here
LabelTempJump2:
 
    // 0;
    ldc.i4 0
    pop
 
    // x ^ x;
    ldloc.s 0
    ldloc.s 0
    xor
    pop
 
    // 1;
    ldc.i4 1
    pop
 
    // -1; note the negative sign takes code
    ldc.i4 1
    neg
    pop
 
    // 0xffffffff; note it equals -1 without taking memory
    ldc.i4 -1
    pop
 
    // ALL_SIDES; ditto
    ldc.i4 -1
    pop
 
    // x | ~x;
    ldloc.s 0
    not
    ldloc.s 0
    or
    pop
 
    // x + 1;
    ldc.i4 1
    ldloc.s 0
    add
    pop
 
    // -~x;
    ldloc.s 0
    not
    neg
    pop
 
    // x - 1;
    ldc.i4 1
    ldloc.s 0
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Subtract(int32, int32)
    pop
 
    // x + -1;
    ldc.i4 1
    neg
    ldloc.s 0
    add
    pop
 
    // ~-x;
    ldloc.s 0
    neg
    not
    pop
 
    // x*y + y - 1;
    ldc.i4 1
    ldloc.s 1
    ldloc.s 1
    ldloc.s 0
    mul
    add
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Subtract(int32, int32)
    pop
 
    // (x + 1)*y - 1;
    ldc.i4 1
    ldloc.s 1
    ldc.i4 1
    ldloc.s 0
    add
    mul
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Subtract(int32, int32)
    pop
 
    // ~(~x*y);
    ldloc.s 1
    ldloc.s 0
    not
    mul
    not
    pop
 
    // while (x) ;
LabelTempJump3:
    ldloc.s 0
    brfalse LabelTempJump4
    br LabelTempJump3
LabelTempJump4:
 
    // do ; while (x);
LabelTempJump5:
    ldloc.s 0
    brtrue LabelTempJump5
 
    // for (; x; ) ;
LabelTempJump6:
    ldloc.s 0
    brfalse LabelTempJump7
    br LabelTempJump6
LabelTempJump7:
 
    // @label; if (x) jump label;
'label':
    ldloc.s 0
    brfalse LabelTempJump8
    br 'label'
LabelTempJump8:
 
    // 0.0;
    ldc.r8 (00 00 00 00 00 00 00 00)
    pop
 
    // f = 0.0;
    ldc.r8 (00 00 00 00 00 00 00 00)
    dup
    stloc.s 3
    pop
 
    // f = 0;
    ldc.i4 0
    conv.r8
    dup
    stloc.s 3
    pop
 
    // <0.0, 0.0, 0.0>;
    ldc.r8 (00 00 00 00 00 00 00 00)
    ldc.r8 (00 00 00 00 00 00 00 00)
    ldc.r8 (00 00 00 00 00 00 00 00)
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
    pop
 
    // ZERO_VECTOR;
    ldc.r8 (00 00 00 00 00 00 00 00)
    ldc.r8 (00 00 00 00 00 00 00 00)
    ldc.r8 (00 00 00 00 00 00 00 00)
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
    pop
 
    // <0, 0, 0>;
    ldc.i4 0
    conv.r8
    ldc.i4 0
    conv.r8
    ldc.i4 0
    conv.r8
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
    pop
 
    // <-1.0, -1.0, 0.0>;
    ldc.r8 (00 00 00 00 00 00 f0 3f)
    neg
    ldc.r8 (00 00 00 00 00 00 f0 3f)
    neg
    ldc.r8 (00 00 00 00 00 00 00 00)
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
    pop
 
    // TOUCH_INVALID_TEXCOORD;
    ldc.r8 (00 00 00 00 00 00 f0 bf)
    ldc.r8 (00 00 00 00 00 00 f0 bf)
    ldc.r8 (00 00 00 00 00 00 00 00)
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
    pop
 
    // <-1, -1, 0>;
    ldc.i4 1
    neg
    conv.r8
    ldc.i4 1
    neg
    conv.r8
    ldc.i4 0
    conv.r8
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
    pop
 
    // <0xffffffff, 0xffffffff, 0>;
    ldc.i4 -1
    conv.r8
    ldc.i4 -1
    conv.r8
    ldc.i4 0
    conv.r8
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
    pop
 
    // v + v;
    ldloc.s 5
    ldloc.s 5
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Add'(class [ScriptTypes]LindenLab.SecondLife.Vector, class [ScriptTypes]LindenLab.SecondLife.Vector)
    pop
 
    // v - v;
    ldloc.s 5
    ldloc.s 5
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Subtract'(class [ScriptTypes]LindenLab.SecondLife.Vector, class [ScriptTypes]LindenLab.SecondLife.Vector)
    pop
 
    // v * v;
    ldloc.s 5
    ldloc.s 5
    call float32 class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Multiply'(class [ScriptTypes]LindenLab.SecondLife.Vector, class [ScriptTypes]LindenLab.SecondLife.Vector)
    pop
 
    // v % v;
    ldloc.s 5
    ldloc.s 5
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Modulo'(class [ScriptTypes]LindenLab.SecondLife.Vector, class [ScriptTypes]LindenLab.SecondLife.Vector)
    pop
 
    // [];
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
    pop
 
    // a = [];
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
    dup
    stloc.s 6
    pop
 
    // a + [x];
    ldloc.s 0
    box [mscorlib]System.Int32
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(object, class [mscorlib]System.Collections.ArrayList)
    ldloc.s 6
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(class [mscorlib]System.Collections.ArrayList, class [mscorlib]System.Collections.ArrayList)
    pop
 
    // a + x;
    ldloc.s 0
    ldloc.s 6
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(int32, class [mscorlib]System.Collections.ArrayList)
    pop
 
    // [x] + a;
    ldloc.s 6
    ldloc.s 0
    box [mscorlib]System.Int32
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(object, class [mscorlib]System.Collections.ArrayList)
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(class [mscorlib]System.Collections.ArrayList, class [mscorlib]System.Collections.ArrayList)
    pop
 
    // x + a;
    ldloc.s 6
    ldloc.s 0
    box [mscorlib]System.Int32
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(class [mscorlib]System.Collections.ArrayList, object)
    pop
 
    // [x];
    ldloc.s 0
    box [mscorlib]System.Int32
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(object, class [mscorlib]System.Collections.ArrayList)
    pop
 
    // []+x;
    ldloc.s 0
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(int32, class [mscorlib]System.Collections.ArrayList)
    pop
 
    // (list)x;
    ldloc.s 0
    box [mscorlib]System.Int32
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList(object)
    pop
 
    // [x, y];
    ldloc.s 0
    box [mscorlib]System.Int32
    ldloc.s 1
    box [mscorlib]System.Int32
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(object, class [mscorlib]System.Collections.ArrayList)
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(object, class [mscorlib]System.Collections.ArrayList)
    pop
 
    // []+x+y;
    ldloc.s 1
    ldloc.s 0
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(int32, class [mscorlib]System.Collections.ArrayList)
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(int32, class [mscorlib]System.Collections.ArrayList)
    pop
 
    // (string)a;
    ldloc.s 6
    call string [LslLibrary]LindenLab.SecondLife.LslRunTime::ListToString(class [mscorlib]System.Collections.ArrayList)
    pop
 
    // i; (global).
    ldarg.0
    ldfld int32 LSL_y::'i'
    pop
 
    // u();
    ldarg.0
    call instance void class LSL_y::'gu'()
 
    // end of event
    ret
  }
 
}
</pre>
</pre>
|}


{| {{Prettytable}}
'''Important notes:'''
|-
| LSL || width=600|<code>x;</code> or <code>(x)</code> or <code>(integer)x</code>
|-
| CIL || <pre>
11 00                        ldloc.s 0
26                            pop
</pre>
|-
| colspan=2 width=600 | Note: ldloc.s 0 is probably contracted to ldloc.0 (opcode 06) at assembly time, resulting in a length of 2. Or possibly the server-side compiler added an optimization of this (!). This is confirmed by the fact that <code>x;</code> takes 2 bytes if it's one of the first four variables (there are 1-byte opcodes for ldloc.0 through ldloc.3), and 3 bytes otherwise. This caveat applies to most appearances of this opcode.
|}


{| {{Prettytable}}
* <code>ldloc.s 0</code> (opcode 11, argument 00) is probably contracted to the abbreviation <code>ldloc.0</code> (opcode 06) at assembly time, resulting in the length of 2 obtained in the [[User:Pedro Oval/Mono code memory usage|tests]]. Or possibly the server-side compiler added an optimization of this case (!). Either way, the evidence for this is confirmed by the fact that <code>x;</code> takes 2 bytes if it's one of the first four variables (there are 1-byte opcodes for ldloc.0 through ldloc.3), and 3 bytes otherwise. This applies to all appearances of this opcode and the similar <code>stloc.s</code>.
|-
* Local variable definitions seem to take a variable and big number of bytes (averaging about 47 bytes for local integers) if there is a function call anywhere in the event where they are defined.
| LSL || width=600|<code>(float)x;</code>
* As things are now, having more than 256 local variables causes wraparound, making the 257th be an alias to the 1st, and so on.
|-
* Backward jumps seem to take much more bytes than what the CIL result above suggests. Forward jumps, however, seem predictable enough.
| CIL || <pre>
* Global variable and function names do take code memory.
11 00                        ldloc.s 0
6C                            conv.r8
26                            pop
</pre>
|}

Revision as of 17:35, 30 May 2014

Here's the CIL code generated by the script below, which gives some insight of what's happening under the hood.

Compilation was done using the viewer's built-in compiler as suggested by User:Becky Pippen/LSL Performance. Assembly was done using ilasm from the Mono suite.

Script that gets compiled:

<lsl> integer i; u(){}

default {

   state_entry()
   {
       integer x;
       integer y = 0;
       integer z;
       float f;
       float g;
       vector v;
       list a;
       ;;;;;;;;;{{{{{{{{}}}}}}}}
       return;
       x;
       (x);
       (integer)x;
       (float)x;
       f;
       (float)f;
       (integer)f;
       v;
       v.z;
       -x;
       ~x;
       !x;
       --x;
       ++x;
       x--;
       x++;
       x=y;
       x==y;
       x=y=z;
       f=x;
       f=(float)x;
       x!=y;
       x+y;
       x-y;
       x+-y;
       x*y;
       x/y;
       x%y;
       x&y;
       x&&y;
       x|y;
       x||y;
       x^y;
       x<<y;
       x>>y;
       x<y;
       x>y;
       x<=y;
       x>=y;
       x+=y;
       x-=y;
       x+=-y;
       x*=y;
       x/=y;
       x%=y;
       if (x) ;
       if (x) ; else ;
       0;
       x^x;
       1;
       -1;
       0xffffffff;
       ALL_SIDES;
       x|~x;
       x+1;
       -~x;
       x-1;
       x+-1;
       ~-x;
       x*y+y-1;
       (x+1)*y-1;
       ~(~x*y)
       while (x) ;
       do ; while (x);
       for (;x;) ;
       @label; if (x) jump label;
       0.0;
       f=0.0;
       f=0;
       <0.0, 0.0, 0.0>;
       ZERO_VECTOR;
       <0, 0, 0>;
       <-1.0, -1.0, 0.0>;
       TOUCH_INVALID_TEXCOORD;
       <-1, -1, 0>;
       <0xffffffff, 0xffffffff, 0>;
       v+v;
       v-v;
       v*v;
       v%v;
       [];
       a=[];
       a+[x];
       a+x;
       [x]+a;
       x+a;
       [x];
       []+x;
       (list)x;
       [x,y];
       []+x+y;
       (string)a;
       i;
       u();
   }

} </lsl>

Compiled and annotated result:

.assembly extern mscorlib {.ver 1:0:5000:0}
.assembly extern LslLibrary {.ver 0:1:0:0}
.assembly extern LslUserScript {.ver 0:1:0:0}
.assembly extern ScriptTypes {.ver 0:1:0:0}
.assembly 'LSL_y' {.ver 0:0:0:0}
.class public auto ansi serializable beforefieldinit LSL_y extends [LslUserScript]LindenLab.SecondLife.LslUserScript
{
  .field public int32 'i'
  .method public hidebysig  specialname  rtspecialname instance default void .ctor ()  cil managed
  {
    .maxstack 500
    // Globals:
    // integer i;
    ldarg.0
    ldc.i4.0
    stfld int32 LSL_y::'i'

    ldarg.0
    call instance void [LslUserScript]LindenLab.SecondLife.LslUserScript::.ctor()
    ret
  }
  .method public hidebysig instance default void 'gu'() cil managed
  {
    .maxstack 500
    ret
  }


  .method public hidebysig instance default void edefaultstate_entry() cil managed
  {
    .maxstack 500
    .locals init (int32, int32, int32, float32, float32, class [ScriptTypes]LindenLab.SecondLife.Vector, class [mscorlib]System.Collections.ArrayList)
    // integer x;
    ldc.i4.0
    stloc.s 0
    // integer y;
    ldc.i4 0
    stloc.s 1
    // integer z;
    ldc.i4.0
    stloc.s 2
    // float f;
    ldc.r8 0
    stloc.s 3
    // float g;
    ldc.r8 0
    stloc.s 4
    // vector v;
    ldc.r8 0
    ldc.r8 0
    ldc.r8 0
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
    stloc.s 5
    // list a;
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
    stloc.s 6

    // ;;; {{{ }}} generate no code

    // return;
    ret

    // x;
    ldloc.s 0
    pop

    // (x);
    ldloc.s 0
    pop

    // (integer)x;
    ldloc.s 0
    pop

    // (float)x;
    ldloc.s 0
    conv.r8
    pop

    // f;
    ldloc.s 3
    pop

    // (float)f;
    ldloc.s 3
    pop

    // (integer)f;
    ldloc.s 3
    call int32 [LslLibrary]LindenLab.SecondLife.LslRunTime::ToInteger(float32)
    pop

    // v;
    ldloc.s 5
    pop

    // v.z;
    ldloca.s 5
    ldfld float32 class [ScriptTypes]LindenLab.SecondLife.Vector::z
    pop

    // -x;
    ldloc.s 0
    neg
    pop

    // ~x;
    ldloc.s 0
    not
    pop

    // !x;
    ldloc.s 0
    ldc.i4.0
    ceq
    pop

    // --x;
    ldloc.s 0
    ldc.i4.1
    sub
    dup
    stloc.s 0
    pop

    // ++x;
    ldloc.s 0
    ldc.i4.1
    add
    dup
    stloc.s 0
    pop

    // x--;
    ldloc.s 0
    ldloc.s 0
    ldc.i4.1
    sub
    dup
    stloc.s 0
    pop
    pop

    // x++;
    ldloc.s 0
    ldloc.s 0
    ldc.i4.1
    add
    dup
    stloc.s 0
    pop
    pop

    // x = y;
    ldloc.s 1
    dup
    stloc.s 0
    pop

    // x == y;
    ldloc.s 1
    ldloc.s 0
    ceq
    pop

    // x = y = z;
    ldloc.s 2
    dup
    stloc.s 1
    dup
    stloc.s 0
    pop

    // f = x;
    ldloc.s 0
    conv.r8
    dup
    stloc.s 3
    pop

    // f = (float)x;
    ldloc.s 0
    conv.r8
    dup
    stloc.s 3
    pop

    // x != y; implemented as: !(x==y)
    ldloc.s 1  // this part is x == y
    ldloc.s 0
    ceq
    ldc.i4.0   // this part is 'not'
    ceq
    pop

    // x + y;
    ldloc.s 1
    ldloc.s 0
    add
    pop

    // x - y;
    ldloc.s 1
    ldloc.s 0
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Subtract(int32, int32)
    pop

    // x + -y;
    ldloc.s 1
    neg
    ldloc.s 0
    add
    pop

    // x * y;
    ldloc.s 1
    ldloc.s 0
    mul
    pop

    // x / y;
    ldloc.s 1
    ldloc.s 0
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Divide(int32, int32)
    pop

    // x % y;
    ldloc.s 1
    ldloc.s 0
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Modulo(int32, int32)
    pop

    // x & y;
    ldloc.s 1
    ldloc.s 0
    and
    pop

    // x && y; implemented as: !(!x | !y)
    ldloc.s 1    // !x
    ldc.i4.0
    ceq
    ldloc.s 0    // !y
    ldc.i4.0
    ceq
    or           // !x | !y
    ldc.i4.0     // !(!x | !y)
    ceq
    pop

    // x | y;
    ldloc.s 1
    ldloc.s 0
    or
    pop

    // x || y; implemented as: !!(x | y)
    ldloc.s 1    // x | y
    ldloc.s 0
    or
    ldc.i4.0     // !(x | y)
    ceq
    ldc.i4.0     // !!(x | y)
    ceq
    pop

    // x ^ y;
    ldloc.s 1
    ldloc.s 0
    xor
    pop

    // x << y;
    ldloc.s 1
    ldloc.s 0
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::ShiftLeft(int32, int32)
    pop

    // x >> y;
    ldloc.s 1
    ldloc.s 0
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::ShiftRight(int32, int32)
    pop

    // x < y; implemented as: y > x
    ldloc.s 1
    ldloc.s 0
    cgt
    pop

    // x > y; implemented as: y < x;
    ldloc.s 1
    ldloc.s 0
    clt
    pop

    // x <= y; implemented as: !(y < x)
    ldloc.s 1
    ldloc.s 0
    clt
    ldc.i4.0
    ceq
    pop

    // x >= y; implemented as: !(y > x)
    ldloc.s 1
    ldloc.s 0
    cgt
    ldc.i4.0
    ceq
    pop

    // x += y;
    ldloc.s 1
    ldloc.s 0
    add
    dup
    stloc.s 0
    pop

    // x -= y;
    ldloc.s 1
    ldloc.s 0
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Subtract(int32, int32)
    dup
    stloc.s 0
    pop

    // x += -y;
    ldloc.s 1
    neg
    ldloc.s 0
    add
    dup
    stloc.s 0
    pop

    // x *= y;
    ldloc.s 1
    ldloc.s 0
    mul
    dup
    stloc.s 0
    pop

    // x /= y;
    ldloc.s 1
    ldloc.s 0
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Divide(int32, int32)
    dup
    stloc.s 0
    pop

    // x %= y;
    ldloc.s 1
    ldloc.s 0
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Modulo(int32, int32)
    dup
    stloc.s 0
    pop

    // if (x) ;
    ldloc.s 0
    brfalse LabelTempJump0
    // THEN branch code would go here
LabelTempJump0:

    // if (x) ; else ;
    ldloc.s 0
    brfalse LabelTempJump1
    // THEN branch code would go here
    br LabelTempJump2
LabelTempJump1:
    // ELSE branch code would go here
LabelTempJump2:

    // 0;
    ldc.i4 0
    pop

    // x ^ x;
    ldloc.s 0
    ldloc.s 0
    xor
    pop

    // 1;
    ldc.i4 1
    pop

    // -1; note the negative sign takes code
    ldc.i4 1
    neg
    pop

    // 0xffffffff; note it equals -1 without taking memory
    ldc.i4 -1
    pop

    // ALL_SIDES; ditto
    ldc.i4 -1
    pop

    // x | ~x;
    ldloc.s 0
    not
    ldloc.s 0
    or
    pop

    // x + 1;
    ldc.i4 1
    ldloc.s 0
    add
    pop

    // -~x;
    ldloc.s 0
    not
    neg
    pop

    // x - 1;
    ldc.i4 1
    ldloc.s 0
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Subtract(int32, int32)
    pop

    // x + -1;
    ldc.i4 1
    neg
    ldloc.s 0
    add
    pop

    // ~-x;
    ldloc.s 0
    neg
    not
    pop

    // x*y + y - 1;
    ldc.i4 1
    ldloc.s 1
    ldloc.s 1
    ldloc.s 0
    mul
    add
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Subtract(int32, int32)
    pop

    // (x + 1)*y - 1;
    ldc.i4 1
    ldloc.s 1
    ldc.i4 1
    ldloc.s 0
    add
    mul
    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Subtract(int32, int32)
    pop

    // ~(~x*y);
    ldloc.s 1
    ldloc.s 0
    not
    mul
    not
    pop

    // while (x) ;
LabelTempJump3:
    ldloc.s 0
    brfalse LabelTempJump4
    br LabelTempJump3
LabelTempJump4:

    // do ; while (x);
LabelTempJump5:
    ldloc.s 0
    brtrue LabelTempJump5

    // for (; x; ) ;
LabelTempJump6:
    ldloc.s 0
    brfalse LabelTempJump7
    br LabelTempJump6
LabelTempJump7:

    // @label; if (x) jump label;
'label':
    ldloc.s 0
    brfalse LabelTempJump8
    br 'label'
LabelTempJump8:

    // 0.0;
    ldc.r8 (00 00 00 00 00 00 00 00)
    pop

    // f = 0.0;
    ldc.r8 (00 00 00 00 00 00 00 00)
    dup
    stloc.s 3
    pop

    // f = 0;
    ldc.i4 0
    conv.r8
    dup
    stloc.s 3
    pop

    // <0.0, 0.0, 0.0>;
    ldc.r8 (00 00 00 00 00 00 00 00)
    ldc.r8 (00 00 00 00 00 00 00 00)
    ldc.r8 (00 00 00 00 00 00 00 00)
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
    pop

    // ZERO_VECTOR;
    ldc.r8 (00 00 00 00 00 00 00 00)
    ldc.r8 (00 00 00 00 00 00 00 00)
    ldc.r8 (00 00 00 00 00 00 00 00)
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
    pop

    // <0, 0, 0>;
    ldc.i4 0
    conv.r8
    ldc.i4 0
    conv.r8
    ldc.i4 0
    conv.r8
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
    pop

    // <-1.0, -1.0, 0.0>;
    ldc.r8 (00 00 00 00 00 00 f0 3f)
    neg
    ldc.r8 (00 00 00 00 00 00 f0 3f)
    neg
    ldc.r8 (00 00 00 00 00 00 00 00)
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
    pop

    // TOUCH_INVALID_TEXCOORD;
    ldc.r8 (00 00 00 00 00 00 f0 bf)
    ldc.r8 (00 00 00 00 00 00 f0 bf)
    ldc.r8 (00 00 00 00 00 00 00 00)
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
    pop

    // <-1, -1, 0>;
    ldc.i4 1
    neg
    conv.r8
    ldc.i4 1
    neg
    conv.r8
    ldc.i4 0
    conv.r8
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
    pop

    // <0xffffffff, 0xffffffff, 0>;
    ldc.i4 -1
    conv.r8
    ldc.i4 -1
    conv.r8
    ldc.i4 0
    conv.r8
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
    pop

    // v + v;
    ldloc.s 5
    ldloc.s 5
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Add'(class [ScriptTypes]LindenLab.SecondLife.Vector, class [ScriptTypes]LindenLab.SecondLife.Vector)
    pop

    // v - v;
    ldloc.s 5
    ldloc.s 5
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Subtract'(class [ScriptTypes]LindenLab.SecondLife.Vector, class [ScriptTypes]LindenLab.SecondLife.Vector)
    pop

    // v * v;
    ldloc.s 5
    ldloc.s 5
    call float32 class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Multiply'(class [ScriptTypes]LindenLab.SecondLife.Vector, class [ScriptTypes]LindenLab.SecondLife.Vector)
    pop

    // v % v;
    ldloc.s 5
    ldloc.s 5
    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Modulo'(class [ScriptTypes]LindenLab.SecondLife.Vector, class [ScriptTypes]LindenLab.SecondLife.Vector)
    pop

    // [];
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
    pop

    // a = [];
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
    dup
    stloc.s 6
    pop

    // a + [x];
    ldloc.s 0
    box [mscorlib]System.Int32
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(object, class [mscorlib]System.Collections.ArrayList)
    ldloc.s 6
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(class [mscorlib]System.Collections.ArrayList, class [mscorlib]System.Collections.ArrayList)
    pop

    // a + x;
    ldloc.s 0
    ldloc.s 6
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(int32, class [mscorlib]System.Collections.ArrayList)
    pop

    // [x] + a;
    ldloc.s 6
    ldloc.s 0
    box [mscorlib]System.Int32
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(object, class [mscorlib]System.Collections.ArrayList)
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(class [mscorlib]System.Collections.ArrayList, class [mscorlib]System.Collections.ArrayList)
    pop

    // x + a;
    ldloc.s 6
    ldloc.s 0
    box [mscorlib]System.Int32
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(class [mscorlib]System.Collections.ArrayList, object)
    pop

    // [x];
    ldloc.s 0
    box [mscorlib]System.Int32
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(object, class [mscorlib]System.Collections.ArrayList)
    pop

    // []+x;
    ldloc.s 0
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(int32, class [mscorlib]System.Collections.ArrayList)
    pop

    // (list)x;
    ldloc.s 0
    box [mscorlib]System.Int32
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList(object)
    pop

    // [x, y];
    ldloc.s 0
    box [mscorlib]System.Int32
    ldloc.s 1
    box [mscorlib]System.Int32
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(object, class [mscorlib]System.Collections.ArrayList)
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(object, class [mscorlib]System.Collections.ArrayList)
    pop

    // []+x+y;
    ldloc.s 1
    ldloc.s 0
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(int32, class [mscorlib]System.Collections.ArrayList)
    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(int32, class [mscorlib]System.Collections.ArrayList)
    pop

    // (string)a;
    ldloc.s 6
    call string [LslLibrary]LindenLab.SecondLife.LslRunTime::ListToString(class [mscorlib]System.Collections.ArrayList)
    pop

    // i; (global).
    ldarg.0
    ldfld int32 LSL_y::'i'
    pop

    // u();
    ldarg.0
    call instance void class LSL_y::'gu'()

    // end of event
    ret
  }

}

Important notes:

  • ldloc.s 0 (opcode 11, argument 00) is probably contracted to the abbreviation ldloc.0 (opcode 06) at assembly time, resulting in the length of 2 obtained in the tests. Or possibly the server-side compiler added an optimization of this case (!). Either way, the evidence for this is confirmed by the fact that x; takes 2 bytes if it's one of the first four variables (there are 1-byte opcodes for ldloc.0 through ldloc.3), and 3 bytes otherwise. This applies to all appearances of this opcode and the similar stloc.s.
  • Local variable definitions seem to take a variable and big number of bytes (averaging about 47 bytes for local integers) if there is a function call anywhere in the event where they are defined.
  • As things are now, having more than 256 local variables causes wraparound, making the 257th be an alias to the 1st, and so on.
  • Backward jumps seem to take much more bytes than what the CIL result above suggests. Forward jumps, however, seem predictable enough.
  • Global variable and function names do take code memory.