Jakob, Toon, thank you very much for the insightful answers! From both of
you I learned something new about V8.
The return value of top level code makes total sense to me. The GC behavior
is replicated even when I replace assignment in the inner cycle to simple
read expression. E.g.
for (var i = 0; i < length; ++i) {
for (var j = 0; j < length; ++j) {
arr2[j]; // You'll see tones of GCs here.
}
}
I assume GC does not happen for the integer type, because the integer
return value does not need to be boxed?
And yes, Jakob, you are right. By no means the code in the gist was
supposed to actually copy arrays. I used it exclusively to explore this
behavior of GC.
Cheers,
Andrei
On Sunday, April 21, 2013 10:26:53 AM UTC-7, Jakob Kummerow wrote:
>
> On Sat, Apr 20, 2013 at 10:13 AM, Toon Verwaest
> <[email protected]<javascript:>
> > wrote:
>
>> Hi Andrei,
>>
>> V8 has an optimization that turns arrays into unboxed double arrays. If
>> you build a debug build of V8 you could do %DebugPrint(arr1) for example,
>> and you'll see that the elements kind is set to FAST_DOUBLE_ELEMENTS (or
>> FAST_HOLEY_DOUBLE_ELEMENTS).
>>
>> This means that doubles are stored unboxed in the array, i.e., there's no
>> heap-number wrapping around them. When you read such a number in optimized
>> code, it goes straight to a double-register. When you write it back to a
>> double array, it gets written directly inline into the array. This is a lot
>> faster than having to allocate heap-numbers and wrap/unwrap them for
>> computation.
>>
>> There's a catch however: fullcodegen, our slow compiler used to gather
>> typefeedback, does not support reading raw doubles. It can only work with
>> heap numbers. This means that when you read a double from a raw-double
>> array in fullcodegen, for example to copy it, you have to allocate a
>> heap-number and wrap the double in it. When you write this heap-number to
>> another double-array, the value gets taken out and written into the next
>> array. Thus the temporary heap-number is now garbage.
>>
>> So if you'd do trace-opt, hopefully you wouldn't see GC anymore after the
>> point where your copying function is optimized.
>>
>
> Well, you'd be surprised then :-)
>
> All of the cases where no excessive amounts of garbage are produced are
> working as expected.
>
> The interesting case is where lots of heap numbers are allocated even
> though optimized code is loading from and storing into arrays with double
> elements. This seems to be an artifact of how the return value of top-level
> code is computed. Essentially, the value that's being copied may become the
> top level's return value, which must always be boxed in a heap number, so
> in every iteration a heap number is allocated and filled with the value
> that was just copied, just in case it needs to be returned eventually.
> I'm not sure whether this is a bug or needs to be this way; but either way
> since array copying will typically be implemented in a function rather than
> in the top level, this is probably not worth spending much time on.
>
> Also, please note that the code in that gist (
> https://gist.github.com/anvaka/5423226) does *not* copy arrays. Instead,
> it's a highly inefficient mechanism to set every element in arr1 to the
> value of the last element in arr2. Before using this to actually copy any
> arrays, you'll want to remove one of the loops.
>
>
>> hth,
>> Toon
>>
>>
>> On Sat, Apr 20, 2013 at 4:42 AM, Andrei Kashcha
>> <[email protected]<javascript:>
>> > wrote:
>>
>>> I've been puzzling over V8 GC behavior for the past few days. I made a
>>> really simple program which copies content of one array into another (
>>> https://gist.github.com/anvaka/5423226 ), and I'm seeing lots of
>>> garbage collection in the d8 console with --trace_gc flag. But, with very
>>> simple tweaks garbage is not produced:
>>>
>>> This does not happen when arrays contain integer numbers
>>> This does not happen when any of the array's elements is printed to the
>>> console before or after the copy cycles
>>> This does not happen when the copy is executed within a function scope.
>>>
>>> Looking at the GC histograms "garbage" is comprised of nothing
>>> but HEAP_NUMBER_TYPE. When debugging the v8 source code I indeed see tones
>>> of calls to Runtime_AllocateHeapNumber in the runtime.cc file, but
>>> unfortunately my assembly programming skills do not allow me to fully
>>> understand what's going on here.
>>>
>>> Can someone shed some light on this behavior?
>>>
>>> --
>>> --
>>> v8-users mailing list
>>> [email protected] <javascript:>
>>> http://groups.google.com/group/v8-users
>>> ---
>>> You received this message because you are subscribed to the Google
>>> Groups "v8-users" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to [email protected] <javascript:>.
>>> For more options, visit https://groups.google.com/groups/opt_out.
>>>
>>>
>>>
>>
>> --
>> --
>> v8-users mailing list
>> [email protected] <javascript:>
>> http://groups.google.com/group/v8-users
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "v8-users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected] <javascript:>.
>> For more options, visit https://groups.google.com/groups/opt_out.
>>
>>
>>
>
>
--
--
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
---
You received this message because you are subscribed to the Google Groups
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.