Beispiel #1
0
// Allocates memory
inline object* factor_vm::allot_object(cell type, cell size) {
  FACTOR_ASSERT(!current_gc);

  bump_allocator *nursery = data->nursery;

  // If the object is bigger than the nursery, allocate it in tenured space
  if (size >= nursery->size)
    return allot_large_object(type, size);

  // If the object is smaller than the nursery, allocate it in the nursery,
  // after a GC if needed
  if (nursery->here + size > nursery->end)
    primitive_minor_gc();

  object* obj = nursery->allot(size);
  obj->initialize(type);
  return obj;
}
Beispiel #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();
}
Beispiel #3
0
/* Allocates memory */
inline object* factor_vm::allot_object(cell type, cell size) {
  FACTOR_ASSERT(!current_gc);

  bump_allocator *nursery = data->nursery;
  /* If the object is smaller than the nursery, allocate it in the nursery,
     after a GC if needed */
  if (nursery->size > size) {
    /* If there is insufficient room, collect the nursery */
    if (nursery->here + size > nursery->end)
      primitive_minor_gc();

    object* obj = nursery->allot(size);

    obj->initialize(type);
    return obj;
  } /* If the object is bigger than the nursery, allocate it in
       tenured space */
  else
    return allot_large_object(type, size);
}
Beispiel #4
0
void factor_vm::inline_gc(cell *data_roots_base, cell data_roots_size)
{
	data_roots.push_back(data_root_range(data_roots_base,data_roots_size));
	primitive_minor_gc();
	data_roots.pop_back();
}