[Vm-dev] [Spur] endless recursion in forward become
Igor Stasenko
siguctua at gmail.com
Thu Jun 23 15:11:33 UTC 2016
On 23 June 2016 at 18:00, Eliot Miranda <eliot.miranda at gmail.com> wrote:
>
> Hi Igor,
>
> On Jun 23, 2016, at 7:34 AM, Igor Stasenko <siguctua at gmail.com> wrote:
>
> Hi, Eliot,
>
> why not trimming the object (if its size allows it) to mark rest of
> now-forwader object to be a freespace immediately?
> Like that you can avoid stressing memory too much by doubling amount of
> memory needed per each forwaded object involved in become operation.
> And that, of course, if direct contents swap is not possible.
>
>
> Agreed. Would you like to have a go and I'll review it? The problem with
> truncating short objects is that Spur's memory manager cannot represent a
> free chunk of only 8 bytes in length. The minimum sized free chunk (& minimum
> sized object) is 16 bytes. And any size higher (24, 32, 40 etc) is ok. So
> if you want to shorten a 24 byte object to 16 bytes because it's been
> turned into a forwarder, you can't because that would leave an 8-byte
> sliver. So be sure to check that the object is > 24 bytes long before
> trying to truncate it.
>
That's why i said - if its size allows it.
I could give it try.. Of course i will need some more details, to do it
fast, like updating a first-free object pointer, if needed and what
limitations there, and things like if it safe to throw this newly-free
object space into a soup of free chunks regardless of their location in
memory (old heap/eden etc)
I would be glad, if you can give me quick brief of these potential pitfall,
since i don't know much about new spur memory model innards.
>
> On 22 June 2016 at 16:44, Eliot Miranda <eliot.miranda at gmail.com> wrote:
>
>>
>> Hi Bert,
>>
>>
>> On Jun 22, 2016, at 5:57 AM, Bert Freudenberg <bert at freudenbergs.de>
>> wrote:
>>
>> Hi Eliot,
>>
>> the become-forward works now, indeed.
>>
>> But why is it different with the swapping become? This still gets into an
>> endless recursion:
>>
>> (ByteString new: 20000000) become: (WideString new: 20000000)
>>
>> Why is it creating copies at all?
>>
>>
>> because that's how Spur works. Become is lazy; the two objects are
>> turned into forwarders to copies of each other. If the two objects have
>> the same byte size as heap objects (rounded up to 8 byte units) their
>> contents can be exchanged. If they are not, two copies must be created and
>> the two originals turned into forwarders to the copies. Remember the
>> slides from my Cambridge talk.
>>
>> Spur chooses to trade memory (creating the copies) over time (searching
>> the entire heap looking fir references). This is the right trade off until
>> you start becoming objects that are substantial fractions of the entire
>> heap in size.
>>
>> In your case you could avoid the pain simply by making sure the steam had
>> a wide String as contents in the first place. I understand that may not be
>> possible.
>>
>>
>> - Bert -
>>
>> On Mon, Jun 20, 2016 at 10:36 PM, Eliot Miranda <eliot.miranda at gmail.com>
>> wrote:
>>
>>>
>>> Hi Bert,
>>>
>>> it was a regression in argument validation for become introduced in
>>> fixing argument validation for the one-way copy hash case. The code was
>>> erroneously checking that it had space to create copies of the input
>>> arguments, even though it was a one-way become. It's a copyHash become and
>>> that confused it. It's now fixed. I'll generate sources and push and new
>>> builds should appear shortly ;-)
>>>
>>> On Thu, Jun 16, 2016 at 5:11 AM, Bert Freudenberg <bert at freudenbergs.de>
>>> wrote:
>>>
>>>>
>>>> I'm reading a 20MB text file. At some point it tries to convert the 20
>>>> MB ByteString into an 80 MB WideString using forward become. This fails
>>>> resulting in an endless loop. The primitive failure code for
>>>> elementsForwardIdentityTo: (primitive 72) is #'insufficient object memory'
>>>> and it tries again after growing:
>>>>
>>>> ec == #'insufficient object memory' ifTrue:
>>>> [Smalltalk garbageCollect < 1048576 ifTrue:
>>>> [Smalltalk growMemoryByAtLeast: 1048576].
>>>> ^self elementsForwardIdentityTo: otherArray].
>>>>
>>>> but the growMemoryByAtLeast: does not actually grow the memory:
>>>>
>>>> {Smalltalk garbageCollect.
>>>> Smalltalk growMemoryByAtLeast: 1048576.
>>>> Smalltalk garbageCollect.}
>>>>
>>>> ==> #(58576608 16777216 58576608)
>>>>
>>>> 58 MB are not enough, but it doesn't grow any further.
>>>>
>>>> The question is, why does it try to allocate a new object at all? The
>>>> WideString exists already. I thought Spur would simply install a forwarder?
>>>>
>>>> To reproduce, execute
>>>>
>>>> (ByteString new: 20000000) writeStream nextPut: (Character value:
>>>> 128169)
>>>>
>>>> You probably want to follow that with a user interrupt (Cmd-period).
>>>>
>>>> This happens using the latest Spur VM from github (r201606160944)
>>>>
>>>> - Bert -
>>>>
>>>>
>>>
>>>
>>> --
>>> _,,,^..^,,,_
>>> best, Eliot
>>>
>>
>>
>>
>
>
> --
> Best regards,
> Igor Stasenko.
>
>
>
--
Best regards,
Igor Stasenko.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20160623/1feb36ea/attachment-0001.htm
More information about the Vm-dev
mailing list