<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>vm/data_heap_checker.cpp</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -44,6 +44,7 @@ DLL_OBJS = $(PLAF_DLL_OBJS) \
 	vm/compaction.o \
 	vm/contexts.o \
 	vm/data_heap.o \
+	vm/data_heap_checker.o \
 	vm/debug.o \
 	vm/dispatch.o \
 	vm/errors.o \</diff>
      <filename>Makefile</filename>
    </modified>
    <modified>
      <diff>@@ -288,7 +288,7 @@ struct data_reference_object_visitor {
 	void operator()(object *obj)
 	{
 		data_reference_slot_visitor visitor(look_for,obj,parent);
-		parent-&gt;do_slots(obj,visitor);
+		obj-&gt;each_slot(visitor);
 	}
 };
 </diff>
      <filename>vm/debug.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -138,7 +138,7 @@ void factor_vm::relocate_object(object *object,
 	cell type = object-&gt;type();
 	
 	/* Tuple relocation is a bit trickier; we have to fix up the
-	layout object before we can get the tuple size, so do_slots is
+	layout object before we can get the tuple size, so each_slot is
 	out of the question */
 	if(type == TUPLE_TYPE)
 	{
@@ -154,7 +154,7 @@ void factor_vm::relocate_object(object *object,
 	else
 	{
 		object_fixupper fixupper(this,data_relocation_base);
-		do_slots(object,fixupper);
+		object-&gt;each_slot(fixupper);
 
 		switch(type)
 		{</diff>
      <filename>vm/image.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -102,7 +102,9 @@ struct object {
 	cell size() const;
 	cell binary_payload_start() const;
 
-	cell *slots()  const { return (cell *)this; }
+	cell *slots() const { return (cell *)this; }
+
+	template&lt;typename Iterator&gt; void each_slot(Iterator &amp;iter);
 
 	/* Only valid for objects in tenured space; must cast to free_heap_block
 	to do anything with it if its free */</diff>
      <filename>vm/layouts.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -98,4 +98,19 @@ inline static bool save_env_p(cell i)
 	return (i &gt;= OBJ_FIRST_SAVE &amp;&amp; i &lt;= OBJ_LAST_SAVE);
 }
 
+template&lt;typename Iterator&gt; void object::each_slot(Iterator &amp;iter)
+{
+	cell scan = (cell)this;
+	cell payload_start = binary_payload_start();
+	cell end = scan + payload_start;
+
+	scan += sizeof(cell);
+
+	while(scan &lt; end)
+	{
+		iter((cell *)scan);
+		scan += sizeof(cell);
+	}
+}
+
 }</diff>
      <filename>vm/objects.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -262,11 +262,16 @@ struct factor_vm
 
 	inline void write_barrier(object *obj, cell size)
 	{
-		char *start = (char *)obj;
-		for(cell offset = 0; offset &lt; size; offset += card_size)
-			write_barrier((cell *)(start + offset));
+		cell start = (cell)obj &amp; -card_size;
+		cell end = ((cell)obj + size + card_size - 1) &amp; -card_size;
+
+		for(cell offset = start; offset &lt; end; offset += card_size)
+			write_barrier((cell *)offset);
 	}
 
+	// data heap checker
+	void check_data_heap();
+
 	// gc
 	void end_gc();
 	void start_gc_again();
@@ -585,24 +590,6 @@ struct factor_vm
 	void save_callstack_bottom(stack_frame *callstack_bottom);
 	template&lt;typename Iterator&gt; void iterate_callstack(context *ctx, Iterator &amp;iterator);
 
-	/* Every object has a regular representation in the runtime, which makes GC
-	much simpler. Every slot of the object until binary_payload_start is a pointer
-	to some other object. */
-	template&lt;typename Iterator&gt; void do_slots(object *obj, Iterator &amp;iter)
-	{
-		cell scan = (cell)obj;
-		cell payload_start = obj-&gt;binary_payload_start();
-		cell end = scan + payload_start;
-
-		scan += sizeof(cell);
-
-		while(scan &lt; end)
-		{
-			iter((cell *)scan);
-			scan += sizeof(cell);
-		}
-	}
-
 	//alien
 	char *pinned_alien_offset(cell obj);
 	cell allot_alien(cell delegate_, cell displacement);</diff>
      <filename>vm/vm.hpp</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>81a68ebd364926d69328c01a685a755ed597b846</id>
    </parent>
  </parents>
  <author>
    <name>Slava Pestov</name>
    <email>slava@slava-pestovs-macbook-pro.local</email>
  </author>
  <url>http://github.com/slavapestov/factor/commit/585a1a7fbe5d8a9baa9ef833d171802d389a542e</url>
  <id>585a1a7fbe5d8a9baa9ef833d171802d389a542e</id>
  <committed-date>2009-11-11T17:31:18-08:00</committed-date>
  <authored-date>2009-11-11T17:31:18-08:00</authored-date>
  <message>vm: fix fencepost error in write barrier on large object allocation; fixes benchmark.sort crash</message>
  <tree>afc00fe7ef43f34c289a428937c73e1c52682232</tree>
  <committer>
    <name>Slava Pestov</name>
    <email>slava@slava-pestovs-macbook-pro.local</email>
  </committer>
</commit>
