{"action":"created","issue":{"url":"https://api.github.com/repos/planar/ocaml/issues/5","labels_url":"https://api.github.com/repos/planar/ocaml/issues/5/labels{/name}","comments_url":"https://api.github.com/repos/planar/ocaml/issues/5/comments","events_url":"https://api.github.com/repos/planar/ocaml/issues/5/events","html_url":"https://github.com/planar/ocaml/pull/5","id":97947089,"number":5,"title":"Fix caml_obj_truncate","user":{"login":"lpw25","id":2631210,"avatar_url":"https://avatars.githubusercontent.com/u/2631210?v=3","gravatar_id":"","url":"https://api.github.com/users/lpw25","html_url":"https://github.com/lpw25","followers_url":"https://api.github.com/users/lpw25/followers","following_url":"https://api.github.com/users/lpw25/following{/other_user}","gists_url":"https://api.github.com/users/lpw25/gists{/gist_id}","starred_url":"https://api.github.com/users/lpw25/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lpw25/subscriptions","organizations_url":"https://api.github.com/users/lpw25/orgs","repos_url":"https://api.github.com/users/lpw25/repos","events_url":"https://api.github.com/users/lpw25/events{/privacy}","received_events_url":"https://api.github.com/users/lpw25/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-07-29T14:20:30Z","updated_at":"2015-07-30T07:53:41Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/planar/ocaml/pulls/5","html_url":"https://github.com/planar/ocaml/pull/5","diff_url":"https://github.com/planar/ocaml/pull/5.diff","patch_url":"https://github.com/planar/ocaml/pull/5.patch"},"body":"Since sweeping can now occur before the ref table is emptied,\r\noverflow objects created by Obj.truncate must be marked Caml_black\r\nto avoid them being reallocated whilst still in the ref table.\r\nUsing Caml_black means that Abstract_tag should be used instead\r\nof 1 in case the contents of the block are not safe to scan."},"comment":{"url":"https://api.github.com/repos/planar/ocaml/issues/comments/126214535","html_url":"https://github.com/planar/ocaml/pull/5#issuecomment-126214535","issue_url":"https://api.github.com/repos/planar/ocaml/issues/5","id":126214535,"user":{"login":"lpw25","id":2631210,"avatar_url":"https://avatars.githubusercontent.com/u/2631210?v=3","gravatar_id":"","url":"https://api.github.com/users/lpw25","html_url":"https://github.com/lpw25","followers_url":"https://api.github.com/users/lpw25/followers","following_url":"https://api.github.com/users/lpw25/following{/other_user}","gists_url":"https://api.github.com/users/lpw25/gists{/gist_id}","starred_url":"https://api.github.com/users/lpw25/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lpw25/subscriptions","organizations_url":"https://api.github.com/users/lpw25/orgs","repos_url":"https://api.github.com/users/lpw25/repos","events_url":"https://api.github.com/users/lpw25/events{/privacy}","received_events_url":"https://api.github.com/users/lpw25/received_events","type":"User","site_admin":false},"created_at":"2015-07-30T07:53:41Z","updated_at":"2015-07-30T07:53:41Z","body":"This patch fixes a segfault which would occasionally happen during the tests for Core. The sequence of events that leads to a segfault is as follows:\r\n\r\n  1. Modify a value in some object (an array in this case) to point to a value on the minor heap -- which adds the modified address to the ref table (i.e. the remembered set).\r\n\r\n  2. Call Obj.truncate on the modified object. This creates a new \"overflow\" object containing the discarded part of the old object. This new object is marked *white*. Note that there is still a reference to this new object in the ref table.\r\n\r\n  3. The GC decides to do some sweeping (without performing a minor collection). This adds the overflow object to the free list because it is marked white.\r\n\r\n  4. The GC decides to do a minor collection. It starts by allocating objects on the major heap for each object being promoted from the minor heap, and adding a pointer from the minor heap object to the fresh major heap object. It also makes a linked list of these new values (called the todo list) by adding a pointer from each fresh major heap object to the previous minor heap object. Unfortunately, one of the fresh allocated major heap objects was made from part of the overflow object. This means there is a reference in the ref table to an item on the todo list.\r\n\r\n  5. As part of the minor collection, the references in the ref table are forwarded from the old minor heap objects to the corresponding major heap objects. Since one entry in the ref table refers not to a real pointer but to one of the pointers used to implement the todo list, it incorrectly forwards this pointer breaking the structure of the todo list.\r\n\r\n  6. Whilst attempting to finish the minor collection by traversing the todo list, the GC veers off into uninitialised bits of memory and segfaults.\r\n\r\nThis sequence of events was not possible in the old GC as the collector would never sweep until the ref table was empty. The solution is to mark the overflow object *black*. This forces it to stay around for a full cycle -- which ensures that we will have performed at least one minor collection."}}