Пример #1
0
/* classes.tuple uses this to reshape tuples; tools.deploy.shaker uses this
   to coalesce equal but distinct quotations and wrappers. */
void factor_vm::primitive_become()
{
	array *new_objects = untag_check<array>(ctx->pop());
	array *old_objects = untag_check<array>(ctx->pop());

	cell capacity = array_capacity(new_objects);
	if(capacity != array_capacity(old_objects))
		critical_error("bad parameters to become",0);

	/* Build the forwarding map */
	std::map<object *,object *> become_map;

	for(cell i = 0; i < capacity; i++)
	{
		tagged<object> old_obj(array_nth(old_objects,i));
		tagged<object> new_obj(array_nth(new_objects,i));

		if(old_obj != new_obj)
			become_map[old_obj.untagged()] = new_obj.untagged();
	}

	/* Update all references to old objects to point to new objects */
	{
		slot_visitor<slot_become_fixup> workhorse(this,slot_become_fixup(&become_map));
		workhorse.visit_roots();
		workhorse.visit_contexts();

		object_become_visitor object_visitor(&workhorse);
		each_object(object_visitor);

		code_block_become_visitor code_block_visitor(&workhorse);
		each_code_block(code_block_visitor);
	}

	/* Since we may have introduced old->new references, need to revisit
	all objects and code blocks on a minor GC. */
	data->mark_all_cards();

	{
		code_block_write_barrier_visitor code_block_visitor(code);
		each_code_block(code_block_visitor);
	}
}
Пример #2
0
// classes.tuple uses this to reshape tuples; tools.deploy.shaker uses this
// to coalesce equal but distinct quotations and wrappers.
// Calls gc
void factor_vm::primitive_become() {
  primitive_minor_gc();
  array* new_objects = untag_check<array>(ctx->pop());
  array* old_objects = untag_check<array>(ctx->pop());

  cell capacity = array_capacity(new_objects);
  if (capacity != array_capacity(old_objects))
    critical_error("bad parameters to become", 0);

  // Build the forwarding map
  std::map<object*, object*> become_map;

  for (cell i = 0; i < capacity; i++) {
    cell old_ptr = array_nth(old_objects, i);
    cell new_ptr = array_nth(new_objects, i);
    if (old_ptr != new_ptr)
      become_map[untag<object>(old_ptr)] = untag<object>(new_ptr);
  }

  // Update all references to old objects to point to new objects
  {
    slot_visitor<slot_become_fixup> visitor(this,
                                            slot_become_fixup(&become_map));
    visitor.visit_all_roots();

    auto object_become_func = [&](object* obj) {
      visitor.visit_slots(obj);
    };
    each_object(object_become_func);

    auto code_block_become_func = [&](code_block* compiled, cell size) {
      visitor.visit_code_block_objects(compiled);
      visitor.visit_embedded_literals(compiled);
      code->write_barrier(compiled);
    };
    each_code_block(code_block_become_func);
  }

  // Since we may have introduced old->new references, need to revisit
  // all objects and code blocks on a minor GC.
  data->mark_all_cards();
}