Permalink
Browse files

If we try to update a header and it fails we can retry

If we fail to update a header atomically and see an empty object header,
that's a valid state. It could be that the header was used for something
else before and isn't anymore, for example when it was thinly locked
when trying to install an object id and unlocked when the header was
swapped.

Related to #1995
  • Loading branch information...
1 parent 6e84de7 commit 52eba5f9280cdb9b5fda5b41eeb175e0c236533d @dbussink dbussink committed Nov 10, 2012
Showing with 9 additions and 2 deletions.
  1. +9 −2 vm/oop.cpp
View
@@ -99,6 +99,7 @@ namespace rubinius {
// Just ignore trying to reset it to 0 for now.
if(id == 0) return;
+retry:
// Construct 2 new headers: one is the version we hope that
// is in use and the other is what we want it to be. The CAS
// the new one into place.
@@ -124,7 +125,9 @@ namespace rubinius {
switch(orig.f.meaning) {
case eAuxWordEmpty:
- rubinius::bug("ObjectHeader claimed to be empty");
+ // The header was used for something else but not anymore
+ // Therefore we can just retry here.
+ goto retry;
case eAuxWordObjID:
// Someone beat us to it, ignore it
break;
@@ -143,6 +146,8 @@ namespace rubinius {
// Construct 2 new headers: one is the version we hope that
// is in use and the other is what we want it to be. The CAS
// the new one into place.
+
+retry:
HeaderWord orig = header;
orig.f.inflated = 0;
@@ -167,7 +172,9 @@ namespace rubinius {
switch(orig.f.meaning) {
case eAuxWordEmpty:
- rubinius::bug("ObjectHeader claimed to be empty");
+ // The header was used for something else but not anymore
+ // Therefore we can just retry here.
+ goto retry;
case eAuxWordHandle:
// Someone else has beaten us to it, clear the allocated
// header so it can be cleaned up on the next GC

0 comments on commit 52eba5f

Please sign in to comment.