void
Obj_space_virt<SPACE>::caps_free()
{
  Mem_space *ms = SPACE::mem_space(this);
  if (EXPECT_FALSE(!ms || !ms->dir()))
    return;

  Kmem_alloc *a = Kmem_alloc::allocator();
  for (Cap_index i = Cap_index(0); i < obj_map_max_address();
       i += Cap_diff(Obj::Caps_per_page))
    {
      Entry *c = get_cap(i);
      if (!c)
	continue;

      Address cp = Address(ms->virt_to_phys(Address(c)));
      assert_kdb (cp != ~0UL);
      void *cv = (void*)Mem_layout::phys_to_pmem(cp);
      Obj::remove_cap_page_dbg_info(cv);

      a->q_unaligned_free(SPACE::ram_quota(this), Config::PAGE_SIZE, cv);
    }
  ms->dir()->destroy(Virt_addr(Mem_layout::Caps_start),
                     Virt_addr(Mem_layout::Caps_end-1),
                     Pdir::Super_level,
                     Pdir::Depth,
                     Kmem_alloc::q_allocator(SPACE::ram_quota(this)));
}
void
Generic_obj_space<SPACE>::caps_free()
{
  Mem_space *ms = mem_space();
  if (EXPECT_FALSE(!ms || !ms->dir()))
    return;

  Mapped_allocator *a = Mapped_allocator::allocator();
  for (unsigned long i = 0; i < map_max_address().value();
       i += Caps_per_page)
    {
      Entry *c = get_cap(i);
      if (!c)
	continue;

      Address cp = Address(ms->virt_to_phys(Address(c)));
      assert_kdb (cp != ~0UL);
      void *cv = (void*)Mem_layout::phys_to_pmem(cp);
      remove_dbg_info(cv);

      a->q_unaligned_free(ram_quota(), Config::PAGE_SIZE, cv);
    }
#if defined (CONFIG_ARM)
  ms->dir()->free_page_tables((void*)Mem_layout::Caps_start, (void*)Mem_layout::Caps_end);
#else
  ms->dir()->Pdir::alloc_cast<Mem_space_q_alloc>()
    ->destroy(Virt_addr(Mem_layout::Caps_start),
              Virt_addr(Mem_layout::Caps_end), Pdir::Depth - 1,
              Mem_space_q_alloc(ram_quota(), Mapped_allocator::allocator()));
#endif
}