From da70c79fa0e282cef042e4f2785df899010f53d6 Mon Sep 17 00:00:00 2001 From: Richard Kistruck Date: Fri, 9 Jun 2006 18:21:58 +0100 Subject: [PATCH] Mps wiki article on gc: allocation points: how it's supposed to be. Also note that must make at least one ambiguous ref and no exact refs to new object before calling commit. Copied from Perforce Change: 159174 ServerID: perforce.ravenbrook.com --- mps/manual/wiki/gc.html | 183 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 181 insertions(+), 2 deletions(-) diff --git a/mps/manual/wiki/gc.html b/mps/manual/wiki/gc.html index 4083e25017c..f7ba260a475 100644 --- a/mps/manual/wiki/gc.html +++ b/mps/manual/wiki/gc.html @@ -48,11 +48,19 @@

The essential MPS concepts for GC are:

-

Formats

+

The advanced MPS concepts for GC are:

+ + + +

Format

The client can choose how to format its objects, but the MPS will sometimes need to ask the client some questions about an object, such @@ -181,12 +189,183 @@ AMCFix() (and now AMCHeaderFix() too).

It's a bit messy -- sorry.

+ +

Allocation Point

+ +

Overview of two-phase allocation

+ +

The client should:

+
    +
  1. mps_reserve some memory,
  2. +
  3. construct a new object in it,
  4. +
  5. write a reference to the new object into some older object, + thereby connecting the new object into the client's graph of + objects
  6. +
  7. mps_commit the new object to MPS management.
  8. +
+ +

The graph of managed references to mobile objects

+ +

The MPS is a moving garbage collector: it supports + preserve-by-copying pools, whose objects are 'mobile'. + Whenever the MPS moves an object, it will ensure that + all managed references are updated to point to the + new location -- and this happens instantaneously as far + as the client sees it.

+ +

The client should assume that, between any pair of + instructions, the MPS may 'shake' this graph, moving + all the mobile objects, and updating all the managed + references.

+ +

The client usually takes care to ensure that the + references it + holds are managed. To be managed, the reference must be + in a formatted object that is reachable from a root, or + actually in a root (such as a scanned stack).

+ +

It is okay for a careful client to hold unmanaged references, + but:

+ + +

mps_reserve

+ +

mps_reserve returns a reference to a piece + of new memory for the client to build a new object in. + During this build, the MPS pins the piece of memory, and + treats it as raw data.

+ +

"Pinned" means: it will not move, be collected, be unmapped, + or anything like that.

+ +

"Raw data" means two things:

+ +

Firstly, "raw data" means that any references stored IN the + new object are unmanaged. This means:

+ + +

Secondly, "raw data" means that any references TO the new + object are treated like other references to unmanaged memory. + [.belief.refs-to-uninit-safe: + We're 'sure', but I need to check this. What does Fix + actually do with a pointer into the init-alloc zone? We + hope it ignores it. RHSK 2006-06-09] + Because of this, you are permitted to connect the new object + into your graph of managed objects immediately. The MPS gives + you these guarantees:

+ + +

Building the object

+ +

The client will typically do all these things:

+ + +

However, during the build, the client MUST NOT read + (from the new object) a reference to an existing mobile object -- + because the reference is unmanaged and may be stale.

+ +

(Actually, the restriction is: the moment a reference to an + existing mobile object is written into the new object, that + reference (in the new object) may become stale. And you'd better + not use (dereference) a stale reference. And you'd better not + write it into any existing object. Writing it back into another + part of the new object is okay. Just don't trust it to be a valid + reference.)

+ +

mps_commit

+ +

When you call mps_commit, it will either fail or succeed.

+ +

Almost always, mps_commit succeeds. + If it succeeds, that means:

+ + +

Occasionally but rarely, mps_commit fails. + This means that the new object no longer exists. + The memory may even be unmapped by the time + mps_commit returns.

+ +

When this happens the client should take care to clear up any + managed references to the (now vanished) new object.

+ +

[But there's a hole here, before the client does this. + Are managed (aka scanned) references TO + it still safe? They were safe during building + (by .belief.refs-to-uninit-safe). But now the AP pointers have + gone away. Are they still safe? + Clearly, if they are only RankAMBIG, they are safe. + What if they are RankEXACT? + RHSK 2006-06-09]

+ +

[Discussion with RB 2006-06-09: yes, that's a problem for exact + references. Must not make any exact refs to a new object. And + unmanaged refs are not sufficient, because they won't preserve the + new object during commit. So must make at least one ambiguous + ref to new object before calling commit. That's the truth + currently. There are various ways to solve this to allow + purely-exact mutators. For instance, + keep the old init..alloc address-space flagged as a zombie zone, + until some communication with mutator (perhaps another reserve + from same AP?) indicates that mutator has removed all those + pesky exact refs to the now-dead ex-new object. RHSK 2006-06-09]

+ +

The client will also have to re-create the object. For this + reason the standard allocation point idiom is:

+ +

+  do {
+    if (mps_reserve != MPS_RES_OK) {
+      goto fail_nomemory;
+    }
+    /* initialize my new object */
+    /* make an ambiguous reference to new object */
+  } while (! mps_commit);
+  /* link new object into my object graph */
+
+ +

B. Document History

   2006-06-02  RHSK  Created.
   2006-06-02  RHSK  Introduction to MPS Formats
   2006-06-06  RHSK  Formats: clarify explanation of methods, copy method is obsolete, mention format variants.
+  2006-06-09  RHSK  Allocation points: how it's supposed to be, from RB 2006-06-09.
+  2006-06-09  RHSK  Allocation points: must make at least one ambiguous ref and no exact refs to new object before calling commit.