<?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>@@ -256,35 +256,22 @@ M: ppc %double&gt;single-float FRSP ;
 M: ppc %unbox-alien ( dst src -- )
     alien-offset LWZ ;
 
-M:: ppc %unbox-any-c-ptr ( dst src temp -- )
+M:: ppc %unbox-any-c-ptr ( dst src -- )
     [
-        { &quot;is-byte-array&quot; &quot;end&quot; &quot;start&quot; } [ define-label ] each
-        ! Address is computed in dst
+        &quot;end&quot; define-label
         0 dst LI
-        ! Load object into scratch-reg
-        scratch-reg src MR
-        ! We come back here with displaced aliens
-        &quot;start&quot; resolve-label
         ! Is the object f?
-        0 scratch-reg \ f type-number CMPI
-        ! If so, done
+        0 src \ f type-number CMPI
         &quot;end&quot; get BEQ
+        ! Compute tag in dst register
+        dst src tag-mask get ANDI
         ! Is the object an alien?
-        0 scratch-reg header-offset LWZ
-        0 0 alien type-number tag-fixnum CMPI
-        &quot;is-byte-array&quot; get BNE
-        ! If so, load the offset
-        0 scratch-reg alien-offset LWZ
-        ! Add it to address being computed
-        dst dst 0 ADD
-        ! Now recurse on the underlying alien
-        scratch-reg scratch-reg underlying-alien-offset LWZ
-        &quot;start&quot; get B
-        &quot;is-byte-array&quot; resolve-label
-        ! Add byte array address to address being computed
-        dst dst scratch-reg ADD
-        ! Add an offset to start of byte array's data area
-        dst dst byte-array-offset ADDI
+        0 dst alien type-number CMPI
+        ! Add an offset to start of byte array's data
+        dst src byte-array-offset ADDI
+        &quot;end&quot; get BNE
+        ! If so, load the offset and add it to the address
+        dst src alien-offset LWZ
         &quot;end&quot; resolve-label
     ] with-scope ;
 
@@ -293,53 +280,84 @@ M:: ppc %unbox-any-c-ptr ( dst src temp -- )
 M:: ppc %box-alien ( dst src temp -- )
     [
         &quot;f&quot; define-label
-        dst  %load-immediate
+        dst \ f type-number %load-immediate
         0 src 0 CMPI
         &quot;f&quot; get BEQ
         dst 5 cells alien temp %allot
         temp \ f type-number %load-immediate
         temp dst 1 alien@ STW
         temp dst 2 alien@ STW
-        displacement dst 3 alien@ STW
-        displacement dst 4 alien@ STW
+        src dst 3 alien@ STW
+        src dst 4 alien@ STW
         &quot;f&quot; resolve-label
     ] with-scope ;
 
