Hi Vyacheslav,

Allow me to demonstrate what I mean.  I ran the v8 shell with code
containing the following function.

function loop() {
  for(var i = 0; i < 5; ++i) {
    print(i);
  }
}

It appears to be emitting the following code (optimized and unoptimized).

--- Code ---
kind = FUNCTION
name = loop
Instructions (size = 196)
0x7f6f3e26fca0     0  55             push rbp
0x7f6f3e26fca1     1  4889e5         REX.W movq rbp,rsp
0x7f6f3e26fca4     4  56             push rsi
0x7f6f3e26fca5     5  57             push rdi
0x7f6f3e26fca6     6  41ff7598       push [r13-0x68]
0x7f6f3e26fcaa    10  493b6508       REX.W cmpq rsp,[r13+0x8]
0x7f6f3e26fcae    14  7305           jnc 21  (0x7f6f3e26fcb5)
0x7f6f3e26fcb0    16  e82bf4fdff     call 0x7f6f3e24f0e0     ;; debug:
statement 36
                                                            ;; code: STUB,
StackCheckStub, minor: 0
0x7f6f3e26fcb5    21  33c0           xorl rax,rax
0x7f6f3e26fcb7    23  488945e8       REX.W movq [rbp-0x18],rax
0x7f6f3e26fcbb    27  e94d000000     jmp 109  (0x7f6f3e26fd0d)
0x7f6f3e26fcc0    32  ff7627         push [rsi+0x27]
0x7f6f3e26fcc3    35  ff75e8         push [rbp-0x18]
0x7f6f3e26fcc6    38  48b9919790636f7f0000 REX.W movq rcx,0x7f6f63909791
 ;; object: 0x7f6f63909791 <String[5]: print>
0x7f6f3e26fcd0    48  e80b98ffff     call 0x7f6f3e2694e0     ;; debug:
statement 76
                                                            ;; code:
contextual, CALL_IC, UNINITIALIZED, in_loop, argc = 1
0x7f6f3e26fcd5    53  488b75f8       REX.W movq rsi,[rbp-0x8]
0x7f6f3e26fcd9    57  488b45e8       REX.W movq rax,[rbp-0x18]
0x7f6f3e26fcdd    61  a801           test al,0x1
0x7f6f3e26fcdf    63  7405           jz 70  (0x7f6f3e26fce6)
0x7f6f3e26fce1    65  e89a83feff     call 0x7f6f3e258080     ;; debug:
statement 43
                                                            ;; debug:
position 67
                                                            ;; code: STUB,
ToNumberStub, minor: 0
0x7f6f3e26fce6    70  4c01e0         REX.W addq rax,r12
0x7f6f3e26fce9    73  7004           jo 79  (0x7f6f3e26fcef)
0x7f6f3e26fceb    75  a801           test al,0x1
0x7f6f3e26fced    77  720d           jc 92  (0x7f6f3e26fcfc)
0x7f6f3e26fcef    79  4c29e0         REX.W subq rax,r12
0x7f6f3e26fcf2    82  4c89e2         REX.W movq rdx,r12
0x7f6f3e26fcf5    85  e80658feff     call 0x7f6f3e255500     ;; code:
BINARY_OP_IC, UNINITIALIZED (id = 30)
0x7f6f3e26fcfa    90  a80d           test al,0xd
0x7f6f3e26fcfc    92  488945e8       REX.W movq [rbp-0x18],rax
0x7f6f3e26fd00    96  493b6508       REX.W cmpq rsp,[r13+0x8]
0x7f6f3e26fd04   100  7307           jnc 109  (0x7f6f3e26fd0d)
0x7f6f3e26fd06   102  e8d5f3fdff     call 0x7f6f3e24f0e0     ;; code: STUB,
StackCheckStub, minor: 0
0x7f6f3e26fd0b   107  a801           test al,0x1
0x7f6f3e26fd0d   109  ff75e8         push [rbp-0x18]
0x7f6f3e26fd10   112  4b8d04a4       REX.W leaq rax,[r12+r12*4]
0x7f6f3e26fd14   116  5a             pop rdx
0x7f6f3e26fd15   117  488bca         REX.W movq rcx,rdx
0x7f6f3e26fd18   120  480bc8         REX.W orq rcx,rax
0x7f6f3e26fd1b   123  f6c101         testb rcx,0x1
0x7f6f3e26fd1e   126  730a           jnc 138  (0x7f6f3e26fd2a)
0x7f6f3e26fd20   128  483bd0         REX.W cmpq rdx,rax
0x7f6f3e26fd23   131  7c9b           jl 32  (0x7f6f3e26fcc0)
0x7f6f3e26fd25   133  e91d000000     jmp 167  (0x7f6f3e26fd47)
0x7f6f3e26fd2a   138  e8313cfeff     call 0x7f6f3e253960     ;; debug:
position 60
                                                            ;; code:
