On 7 August 2018 at 13:22, Ben Coman <btc@openinworld.com> wrote:

Next is to try��loading an Image.

+ Downloaded and unzipped�� http://files.pharo.org/image/70/latest-minimal-64.zip
+ In Visual Studio, right-clicked CMakeLists.txt > Debug and Launch Settings > pharo.exe
+ Edited the presented "launch.vs.json" as follows...
{
�� "version": "0.2.1",
�� "defaults": {},
�� "configurations": [
�� �� {
�� �� �� "type": "default",
�� �� �� "project": "CMakeLists.txt",
�� �� �� "projectTarget": "pharo.exe (dist\\pharo.exe)",
�� �� �� "name": "pharo.exe with image (dist\\pharo.exe)",
�� �� �� "args": [
�� �� �� �� "C:\\#Dev\\latest-minimal-64\\Pharo7.0-metacello-64bit-65cff7b.image",
�� �� �� �� "s"
�� �� �� ]
�� �� },
�� ]
}

Now running "x64-Debug" and��"pharo.exe with image"
I find it gets hung up in...
�� �� sqAllocateMemory(usqInt minHeapSize, usqInt desiredHeapSize)
in call...
�� ��alloc = sqAllocateMemorySegmentOfSizeAboveAllocatedSizeInto (roundUpToPage(desiredHeapSize), address, &allocBytes);
with...
�� �� desiredHeapSize ==> 39583744 (~39MB)
�� �� address ==> 0x00007ff7d6e00000

where inside that call...��
�� void *sqAllocateMemorySegmentOfSizeAboveAllocatedSizeInto(sqInt size, void *minAddress, sqInt *allocatedSizePointer)"
has...��
�� �� size ==> 39583744
�� �� minAddress ==> 0x00007ff7d6e00000
�� �� address ==> 0x00000000d6e00000
�� �� bytes ==> 39583744 (~39MB)
�� �� delta ==> 1048576

it gets stuck the following loop...�� https://github.com/bencoman/opensmalltalk-vm/blob/8231b96f9b/platforms/win32/vm/sqWin32SpurAlloc.c#L139-L183

�� �� while ((usqIntptr_t)(address + bytes) > (usqIntptr_t)address)
�� �� {�� �� alloc = VirtualAlloc(address, bytes, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
�� �� �� �� ��...
�� �� �� �� ��if (alloc >= (char *)minAddress) && (alloc <= address + delta))�� return alloc;
�� �� �� �� ��...
�� �� �� �� ��address += delta;
�� �� }

where...��
�� �� alloc ==> 0x00000000d6e00000
�� �� (alloc >= (char *)minAddress) ==> false.

which is effectively...�� (does this seem normal?)
�� �� �� ((char *)minAddress-address)/delta ==> 134,180,864 loops before exit.

but...��
�� �� (alloc >= (char *)address) ==> true.
would exit on the first pass of the loop, except...��
�� �� /* For some reason (large page support?) we can ask for a page-aligned
�� �� ��* address such as 0xNNNNf000 but VirtualAlloc will answer 0xNNNN0000.
�� �� ��* So accept allocs above minAddress rather than allocs above address
�� �� ��*/

where back one level "minAddress" is derived like this...
�� �� /* choose a suitable starting point. In MinGW the malloc heap is below the
�� �� ��* program, so take the max of a malloc and something form uninitialized
�� �� ��* data.
�� �� ��*/
hint = malloc(1);
free(hint);
hint = max(hint,(char *)&fIsConsole);
�� �� �� ����address = (char *)(((usqInt)hint + alignment - 1) & ~(alignment - 1));
�� �� �� �� address passed-by-value into minAddress��


Now I'm out of my depth trying to understand the background on that logic,
but if I blindly change the loop exit condition��
from...
�� ���� (alloc >= (char *)minAddress)
to...
�� ���� (alloc >= (char *)address)

then�� osvm_loadImage(tempImageNameAttempt()
and subsequently�� osvm_loadDefaultImage()�� succeed.����

So some expert attention would be good here (as time permits)��
In the meantime, I'll forge ahead to play with�� osvm_run();

cheers -ben


P.S. making "#define printProbes 1"�� and "fIsConsole = 1;"
shows...
probing [00000000D6E00000,00000000D93C0000)
probing [00000000D6F00000,00000000D94C0000)
probing [00000000D7000000,00000000D95C0000)
probing [00000000D7100000,00000000D96C0000)
probing [00000000D7200000,00000000D97C0000)
probing [00000000D7300000,00000000D98C0000)
probing [00000000D7400000,00000000D99C0000)
probing [00000000D7500000,00000000D9AC0000)
probing [00000000D7600000,00000000D9BC0000)