GameMonkey Script

GameMonkey Script Forums
It is currently Mon Nov 20, 2017 3:37 pm

All times are UTC




Post new topic Reply to topic  [ 25 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Wed Oct 05, 2011 4:59 am 
Offline

Joined: Fri Jul 24, 2009 5:22 am
Posts: 14
Another update:

I think that:

Code:
for(int index = m_base; index < m_top; ++index) // NOTE: Should this be from m_base - 2 ?


should be:
Code:
for(int index = m_base-2; index < m_top; ++index)


I got a crash when the last stack frame was pop and the thread killed. I am not sure if it was a problem of my simulation, but -2 fixed the crash.


Top
 Profile  
Reply with quote  
PostPosted: Wed Oct 05, 2011 8:15 am 
Offline

Joined: Mon Dec 15, 2003 1:38 pm
Posts: 698
Ghosto wrote:
I found that probably even BC_SETLOCAL should set a barrier.
I am afraid that all this new check could impact on the performances...

It is possible this is needed to support GC running at any time. I guess this whole GC design flaw was hidden because the GC is normally run on plain Execute() cycles. It should be trigger-able on every single alloc if desired.

Looks like I'm going to have to investigate this issue some more to find the best solution with minimal impact on performance and usability.

If we need a few more write barriers, performance may not suffer too much as the write barrier only does work when the GC is actually running a cycle which should be intermittent and short.

Are you still experiencing crashes with the changes you have described so far (BC_SETLOCAL, base-2, native push stack frame) ?


Top
 Profile  
Reply with quote  
PostPosted: Wed Oct 05, 2011 9:07 am 
Offline

Joined: Mon Dec 15, 2003 1:38 pm
Posts: 698
Another question for you Ghosto... do you really need to run the GC manually at various code locations or can you configure it for automatic use, which should avoid stack issues? (We'll still try to fix this properly, even if these issues can be avoided.)


Top
 Profile  
Reply with quote  
PostPosted: Thu Oct 06, 2011 2:19 am 
Offline

Joined: Fri Jul 24, 2009 5:22 am
Posts: 14
Hi, Greg

For the current game we are ok...the frame rate is still ok and I am not able to crash the GC anymore (for test I called a full collect from the BC_CALL switch and it was working)
Like I wrote before, I do not why this happened now...maybe somebody here added a yield() in a wrong place...(for 4 years everything was ok...we never noticed it)

Normally we call GC directly only when we are releasing and loading stuff, it can be reduced, but loading stuff generate so much garbage without yielding, that we have to free memory manually.
Plus, because we do now have separated memory manager for GM, in debug mode we call GC all the times that we want know exactly how much memory is used by a particular feature.

Anyway, do you think that this GC problem is related only to the manual call, I feel that even the incremental GC can create the same problem it is just incredibly rare.

Thanks again


Top
 Profile  
Reply with quote  
PostPosted: Thu Oct 06, 2011 3:19 am 
Offline

Joined: Mon Dec 15, 2003 1:38 pm
Posts: 698
Glad you're able to progress. As you suggest, many titles have shipped with earlier GM versions and tested stable.

I am quite sure I understand the cause of the GC issue, just not the best way to completely address it yet.

At the moment I think that manual calls to the GC help trigger the issue, which can otherwise be mostly or completely avoided with the automatic placement. You can partly verify this by placing a yield() directly after the sysCollectGarbage( true ) in each test case you've shown, which appears to avoid the issue.

I need to think some more about this and run some more tests. I would like the GC to be callable just about anywhere at any time. The user may need to disable the GC manually when they have known floating objects in a native binding, but that was always good practice.


Top
 Profile  
Reply with quote  
PostPosted: Thu Oct 06, 2011 7:06 am 
Offline

Joined: Mon Dec 15, 2003 1:38 pm
Posts: 698
To clarify why I think the GC is 'safe' if started while the script is not running...

Each time the GC starts, two things occur, 1) a 'flip' cycling the GC color logic 2) a atomic root scan.

The flip causes 'new' objects to now just be 'live' objects. The scan seeds the connectivity trace, to find all live objects. When the GC is forced to start while script is running, the stack (a root) changes. Some objects may change from 'new' to 'live' while others become 'new'. However since script is executing, new linkages are formed at that time and new objects may contain old children and vice versa (a breach of the GC color logic.)

Now the GC normally runs over several application frames to complete a cycle, but the 'flip' and atomic root scan does not usually occur while the stack is volatile. Instead, the write barrier merely becomes active, simply adding touched objects to the scan list. When execution has stopped, the GC performs its next phase of operation. Although the stack did not implement the write barrier, new objects remained new and live objects remained live so they did not swap order and cause a breach of the color logic. (If the color logic is breached, new/live objects become isolated because the GC system thinks they have already been scanned and in the next GC phase, they are freed while still connected, causing a native exception.)

When I prototyped the GC, I implemented it as a c++ smart pointer system. You can imagine the compiler automatically adds code for stack changes and stack pops on function returns. When I put the system in GM, I did not add the stack write barriers to the runtime and got away with it because the GC normally operates between script executions.

Anyway, that's why I think this issue has remained hidden most of the time.


Top
 Profile  
Reply with quote  
PostPosted: Thu Oct 06, 2011 8:13 am 
Offline

Joined: Fri Jul 24, 2009 5:22 am
Posts: 14
But, if a TableObject has to write a barrier when it loses the ownership of a referenced object, why the stack doesn't?
In which way they are different?

Another think that I do not understand is that if in my samples I yield or sleep where I was calling the fullCollect, and in the same time the GC reach the hard limit isn't the same?
It will flip the color.
I thought that the difference between a full GC and the normal GC is just the total amount of work done.

Anyway all this stuff are very interesting, I will read the paper about GC that you mentioned in the GameMoneky doc.
Thanks


Top
 Profile  
Reply with quote  
PostPosted: Thu Oct 06, 2011 10:36 pm 
Offline

Joined: Mon Dec 15, 2003 1:38 pm
Posts: 698
Please try v1.28.5 and see if you can break it. It simply includes the stack write barriers discussed so far.


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 11, 2011 3:51 am 
Offline

Joined: Fri Jul 24, 2009 5:22 am
Posts: 14
Hi Greg,

1.28.5 is unbreakable, at least for what I tried.
Thanks again for your support.


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 11, 2011 6:22 am 
Offline

Joined: Mon Dec 15, 2003 1:38 pm
Posts: 698
Good to hear. Stability is critically important to me.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 25 posts ]  Go to page Previous  1, 2

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group