COMPARE_IC, UNINITIALIZED (id = 23)
0x7f6f3e26fd2f   143  a811           test al,0x11
0x7f6f3e26fd31   145  eb0b           jmp 158  (0x7f6f3e26fd3e)
0x7f6f3e26fd33   147  493b45b0       REX.W cmpq rax,[r13-0x50]
0x7f6f3e26fd37   151  7487           jz 32  (0x7f6f3e26fcc0)
0x7f6f3e26fd39   153  e909000000     jmp 167  (0x7f6f3e26fd47)
0x7f6f3e26fd3e   158  4885c0         REX.W testq rax,rax
0x7f6f3e26fd41   161  0f8c79ffffff   jl 32  (0x7f6f3e26fcc0)
0x7f6f3e26fd47   167  498b4598       REX.W movq rax,[r13-0x68]
0x7f6f3e26fd4b   171  488be5         REX.W movq rsp,rbp      ;; debug:
statement 90
                                                            ;; js return
0x7f6f3e26fd4e   174  5d             pop rbp
0x7f6f3e26fd4f   175  c20800         ret 0x8
0x7f6f3e26fd52   178  cc             int3
0x7f6f3e26fd53   179  cc             int3
0x7f6f3e26fd54   180  cc             int3
0x7f6f3e26fd55   181  cc             int3
0x7f6f3e26fd56   182  cc             int3
0x7f6f3e26fd57   183  cc             int3

--- Optimized code ---
kind = OPTIMIZED_FUNCTION
name = loop
stack_slots = 2
Instructions (size = 234)
0x7f6f3e2703a0     0  55             push rbp
0x7f6f3e2703a1     1  4889e5         REX.W movq rbp,rsp
0x7f6f3e2703a4     4  56             push rsi
0x7f6f3e2703a5     5  57             push rdi
0x7f6f3e2703a6     6  4883ec10       REX.W subq rsp,0x10
0x7f6f3e2703aa    10  488bc6         REX.W movq rax,rsi
0x7f6f3e2703ad    13  493b6508       REX.W cmpq rsp,[r13+0x8]
0x7f6f3e2703b1    17  7305           jnc 24  (0x7f6f3e2703b8)
0x7f6f3e2703b3    19  e828edfdff     call 0x7f6f3e24f0e0     ;; code: STUB,
StackCheckStub, minor: 0
0x7f6f3e2703b8    24  488b4627       REX.W movq rax,[rsi+0x27]
0x7f6f3e2703bc    28  488b4027       REX.W movq rax,[rax+0x27]
0x7f6f3e2703c0    32  488945e8       REX.W movq [rbp-0x18],rax
0x7f6f3e2703c4    36  bb00000000     movl rbx,(nil)
0x7f6f3e2703c9    41  48895de0       REX.W movq [rbp-0x20],rbx
0x7f6f3e2703cd    45  83fb05         cmpl rbx,0x5
0x7f6f3e2703d0    48  0f8d5c000000   jge 146  (0x7f6f3e270432)
0x7f6f3e2703d6    54  48ba881d7f636f7f0000 REX.W movq rdx,0x7f6f637f1d88
 ;; global property cell
0x7f6f3e2703e0    64  488b12         REX.W movq rdx,[rdx]
0x7f6f3e2703e3    67  493b55a0       REX.W cmpq rdx,[r13-0x60]
0x7f6f3e2703e7    71  0f8456000000   jz 163  (0x7f6f3e270443)
0x7f6f3e2703ed    77  49ba719295636f7f0000 REX.W movq r10,0x7f6f63959271
 ;; object: 0x7f6f63959271 <JS Function print>
0x7f6f3e2703f7    87  493bd2         REX.W cmpq rdx,r10
0x7f6f3e2703fa    90  0f8550000000   jnz 176  (0x7f6f3e270450)
0x7f6f3e270400    96  50             push rax
0x7f6f3e270401    97  488bd3         REX.W movq rdx,rbx
0x7f6f3e270404   100  48c1e220       REX.W shlq rdx,32
0x7f6f3e270408   104  52             push rdx
0x7f6f3e270409   105  48bf719295636f7f0000 REX.W movq rdi,0x7f6f63959271
 ;; object: 0x7f6f63959271 <JS Function print>
