Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

68k runtime issue #27

Open
polluks opened this issue Mar 3, 2023 · 11 comments
Open

68k runtime issue #27

polluks opened this issue Mar 3, 2023 · 11 comments

Comments

@polluks
Copy link

polluks commented Mar 3, 2023

$ fe scripts/life.fe 
>> iteration 1 
(- # -) 
(- # -) 
(- # -) 
>> iteration 2 
(- - -) 
(# # #) 
(- - -) 
>> iteration 3 
(- # -) 
(- # -) 
(- # -) 
>> iteration 4 
(- - -) 
(# # #) 
(- - -) 
error: dotted pair in argument list 
=> (nth x (nth y grid)) 
=> (or (nth x (nth y grid)) 0) 
=> (get-cell grid (- x 1) y) 
=> (+ (get-cell grid (- x 1) (- y 1)) (get-cell grid (- x 1) y) (g 
=> (let n (+ (get-cell grid (- x 1) (- y 1)) (get-cell grid (- x 1 
=> (next-cell grid cell x y) 
=> (f (car lst)) 
=> (cons (f (car lst)) res) 
=> (= res (cons (f (car lst)) res)) 
=> (while lst (= res (cons (f (car lst)) res)) (= lst (cdr lst))) 
=> (map (fn (cell) (= x (+ x 1)) (next-cell grid cell x y)) row) 
=> (f (car lst)) 
=> (cons (f (car lst)) res) 
=> (= res (cons (f (car lst)) res)) 
=> (while lst (= res (cons (f (car lst)) res)) (= lst (cdr lst))) 
=> (map (fn (row) (= y (+ y 1)) (let x -1) (map (fn (cell) (= x (+ 
=> (next-grid grid) 
=> (= grid (next-grid grid)) 
=> (while (<= i n) (print ">> iteration" i) (print-grid grid) (pri 
@ooichu
Copy link

ooichu commented Mar 4, 2023

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.

@polluks
Copy link
Author

polluks commented Mar 4, 2023

BTW I tried a 6502 port and it didn't work. A platform without alignment.

@ooichu
Copy link

ooichu commented Mar 4, 2023

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.

@polluks
Copy link
Author

polluks commented Mar 4, 2023

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

@ooichu
Copy link

ooichu commented Mar 4, 2023

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.

@polluks
Copy link
Author

polluks commented Mar 5, 2023

Nice try but it didn't help.

@polluks
Copy link
Author

polluks commented Mar 8, 2023

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

@ooichu
Copy link

ooichu commented Mar 8, 2023

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.

@ooichu
Copy link

ooichu commented Mar 8, 2023

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?

@polluks
Copy link
Author

polluks commented Mar 8, 2023

You may type stack 99999 before execution. I'm testing on MorphOS.

@ooichu
Copy link

ooichu commented Mar 8, 2023

Now it works well. If you leave out the fact that it's very slow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants