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