-M:: ppc %box-displaced-alien ( dst displacement base displacement' base' base-class -- )
+M:: ppc %box-displaced-alien ( dst displacement base temp base-class -- )
+    ! This is ridiculous
     [
         &quot;end&quot; define-label
-        &quot;alloc&quot; define-label
-        &quot;simple-case&quot; define-label
+        &quot;not-f&quot; define-label
+        &quot;not-alien&quot; define-label
+
         ! If displacement is zero, return the base
         dst base MR
         0 displacement 0 CMPI
         &quot;end&quot; get BEQ
-        ! Quickly use displacement' before its needed for real, as allot temporary
-        displacement' :&gt; temp
-        dst 4 cells alien temp %allot
-        ! If base is already a displaced alien, unpack it
-        0 base \ f type-number CMPI
-        &quot;simple-case&quot; get BEQ
-        temp base header-offset LWZ
-        0 temp alien type-number tag-fixnum CMPI
-        &quot;simple-case&quot; get BNE
-        ! displacement += base.displacement
-        temp base 3 alien@ LWZ
-        displacement' displacement temp ADD
-        ! base = base.base
-        base' base 1 alien@ LWZ
-        &quot;alloc&quot; get B
-        &quot;simple-case&quot; resolve-label
-        displacement' displacement MR
-        base' base MR
-        &quot;alloc&quot; resolve-label
-        ! Store underlying-alien slot
-        base' dst 1 alien@ STW
-        ! Store offset
-        displacement' dst 3 alien@ STW
-        ! Store expired slot (its ok to clobber displacement')
+
+        ! Displacement is non-zero, we're going to be allocating a new
+        ! object
+        dst 5 cells alien temp %allot
+
+        ! Set expired to f
         temp \ f type-number %load-immediate
         temp dst 2 alien@ STW
+
+        ! Is base f?
+        0 base \ f type-number CMPI
+        &quot;not-f&quot; get BNE
+
+        ! Yes, it is f. Fill in new object
+        base dst 1 alien@ STW
+        displacement dst 3 alien@ STW
+        displacement dst 4 alien@ STW
+
+        &quot;end&quot; get B
+
+        &quot;not-f&quot; resolve-label
+
+        ! Check base type
+        temp base tag-mask get ANDI
+
+        ! Is base an alien?
+        0 temp alien type-number CMPI
+        &quot;not-alien&quot; get BNE
+
+        ! Yes, it is an alien. Set new alien's base to base.base
+        temp base 1 alien@ LWZ
+        temp dst 1 alien@ STW
+
+        ! Compute displacement
+        temp base 3 alien@ LWZ
+        temp temp displacement ADD
+        temp dst 3 alien@ STW
+
+        ! Compute address
+        temp base 4 alien@ LWZ
+        temp temp displacement ADD
+        temp dst 4 alien@ STW
+
+        ! We are done
+        &quot;end&quot; get B
+
+        ! Is base a byte array? It has to be, by now...
+        &quot;not-alien&quot; resolve-label
+
+        base dst 1 alien@ STW
+        displacement dst 3 alien@ STW
+        temp base byte-array-offset ADDI
+        temp temp displacement ADD
+        temp dst 4 alien@ STW
+
         &quot;end&quot; resolve-label
     ] with-scope ;
 </diff>
      <filename>basis/cpu/ppc/ppc.factor</filename>
    </modified>
    <modified>
      <diff>@@ -4,8 +4,7 @@ USING: accessors arrays assocs classes classes.struct
 combinators combinators.smart continuations fry generalizations
 generic grouping io io.styles kernel make math math.parser
 math.statistics memory namespaces parser prettyprint sequences
-sorting specialized-arrays splitting strings system vm words ;
-SPECIALIZED-ARRAY: gc-event
+sorting splitting strings system vm words ;
 IN: tools.memory
 
 &lt;PRIVATE
@@ -101,7 +100,7 @@ SYMBOL: gc-events
 : collect-gc-events ( quot -- )
     enable-gc-events
     [ ] [ disable-gc-events drop ] cleanup
-    disable-gc-events byte-array&gt;gc-event-array gc-events set ; inline
+    disable-gc-events [ gc-event memory&gt;struct ] map gc-events set ; inline
 
 &lt;PRIVATE
 </diff>
      <filename>basis/tools/memory/memory.factor</filename>
    </modified>
    <modified>
      <diff>@@ -3,7 +3,6 @@
 namespace factor
 {
 
-/* make a new array with an initial element */
 array *factor_vm::allot_array(cell capacity, cell fill_)
 {
 	data_root&lt;object&gt; fill(fill_,this);
@@ -12,12 +11,13 @@ array *factor_vm::allot_array(cell capacity, cell fill_)
 	return new_array;
 }
 
-/* push a new array on the stack */
 void factor_vm::primitive_array()
 {
-	cell initial = dpop();
-	cell size = unbox_array_size();
-	dpush(tag&lt;array&gt;(allot_array(size,initial)));
+	data_root&lt;object&gt; fill(dpop(),this);
+	cell capacity = unbox_array_size();
+	array *new_array = allot_uninitialized_array&lt;array&gt;(capacity);
+	memset_cell(new_array-&gt;data(),fill.value(),capacity * sizeof(cell));
+	dpush(tag&lt;array&gt;(new_array));
 }
 
 cell factor_vm::allot_array_1(cell obj_)
@@ -54,9 +54,10 @@ cell factor_vm::allot_array_4(cell v1_, cell v2_, cell v3_, cell v4_)
 
 void factor_vm::primitive_resize_array()
 {
-	array *a = untag_check&lt;array&gt;(dpop());
+	data_root&lt;array&gt; a(dpop(),this);
+	a.untag_check(this);
 	cell capacity = unbox_array_size();
-	dpush(tag&lt;array&gt;(reallot_array(a,capacity)));
+	dpush(tag&lt;array&gt;(reallot_array(a.untagged(),capacity)));
 }
 
 void growable_array::add(cell elt_)</diff>
      <filename>vm/arrays.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -24,9 +24,10 @@ void factor_vm::primitive_uninitialized_byte_array()
 
 void factor_vm::primitive_resize_byte_array()
 {
-	byte_array *array = untag_check&lt;byte_array&gt;(dpop());
+	data_root&lt;byte_array&gt; array(dpop(),this);
+	array.untag_check(this);
 	cell capacity = unbox_array_size();
-	dpush(tag&lt;byte_array&gt;(reallot_array(array,capacity)));
+	dpush(tag&lt;byte_array&gt;(reallot_array(array.untagged(),capacity)));
 }
 
 void growable_byte_array::append_bytes(void *elts, cell len)</diff>
      <filename>vm/byte_arrays.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -15,14 +15,8 @@ struct growable_byte_array {
 
 template&lt;typename Type&gt; byte_array *factor_vm::byte_array_from_value(Type *value)
 {
-	return byte_array_from_values(value,1);
-}
-
-template&lt;typename Type&gt; byte_array *factor_vm::byte_array_from_values(Type *values, cell len)
-{
-	cell size = sizeof(Type) * len;
-	byte_array *data = allot_uninitialized_array&lt;byte_array&gt;(size);
-	memcpy(data-&gt;data&lt;char&gt;(),values,size);
+	byte_array *data = allot_uninitialized_array&lt;byte_array&gt;(sizeof(Type));
+	memcpy(data-&gt;data&lt;char&gt;(),value,sizeof(Type));
 	return data;
 }
 </diff>
      <filename>vm/byte_arrays.hpp</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>@@ -270,11 +270,25 @@ void factor_vm::primitive_disable_gc_events()
 {
 	if(gc_events)
 	{
-		byte_array *data = byte_array_from_values(&amp;gc_events-&gt;front(),gc_events-&gt;size());
-		dpush(tag&lt;byte_array&gt;(data));
+		growable_array result(this);
 
-		delete gc_events;
-		gc_events = NULL;
+		std::vector&lt;gc_event&gt; *gc_events = this-&gt;gc_events;
+		this-&gt;gc_events = NULL;
+
+		std::vector&lt;gc_event&gt;::const_iterator iter = gc_events-&gt;begin();
+		std::vector&lt;gc_event&gt;::const_iterator end = gc_events-&gt;end();
+
+		for(; iter != end; iter++)
+		{
+			gc_event event = *iter;
+			byte_array *obj = byte_array_from_value(&amp;event);
+			result.add(tag&lt;byte_array&gt;(obj));
+		}
+
+		result.trim();
+		dpush(result.elements.value());
+
+		delete this-&gt;gc_events;
 	}
 	else
 		dpush(false_object);</diff>
      <filename>vm/gc.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>@@ -157,9 +157,10 @@ string* factor_vm::reallot_string(string *str_, cell capacity)
 
 void factor_vm::primitive_resize_string()
 {
-	string* str = untag_check&lt;string&gt;(dpop());
+	data_root&lt;string&gt; str(dpop(),this);
+	str.untag_check(this);
 	cell capacity = unbox_array_size();
-	dpush(tag&lt;string&gt;(reallot_string(str,capacity)));
+	dpush(tag&lt;string&gt;(reallot_string(str.untagged(),capacity)));
 }
 
 void factor_vm::primitive_string_nth()</diff>
      <filename>vm/strings.cpp</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();
@@ -374,7 +379,6 @@ struct factor_vm
 	void primitive_resize_byte_array();
 
 	template&lt;typename Type&gt; byte_array *byte_array_from_value(Type *value);
-	template&lt;typename Type&gt; byte_array *byte_array_from_values(Type *values, cell len);
 
 	//tuples
 	void primitive_tuple();
@@ -586,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>995952389b2668fe0ab5a1d06ccd14f2340c1f7f</id>
    </parent>
    <parent>
      <id>1e47c40eb7c063ce3edc4a7438b73f955e0e22a6</id>
    </parent>
  </parents>
  <author>
    <name>Doug Coleman</name>
    <email>doug.coleman@gmail.com</email>
  </author>
  <url>http://github.com/slavapestov/factor/commit/b2a1fcf2676048b3b088db2a5f84080e43a678dd</url>
  <id>b2a1fcf2676048b3b088db2a5f84080e43a678dd</id>
  <committed-date>2009-11-12T01:01:21-08:00</committed-date>
  <authored-date>2009-11-12T01:01:21-08:00</authored-date>
  <message>Merge branch 'master' of git://factorcode.org/git/factor</message>
  <tree>1d6235c1f153187bcfacced61e32e1e11a83504f</tree>
  <committer>
    <name>Doug Coleman</name>
    <email>doug.coleman@gmail.com</email>
  </committer>
</commit>
