Open polluks opened 1 year ago
It looks like something bad is happening after collecting garbage. I added puts("Collect garbage...")
to the collectgarbage()
function and noticed that on m68k the garbage collector is called after the 4th iteration.
>> iteration 1
(- # -)
(- # -)
(- # -)
>> iteration 2
(- - -)
(# # #)
(- - -)
>> iteration 3
(- # -)
(- # -)
(- # -)
>> iteration 4
(- - -)
(# # #)
(- - -)
Collecting garbage...
>> iteration 5
(- # -)
(- # -)
(- # -)
But the problem is not with collectgarbage()
. The only platform-dependent place in fe is the tagging of pointers. It is expected that in the low byte (in big-endian case, the high byte) of the fe_Object
pointer, the two low bits (mask - 0x3) are always zeros; this is true for 32-bit alignment. These bits are used to indicate type and for marking when garbage collection is done. If the pointer actually has a different structure, it doesn't seem to work.
On qemu-m68k
under linux all scripts work without problems.
BTW I tried a 6502 port and it didn't work. A platform without alignment.
The current implementation requires at least 32-bit aligned addresses. It may be worth adding this problem to the 'Known Issues' in impl.md.
This will not work on the 6502 without code changes because it has 16-bit pointers. This means that the pointer tagging trick will only work for bit 0 if the memory is aligned to 16 bits. You can try manually align the memory to 32 bits. In fe_open()
you can replace: for (i = 0; i < ctx->object_count; i++)
with for (i = 0; i < ctx->object_count; i += 2)
; the memory block passed to fe_open()
must initially be 32-bit aligned. If this is the only problem, it should work, but it will require more memory.
Well, I had to reduce buf's size to 6000 because of memory constraints, 32-bit aligned is not an option. Maybe you are guessing that AmigaOS has an 31-bit address space because the most significant bit is used for management...
I think if fe_open()
aligns memory before populating free list, the issue should be solved. I did that, check it out. Funny, but 3 years ago, @rxi deleted something that would solve the problem now.
Nice try but it didn't help.
The compiler constructor said this code seems to be undefined behavior, please take a look:
#define tag(x) ( (x)->car.c )
...
typedef union { fe_Object *o; fe_CFunc f; fe_Number n; char c; } Value;
Maybe https://stackoverflow.com/questions/1812348/a-question-about-union-in-c-store-as-one-type-and-read-as-another-is-it-impl
Perhaps the compiler says this because #define tag(x) ((x)->car.c )
depends on the CPU architecture, namely the size of the other fields of the Value
union and the order of bytes in the system. If the architecture is little-endian, there should be no problem.
From C standard:
6.2.6 Representations of types ... 6.2.6.1 General ... 5 When a value is stored in an object of structure or union type, including in a member object, the bytes of the object representation that correspond to any padding bytes take unspecified values. The values of padding bytes shall not affect whether the value of such an object is a trap representation. Those bits of a structure or union object that are in the same byte as a bit-field member, but are not part of that member, shall similarly not affect whether the value of such an object is a trap representation. 6 When a value is stored in a member of an object of union type, the bytes of the object representation that do not correspond to that member but do correspond to other members take unspecified values, but the value of the union object shall not thereby become a trap representation. ...
The problem described in https://stackoverflow.com/questions/1812348/a-question-about-union-in-c-store-as-one-type-and-read-as-another-is-it-impl is related to incorrect initialization, there is no such problem here.
I'm tried to compile for Amiga with vbcc compiler (without float point), and I got stack overflow on collectgarbage()
with -stack-check
flag. I don't know much about Amiga, but I compiled for kickstart 1.3. Perhaps the behavior in AmigaOS will be different? What did you test on?
You may type stack 99999
before execution. I'm testing on MorphOS.
Now it works well. If you leave out the fact that it's very slow.