0x7f6f3e270413   115  b801000000     movl rax,0x1
0x7f6f3e270418   120  4c89e1         REX.W movq rcx,r12
0x7f6f3e27041b   123  ff5717         call [rdi+0x17]         ;; debug:
position 76
0x7f6f3e27041e   126  488b75f8       REX.W movq rsi,[rbp-0x8]
0x7f6f3e270422   130  488b45e0       REX.W movq rax,[rbp-0x20]
0x7f6f3e270426   134  83c001         addl rax,0x1
0x7f6f3e270429   137  488bd8         REX.W movq rbx,rax
0x7f6f3e27042c   140  488b45e8       REX.W movq rax,[rbp-0x18]
0x7f6f3e270430   144  eb97           jmp 41  (0x7f6f3e2703c9)
0x7f6f3e270432   146  48b8b1208f636f7f0000 REX.W movq rax,0x7f6f638f20b1
 ;; object: 0x7f6f638f20b1 <undefined>
0x7f6f3e27043c   156  488be5         REX.W movq rsp,rbp
0x7f6f3e27043f   159  5d             pop rbp
0x7f6f3e270440   160  c20800         ret 0x8
0x7f6f3e270443   163  49ba4aa0283e6f7f0000 REX.W movq r10,0x7f6f3e28a04a
 ;; deoptimization bailout 1
0x7f6f3e27044d   173  41ffe2         jmp r10
0x7f6f3e270450   176  49ba54a0283e6f7f0000 REX.W movq r10,0x7f6f3e28a054
 ;; deoptimization bailout 2
0x7f6f3e27045a   186  41ffe2         jmp r10
0x7f6f3e27045d   189  90             nop
0x7f6f3e27045e   190  90             nop
0x7f6f3e27045f   191  90             nop
0x7f6f3e270460   192  90             nop
0x7f6f3e270461   193  90             nop
0x7f6f3e270462   194  90             nop
0x7f6f3e270463   195  90             nop
0x7f6f3e270464   196  90             nop
0x7f6f3e270465   197  90             nop
0x7f6f3e270466   198  90             nop
0x7f6f3e270467   199  90             nop
0x7f6f3e270468   200  90             nop
0x7f6f3e270469   201  90             nop
0x7f6f3e27046a   202  6690           nop

It appears that the unoptimized code is emitting two stack limit checks.
 One at offset 16 at the function entry (but prior to the loop starting at
offset 32), and another at offset 102, prior to the loop's backward jump.
 However, the optimized code is only emitting one stack check at offset 19,
when the loop doesn't appear to start until offset 41.  Correct me if I'm
wrong, but the optimized code only appears to be checking the stack limit at
the function entry, not in the loop itself.

- Kyle



On Wed, Aug 31, 2011 at 3:53 PM, Vyacheslav Egorov <[email protected]>
wrote:
> Hi Kyle,
>
> Optimizing compiler inserts stack checks (HStackCheck instruction)
> explicitly at loop body's entry[1].
>
> It also does an optimization pass[2] to remove redundant stack checks
> that are dominated by function calls (as functions always does stack
> check in the prologue).
>
> Stack checks are important part of V8's interruption mechanism so both
> compilers emit them to make all loops interruptable.
>
> [1] http://code.google.com/p/v8/source/browse/trunk/src/hydrogen.cc#2823
> [2] http://code.google.com/p/v8/source/browse/trunk/src/hydrogen.cc#1247
>
> --
> Vyacheslav Egorov
>
>
> On Wed, Aug 31, 2011 at 9:27 PM, Kyle <[email protected]> wrote:
>> Hello,
>>
>> Some time ago I noticed that the v8 compile was inserting stack limit
>> checks at the back edges of loops.  I later found out that this check
>> was doubling as a preemption mechanism to interrupt potentially long-
>> running code.  However, I've noticed that the hydrogen/lithium
>> compiler included with crankshaft does not seem to include these
>> checks.  Is there a particular reason for this?  Is the previous
>> design for JavaScript preemption no longer being pursued?
>>
>> --
>> v8-users mailing list
>> [email protected]
>> http://groups.google.com/group/v8-users
>>
>
> --
> v8-users mailing list
> [email protected]
> http://groups.google.com/group/v8-users

-- 
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users

Reply via email to