Skip to content

Commit 678570c

Browse files
committedAug 6, 2015
Removed GCToken.
This was a well-intentioned idea but not practical or useful. The idea was to have the compiler help check where in call paths a garbage-collection cycle could run. Unfortnately, adding this in as an after-thought resulted in all the places where GCTokens are created from thin air deep in some call path. It didn't change the fact that GC could happen pretty much anywhere. In a managed runtime, either GC can happen everywhere or it should only happen at a very small number of extremely well-defined points. The middle ground of "it can happen at all these places" is an invitation for a low budge horror movie, dismembered objects strewn throughout the code. Along with the rework of the stop-the-world mechanism, the removal of GCToken and restricting the invocation of a GC cycle to a single well-defined method call in a few well-defined locations, and finally, making all allocation paths GC-safe (ie GC will NOT run when allocating an object), Rubinius will have much better defined GC behavior. The GC safe allocation path is important for cases like the string_dup instruction, where a young GC cycle could run when allocating the dup and the original String (eg a literal String in a method) is in the young generation and moved. Since the original String is on the C stack and not in a GC root object, the dup fails when copying the contents of the original String. It's better to make allocation GC-safe than to accept the performance cost of the GC root in these sorts of cases. Also, that case is only one well-defined instance of the issue. There are more complicated ones.
1 parent 5f3b880 commit 678570c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+261
-353
lines changed
 

‎vm/builtin/autoload.cpp

+2-8
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,7 @@ namespace rubinius {
1414
G(autoload)->set_object_type(state, AutoloadType);
1515
}
1616

17-
/*
18-
* We added GCToken because we use send(). send() itself doesn't accept
19-
* a GCToken because it was tried and impacted performance severely. We
20-
* include it here anyway so methods using autoload resolving can see
21-
* it can trigger a GC due to calling back into Ruby.
22-
*/
23-
Object* Autoload::resolve(STATE, GCToken gct, CallFrame* call_frame, Module* under, bool honor_require) {
17+
Object* Autoload::resolve(STATE, CallFrame* call_frame, Module* under, bool honor_require) {
2418
Autoload* self = this;
2519
OnStack<1> os(state, self);
2620
Object* res = send(state, call_frame, state->symbol("resolve"));
@@ -41,7 +35,7 @@ namespace rubinius {
4135
return cNil;
4236
}
4337

44-
Object* Autoload::resolve(STATE, GCToken gct, CallFrame* call_frame, bool honor_require) {
38+
Object* Autoload::resolve(STATE, CallFrame* call_frame, bool honor_require) {
4539
Autoload* self = this;
4640
OnStack<1> os(state, self);
4741
Object* res = send(state, call_frame, state->symbol("resolve"));

‎vm/builtin/autoload.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ namespace rubinius {
3333
// Rubinius.primitive :autoload_allocate
3434
static Autoload* create(STATE);
3535

36-
Object* resolve(STATE, GCToken gct, CallFrame* call_frame, Module* under, bool honor_require = false);
37-
Object* resolve(STATE, GCToken gct, CallFrame* call_frame, bool honor_require = false);
36+
Object* resolve(STATE, CallFrame* call_frame, Module* under, bool honor_require = false);
37+
Object* resolve(STATE, CallFrame* call_frame, bool honor_require = false);
3838

3939
public: /* TypeInfo */
4040

0 commit comments

Comments
 (0)