On Sun, Apr 21, 2013 at 11:53 PM, Andrei Kashcha <[email protected]> wrote:

> 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.
>   }
> }
>
> So for the record, the lesson learned here is: don't do heavy computations
in top level code (which (1) is a good idea for several reasons, and (2) is
unlikely to happen in real code anyway).


> I assume GC does not happen for the integer type, because the integer
> return value does not need to be boxed?
>

Right. "Small" integers (up to 31 bits including the sign bit) can be
"Smi-tagged" (using the 32nd bit) and stored directly in objects. Since the
Smi-tag conveys the information that it's a Smi, no boxing is necessary.

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]>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 <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]>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<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]
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.


Reply via email to