GC_push_finalizer_structures ()
{
  GC_push_all (&GC_ll_hashtbl.head, &MEM[(void *)&GC_ll_hashtbl + 4B]);
  GC_push_all (&GC_dl_hashtbl.head, &MEM[(void *)&GC_dl_hashtbl + 4B]);
  GC_push_all (&fo_head, &MEM[(void *)&fo_head + 4B]);
  GC_push_all (&GC_finalize_now, &MEM[(void *)&GC_finalize_now + 4B]);
}


GC_grow_table (struct hash_chain_entry * * * table, signed_word * log_size_ptr)
{
  word iftmp.0;
  int D.4739;
  int D.4741;
  unsigned int D.4742;
  struct hash_chain_entry * * D.4748;
  long unsigned int D.4749;
  struct hash_chain_entry * * D.4750;
  long unsigned int D.4751;
  long unsigned int D.4752;
  long unsigned int real_key.1;
  long unsigned int D.4754;
  int D.4755;
  long unsigned int D.4756;
  long unsigned int D.4757;
  long unsigned int D.4758;
  long unsigned int D.4759;
  unsigned int new_hash.2;
  unsigned int D.4761;
  struct hash_chain_entry * * D.4762;
  struct hash_chain_entry * D.4763;
  register word i;
  register struct hash_chain_entry * p;
  int log_old_size;
  register int log_new_size;
  word old_size;
  register word new_size;
  struct hash_chain_entry * * new_table;

  log_old_size = *log_size_ptr;
  log_new_size = log_old_size + 1;
  if (log_old_size != -1) goto <D.4737>; else goto <D.4738>;
  <D.4737>:
  D.4739 = 1 << log_old_size;
  iftmp.0 = (word) D.4739;
  goto <D.4740>;
  <D.4738>:
  iftmp.0 = 0;
  <D.4740>:
  old_size = iftmp.0;
  D.4741 = 1 << log_new_size;
  new_size = (word) D.4741;
  D.4742 = new_size * 4;
  new_table = GC_generic_malloc_inner_ignore_off_page (D.4742, 1);
  if (new_table == 0B) goto <D.4743>; else goto <D.4744>;
  <D.4743>:
  if (table == 0B) goto <D.4745>; else goto <D.4746>;
  <D.4745>:
  GC_abort ("Insufficient space for initial table allocation");
  goto <D.4747>;
  <D.4746>:
  return;
  <D.4747>:
  <D.4744>:
  i = 0;
  goto <D.4487>;
  <D.4486>:
  D.4748 = *table;
  D.4749 = i * 4;
  D.4750 = D.4748 + D.4749;
  p = *D.4750;
  goto <D.4484>;
  <D.4483>:
  {
    register char * real_key;
    register struct hash_chain_entry * next;
    register int new_hash;

    D.4751 = p->hidden_key;
    D.4752 = ~D.4751;
    real_key = (char *) D.4752;
    next = p->next;
    real_key.1 = (long unsigned int) real_key;
    D.4754 = real_key.1 >> 3;
    real_key.1 = (long unsigned int) real_key;
    D.4755 = log_new_size + 3;
    D.4756 = real_key.1 >> D.4755;
    D.4757 = D.4754 ^ D.4756;
    D.4758 = new_size + 4294967295;
    D.4759 = D.4757 & D.4758;
    new_hash = (int) D.4759;
    new_hash.2 = (unsigned int) new_hash;
    D.4761 = new_hash.2 * 4;
    D.4762 = new_table + D.4761;
    D.4763 = *D.4762;
    p->next = D.4763;
    new_hash.2 = (unsigned int) new_hash;
    D.4761 = new_hash.2 * 4;
    D.4762 = new_table + D.4761;
    *D.4762 = p;
    p = next;
  }
  <D.4484>:
  if (p != 0B) goto <D.4483>; else goto <D.4485>;
  <D.4485>:
  i = i + 1;
  <D.4487>:
  if (i < old_size) goto <D.4486>; else goto <D.4488>;
  <D.4488>:
  *log_size_ptr = log_new_size;
  *table = new_table;
}


GC_register_disappearing_link (void * * link)
{
  int D.4767;
  char * base;

  base = GC_base (link);
  if (base == 0B) goto <D.4765>; else goto <D.4766>;
  <D.4765>:
  GC_abort ("Bad arg to GC_register_disappearing_link");
  <D.4766>:
  D.4767 = GC_general_register_disappearing_link (link, base);
  return D.4767;
}


GC_general_register_disappearing_link (void * * link, void * obj)
{
  int D.4769;

  D.4769 = GC_register_disappearing_link_inner (&GC_dl_hashtbl, link, obj);
  return D.4769;
}


GC_register_disappearing_link_inner (struct dl_hashtbl_s * dl_hashtbl, void * * link, void * obj)
{
  long unsigned int link.3;
  long unsigned int D.4772;
  int D.4775;
  long int D.4780;
  long unsigned int D.4782;
  long unsigned int D.4783;
  struct disappearing_link * * * D.4784;
  signed_word * D.4785;
  int GC_print_stats.4;
  int D.4789;
  long unsigned int D.4790;
  long int D.4791;
  long unsigned int D.4792;
  long unsigned int D.4793;
  int D.4794;
  long unsigned int D.4795;
  long unsigned int D.4796;
  struct disappearing_link * * D.4797;
  unsigned int index.5;
  unsigned int D.4799;
  struct disappearing_link * * D.4800;
  long unsigned int D.4801;
  long unsigned int D.4802;
  long unsigned int obj.6;
  long unsigned int D.4806;
  int D.4807;
  void * (*<T2ab>) (size_t) GC_oom_fn.7;
  unsigned int GC_finalization_failures.8;
  unsigned int GC_finalization_failures.9;
  int D.4815;
  struct disappearing_link * D.4818;
  long unsigned int D.4819;
  struct disappearing_link * curr_dl;
  int index;
  struct disappearing_link * new_dl;

  link.3 = (long unsigned int) link;
  D.4772 = link.3 & 3;
  if (D.4772 != 0) goto <D.4773>; else goto <D.4774>;
  <D.4773>:
  GC_abort ("Bad arg to GC_general_register_disappearing_link");
  <D.4774>:
  D.4775 = _test_and_set (&GC_allocate_lock, 1);
  if (D.4775 != 0) goto <D.4776>; else goto <D.4777>;
  <D.4776>:
  GC_lock ();
  <D.4777>:
  D.4780 = dl_hashtbl->log_size;
  if (D.4780 == -1) goto <D.4778>; else goto <D.4781>;
  <D.4781>:
  D.4782 = dl_hashtbl->entries;
  D.4780 = dl_hashtbl->log_size;
  D.4783 = 1 << D.4780;
  if (D.4782 > D.4783) goto <D.4778>; else goto <D.4779>;
  <D.4778>:
  D.4784 = &dl_hashtbl->head;
  D.4785 = &dl_hashtbl->log_size;
  GC_grow_table (D.4784, D.4785);
  GC_print_stats.4 = GC_print_stats;
  if (GC_print_stats.4 != 0) goto <D.4787>; else goto <D.4788>;
  <D.4787>:
  D.4780 = dl_hashtbl->log_size;
  D.4789 = 1 << D.4780;
  GC_printf ("Grew dl table to %lu entries\n", D.4789, 0, 0, 0, 0, 0);
  <D.4788>:
  <D.4779>:
  link.3 = (long unsigned int) link;
  D.4790 = link.3 >> 3;
  link.3 = (long unsigned int) link;
  D.4780 = dl_hashtbl->log_size;
  D.4791 = D.4780 + 3;
  D.4792 = link.3 >> D.4791;
  D.4793 = D.4790 ^ D.4792;
  D.4780 = dl_hashtbl->log_size;
  D.4789 = 1 << D.4780;
  D.4794 = D.4789 + -1;
  D.4795 = (long unsigned int) D.4794;
  D.4796 = D.4793 & D.4795;
  index = (int) D.4796;
  D.4797 = dl_hashtbl->head;
  index.5 = (unsigned int) index;
  D.4799 = index.5 * 4;
  D.4800 = D.4797 + D.4799;
  curr_dl = *D.4800;
  D.4797 = dl_hashtbl->head;
  index.5 = (unsigned int) index;
  D.4799 = index.5 * 4;
  D.4800 = D.4797 + D.4799;
  curr_dl = *D.4800;
  goto <D.4506>;
  <D.4505>:
  D.4801 = curr_dl->prolog.hidden_key;
  link.3 = (long unsigned int) link;
  D.4802 = ~link.3;
  if (D.4801 == D.4802) goto <D.4803>; else goto <D.4804>;
  <D.4803>:
  obj.6 = (long unsigned int) obj;
  D.4806 = ~obj.6;
  curr_dl->dl_hidden_obj = D.4806;
  GC_clear (&GC_allocate_lock);
  D.4807 = 1;
  return D.4807;
  <D.4804>:
  curr_dl = curr_dl->prolog.next;
  <D.4506>:
  if (curr_dl != 0B) goto <D.4505>; else goto <D.4507>;
  <D.4507>:
  new_dl = GC_generic_malloc_inner (12, 1);
  if (new_dl == 0B) goto <D.4808>; else goto <D.4809>;
  <D.4808>:
  GC_clear (&GC_allocate_lock);
  GC_oom_fn.7 = GC_oom_fn;
  new_dl = GC_oom_fn.7 (12);
  if (new_dl == 0B) goto <D.4811>; else goto <D.4812>;
  <D.4811>:
  GC_finalization_failures.8 = GC_finalization_failures;
  GC_finalization_failures.9 = GC_finalization_failures.8 + 1;
  GC_finalization_failures = GC_finalization_failures.9;
  D.4807 = 0;
  return D.4807;
  <D.4812>:
  D.4815 = _test_and_set (&GC_allocate_lock, 1);
  if (D.4815 != 0) goto <D.4816>; else goto <D.4817>;
  <D.4816>:
  GC_lock ();
  <D.4817>:
  <D.4809>:
  obj.6 = (long unsigned int) obj;
  D.4806 = ~obj.6;
  new_dl->dl_hidden_obj = D.4806;
  link.3 = (long unsigned int) link;
  D.4802 = ~link.3;
  new_dl->prolog.hidden_key = D.4802;
  D.4797 = dl_hashtbl->head;
  index.5 = (unsigned int) index;
  D.4799 = index.5 * 4;
  D.4800 = D.4797 + D.4799;
  D.4818 = *D.4800;
  new_dl->prolog.next = D.4818;
  D.4797 = dl_hashtbl->head;
  index.5 = (unsigned int) index;
  D.4799 = index.5 * 4;
  D.4800 = D.4797 + D.4799;
  *D.4800 = new_dl;
  D.4782 = dl_hashtbl->entries;
  D.4819 = D.4782 + 1;
  dl_hashtbl->entries = D.4819;
  GC_clear (&GC_allocate_lock);
  D.4807 = 0;
  return D.4807;
}


_test_and_set (int * __p, int __v)
{
  int D.4821;
  int __r;
  int __t;

  __asm__ __volatile__("/* Inline test and set */
.set	push
	.set	mips2
	sync
	1:
	ll	%0,%3
	move	%1,%4
	beq	%0,%4,2f
	sc	%1,%2
	beqz	%1,1b
sync
	.set	pop
	2:
	/* End test and set */" : "=&r" __r, "=&r" __t, "=m" *__p : "m" *__p, "r" __v : "memory");
  D.4821 = __r;
  return D.4821;
}


GC_clear (volatile unsigned int * addr)
{
  __asm__ __volatile__(" " :  :  : "memory");
  *addr = 0;
}


GC_unregister_disappearing_link (void * * link)
{
  int D.4823;

  D.4823 = GC_unregister_disappearing_link_inner (&GC_dl_hashtbl, link);
  return D.4823;
}


GC_unregister_disappearing_link_inner (struct dl_hashtbl_s * dl_hashtbl, void * * link)
{
  int D.4825;
  long unsigned int link.10;
  long unsigned int D.4829;
  long int D.4830;
  long int D.4831;
  long unsigned int D.4832;
  long unsigned int D.4833;
  int D.4834;
  int D.4835;
  long unsigned int D.4836;
  long unsigned int D.4837;
  long unsigned int D.4838;
  struct disappearing_link * * D.4840;
  unsigned int index.11;
  unsigned int D.4842;
  struct disappearing_link * * D.4843;
  long unsigned int D.4844;
  long unsigned int D.4845;
  struct hash_chain_entry * D.4850;
  long unsigned int D.4852;
  long unsigned int D.4853;
  int D.4854;
  struct disappearing_link * curr_dl;
  struct disappearing_link * prev_dl;
  int index;
  void out = <<< error >>>;

  D.4825 = _test_and_set (&GC_allocate_lock, 1);
  if (D.4825 != 0) goto <D.4826>; else goto <D.4827>;
  <D.4826>:
  GC_lock ();
  <D.4827>:
  link.10 = (long unsigned int) link;
  D.4829 = link.10 >> 3;
  link.10 = (long unsigned int) link;
  D.4830 = dl_hashtbl->log_size;
  D.4831 = D.4830 + 3;
  D.4832 = link.10 >> D.4831;
  D.4833 = D.4829 ^ D.4832;
  D.4830 = dl_hashtbl->log_size;
  D.4834 = 1 << D.4830;
  D.4835 = D.4834 + -1;
  D.4836 = (long unsigned int) D.4835;
  D.4837 = D.4833 & D.4836;
  index = (int) D.4837;
  link.10 = (long unsigned int) link;
  D.4838 = link.10 & 3;
  if (D.4838 != 0) goto out; else goto <D.4839>;
  <D.4839>:
  prev_dl = 0B;
  D.4840 = dl_hashtbl->head;
  index.11 = (unsigned int) index;
  D.4842 = index.11 * 4;
  D.4843 = D.4840 + D.4842;
  curr_dl = *D.4843;
  goto <D.4520>;
  <D.4519>:
  D.4844 = curr_dl->prolog.hidden_key;
  link.10 = (long unsigned int) link;
  D.4845 = ~link.10;
  if (D.4844 == D.4845) goto <D.4846>; else goto <D.4847>;
  <D.4846>:
  if (prev_dl == 0B) goto <D.4848>; else goto <D.4849>;
  <D.4848>:
  D.4840 = dl_hashtbl->head;
  index.11 = (unsigned int) index;
  D.4842 = index.11 * 4;
  D.4843 = D.4840 + D.4842;
  D.4850 = curr_dl->prolog.next;
  *D.4843 = D.4850;
  goto <D.4851>;
  <D.4849>:
  D.4850 = curr_dl->prolog.next;
  prev_dl->prolog.next = D.4850;
  <D.4851>:
  D.4852 = dl_hashtbl->entries;
  D.4853 = D.4852 + 4294967295;
  dl_hashtbl->entries = D.4853;
  GC_clear (&GC_allocate_lock);
  GC_free (curr_dl);
  D.4854 = 1;
  return D.4854;
  <D.4847>:
  prev_dl = curr_dl;
  curr_dl = curr_dl->prolog.next;
  <D.4520>:
  if (curr_dl != 0B) goto <D.4519>; else goto <D.4521>;
  <D.4521>:
  out:
  GC_clear (&GC_allocate_lock);
  D.4854 = 0;
  return D.4854;
}


GC_register_long_link (void * * link, void * obj)
{
  int D.4856;

  D.4856 = GC_register_disappearing_link_inner (&GC_ll_hashtbl, link, obj);
  return D.4856;
}


GC_unregister_long_link (void * * link)
{
  int D.4858;

  D.4858 = GC_unregister_disappearing_link_inner (&GC_ll_hashtbl, link);
  return D.4858;
}


GC_normal_finalize_mark_proc (char * p)
{
  long unsigned int p.12;
  long unsigned int D.4861;
  struct bottom_index * D.4862;
  long unsigned int D.4863;
  long unsigned int D.4864;
  struct mse * GC_mark_stack_top.13;
  struct mse * GC_mark_stack_top.14;
  struct mse * GC_mark_stack.15;
  long unsigned int GC_mark_stack_size.16;
  long unsigned int D.4872;
  struct mse * D.4873;
  struct mse * GC_mark_stack_top.17;
  struct hdr * hhdr;

  p.12 = (long unsigned int) p;
  D.4861 = p.12 >> 22;
  D.4862 = GC_arrays._top_index[D.4861];
  p.12 = (long unsigned int) p;
  D.4863 = p.12 >> 12;
  D.4864 = D.4863 & 1023;
  hhdr = D.4862->index[D.4864];
  {
    register word _descr;

    _descr = hhdr->hb_descr;
    if (_descr == 0) goto <D.4865>; else goto <D.4866>;
    <D.4865>:
    goto <D.4867>;
    <D.4866>:
    GC_mark_stack_top.13 = GC_mark_stack_top;
    GC_mark_stack_top.14 = GC_mark_stack_top.13 + 8;
    GC_mark_stack_top = GC_mark_stack_top.14;
    GC_mark_stack.15 = GC_mark_stack;
    GC_mark_stack_size.16 = GC_mark_stack_size;
    D.4872 = GC_mark_stack_size.16 * 8;
    D.4873 = GC_mark_stack.15 + D.4872;
    GC_mark_stack_top.13 = GC_mark_stack_top;
    if (D.4873 <= GC_mark_stack_top.13) goto <D.4874>; else goto <D.4875>;
    <D.4874>:
    GC_mark_stack_top.13 = GC_mark_stack_top;
    GC_mark_stack_top.17 = GC_signal_mark_stack_overflow (GC_mark_stack_top.13);
    GC_mark_stack_top = GC_mark_stack_top.17;
    <D.4875>:
    GC_mark_stack_top.13 = GC_mark_stack_top;
    GC_mark_stack_top.13->mse_start = p;
    GC_mark_stack_top.13 = GC_mark_stack_top;
    GC_mark_stack_top.13->mse_descr = _descr;
    <D.4867>:
  }
}


GC_ignore_self_finalize_mark_proc (char * p)
{
  long unsigned int p.18;
  long unsigned int D.4878;
  struct bottom_index * D.4879;
  long unsigned int D.4880;
  long unsigned int D.4881;
  long unsigned int D.4882;
  long unsigned int D.4883;
  sizetype D.4884;
  long unsigned int D.4885;
  sizetype D.4888;
  void * GC_least_plausible_heap_addr.19;
  void * GC_greatest_plausible_heap_addr.20;
  struct mse * GC_mark_stack_top.21;
  struct mse * GC_mark_stack_limit.22;
  struct GC_ms_entry * GC_mark_stack_top.23;
  struct hdr * hhdr;
  word descr;
  char * q;
  char * r;
  char * scan_limit;
  char * target_limit;

  p.18 = (long unsigned int) p;
  D.4878 = p.18 >> 22;
  D.4879 = GC_arrays._top_index[D.4878];
  p.18 = (long unsigned int) p;
  D.4880 = p.18 >> 12;
  D.4881 = D.4880 & 1023;
  hhdr = D.4879->index[D.4881];
  descr = hhdr->hb_descr;
  D.4882 = hhdr->hb_sz;
  D.4883 = D.4882 << 2;
  D.4884 = D.4883 + 4294967295;
  target_limit = p + D.4884;
  D.4885 = descr & 3;
  if (D.4885 == 0) goto <D.4886>; else goto <D.4887>;
  <D.4886>:
  D.4888 = descr + 4294967292;
  scan_limit = p + D.4888;
  goto <D.4889>;
  <D.4887>:
  scan_limit = target_limit + 4294967293;
  <D.4889>:
  q = p;
  goto <D.4544>;
  <D.4543>:
  r = MEM[(char * *)q];
  if (r < p) goto <D.4890>; else goto <D.4892>;
  <D.4892>:
  if (r > target_limit) goto <D.4890>; else goto <D.4891>;
  <D.4890>:
  GC_least_plausible_heap_addr.19 = GC_least_plausible_heap_addr;
  if (r >= GC_least_plausible_heap_addr.19) goto <D.4894>; else goto <D.4895>;
  <D.4894>:
  GC_greatest_plausible_heap_addr.20 = GC_greatest_plausible_heap_addr;
  if (r < GC_greatest_plausible_heap_addr.20) goto <D.4897>; else goto <D.4898>;
  <D.4897>:
  GC_mark_stack_top.21 = GC_mark_stack_top;
  GC_mark_stack_limit.22 = GC_mark_stack_limit;
  GC_mark_stack_top.23 = GC_mark_and_push (r, GC_mark_stack_top.21, GC_mark_stack_limit.22, q);
  GC_mark_stack_top = GC_mark_stack_top.23;
  <D.4898>:
  <D.4895>:
  <D.4891>:
  q = q + 4;
  <D.4544>:
  if (q <= scan_limit) goto <D.4543>; else goto <D.4545>;
  <D.4545>:
}


GC_null_finalize_mark_proc (char * p)
{

}


GC_register_finalizer_inner (void * obj, void (*GC_finalization_proc) (void *, void *) fn, void * cd, void (*GC_finalization_proc) (void *, void *) * ofn, void * * ocd, void (*<Tcbe>) () mp)
{
  int D.4902;
  long int log_fo_table_size.24;
  long unsigned int D.4909;
  long unsigned int GC_fo_entries.25;
  int GC_print_stats.26;
  int D.4914;
  long unsigned int base.27;
  long unsigned int D.4916;
  long int D.4917;
  long unsigned int D.4918;
  long unsigned int D.4919;
  int D.4920;
  long unsigned int D.4921;
  long unsigned int D.4922;
  struct finalizable_object * * fo_head.28;
  unsigned int index.29;
  unsigned int D.4925;
  struct finalizable_object * * D.4926;
  long unsigned int D.4927;
  long unsigned int D.4928;
  char * D.4933;
  void (*<T30f>) (void *, void *) D.4936;
  struct hash_chain_entry * D.4939;
  long unsigned int GC_fo_entries.30;
  long unsigned int D.4954;
  struct bottom_index * D.4955;
  long unsigned int D.4956;
  long unsigned int D.4957;
  void * (*<T2ab>) (size_t) GC_oom_fn.31;
  unsigned int GC_finalization_failures.32;
  unsigned int GC_finalization_failures.33;
  int D.4967;
  long unsigned int D.4970;
  struct finalizable_object * D.4971;
  long unsigned int GC_fo_entries.34;
  char * base;
  struct finalizable_object * curr_fo;
  struct finalizable_object * prev_fo;
  int index;
  struct finalizable_object * new_fo;
  struct hdr * hhdr;

  D.4902 = _test_and_set (&GC_allocate_lock, 1);
  if (D.4902 != 0) goto <D.4903>; else goto <D.4904>;
  <D.4903>:
  GC_lock ();
  <D.4904>:
  log_fo_table_size.24 = log_fo_table_size;
  if (log_fo_table_size.24 == -1) goto <D.4905>; else goto <D.4908>;
  <D.4908>:
  log_fo_table_size.24 = log_fo_table_size;
  D.4909 = 1 << log_fo_table_size.24;
  GC_fo_entries.25 = GC_fo_entries;
  if (D.4909 < GC_fo_entries.25) goto <D.4905>; else goto <D.4906>;
  <D.4905>:
  GC_grow_table (&fo_head, &log_fo_table_size);
  GC_print_stats.26 = GC_print_stats;
  if (GC_print_stats.26 != 0) goto <D.4912>; else goto <D.4913>;
  <D.4912>:
  log_fo_table_size.24 = log_fo_table_size;
  D.4914 = 1 << log_fo_table_size.24;
  GC_printf ("Grew fo table to %lu entries\n", D.4914, 0, 0, 0, 0, 0);
  <D.4913>:
  <D.4906>:
  base = obj;
  base.27 = (long unsigned int) base;
  D.4916 = base.27 >> 3;
  base.27 = (long unsigned int) base;
  log_fo_table_size.24 = log_fo_table_size;
  D.4917 = log_fo_table_size.24 + 3;
  D.4918 = base.27 >> D.4917;
  D.4919 = D.4916 ^ D.4918;
  log_fo_table_size.24 = log_fo_table_size;
  D.4914 = 1 << log_fo_table_size.24;
  D.4920 = D.4914 + -1;
  D.4921 = (long unsigned int) D.4920;
  D.4922 = D.4919 & D.4921;
  index = (int) D.4922;
  prev_fo = 0B;
  fo_head.28 = fo_head;
  index.29 = (unsigned int) index;
  D.4925 = index.29 * 4;
  D.4926 = fo_head.28 + D.4925;
  curr_fo = *D.4926;
  goto <D.4564>;
  <D.4563>:
  D.4927 = curr_fo->prolog.hidden_key;
  base.27 = (long unsigned int) base;
  D.4928 = ~base.27;
  if (D.4927 == D.4928) goto <D.4929>; else goto <D.4930>;
  <D.4929>:
  if (ocd != 0B) goto <D.4931>; else goto <D.4932>;
  <D.4931>:
  D.4933 = curr_fo->fo_client_data;
  *ocd = D.4933;
  <D.4932>:
  if (ofn != 0B) goto <D.4934>; else goto <D.4935>;
  <D.4934>:
  D.4936 = curr_fo->fo_fn;
  *ofn = D.4936;
  <D.4935>:
  if (prev_fo == 0B) goto <D.4937>; else goto <D.4938>;
  <D.4937>:
  fo_head.28 = fo_head;
  index.29 = (unsigned int) index;
  D.4925 = index.29 * 4;
  D.4926 = fo_head.28 + D.4925;
  D.4939 = curr_fo->prolog.next;
  *D.4926 = D.4939;
  goto <D.4940>;
  <D.4938>:
  D.4939 = curr_fo->prolog.next;
  prev_fo->prolog.next = D.4939;
  <D.4940>:
  if (fn == 0B) goto <D.4941>; else goto <D.4942>;
  <D.4941>:
  GC_fo_entries.25 = GC_fo_entries;
  GC_fo_entries.30 = GC_fo_entries.25 + 4294967295;
  GC_fo_entries = GC_fo_entries.30;
  goto <D.4944>;
  <D.4942>:
  curr_fo->fo_fn = fn;
  curr_fo->fo_client_data = cd;
  curr_fo->fo_mark_proc = mp;
  if (prev_fo == 0B) goto <D.4945>; else goto <D.4946>;
  <D.4945>:
  fo_head.28 = fo_head;
  index.29 = (unsigned int) index;
  D.4925 = index.29 * 4;
  D.4926 = fo_head.28 + D.4925;
  *D.4926 = curr_fo;
  goto <D.4947>;
  <D.4946>:
  prev_fo->prolog.next = curr_fo;
  <D.4947>:
  <D.4944>:
  GC_clear (&GC_allocate_lock);
  return;
  <D.4930>:
  prev_fo = curr_fo;
  curr_fo = curr_fo->prolog.next;
  <D.4564>:
  if (curr_fo != 0B) goto <D.4563>; else goto <D.4565>;
  <D.4565>:
  if (ofn != 0B) goto <D.4948>; else goto <D.4949>;
  <D.4948>:
  *ofn = 0B;
  <D.4949>:
  if (ocd != 0B) goto <D.4950>; else goto <D.4951>;
  <D.4950>:
  *ocd = 0B;
  <D.4951>:
  if (fn == 0B) goto <D.4952>; else goto <D.4953>;
  <D.4952>:
  GC_clear (&GC_allocate_lock);
  return;
  <D.4953>:
  base.27 = (long unsigned int) base;
  D.4954 = base.27 >> 22;
  D.4955 = GC_arrays._top_index[D.4954];
  base.27 = (long unsigned int) base;
  D.4956 = base.27 >> 12;
  D.4957 = D.4956 & 1023;
  hhdr = D.4955->index[D.4957];
  if (hhdr == 0B) goto <D.4958>; else goto <D.4959>;
  <D.4958>:
  GC_clear (&GC_allocate_lock);
  return;
  <D.4959>:
  new_fo = GC_generic_malloc_inner (24, 1);
  if (new_fo == 0B) goto <D.4960>; else goto <D.4961>;
  <D.4960>:
  GC_clear (&GC_allocate_lock);
  GC_oom_fn.31 = GC_oom_fn;
  new_fo = GC_oom_fn.31 (24);
  if (new_fo == 0B) goto <D.4963>; else goto <D.4964>;
  <D.4963>:
  GC_finalization_failures.32 = GC_finalization_failures;
  GC_finalization_failures.33 = GC_finalization_failures.32 + 1;
  GC_finalization_failures = GC_finalization_failures.33;
  return;
  <D.4964>:
  D.4967 = _test_and_set (&GC_allocate_lock, 1);
  if (D.4967 != 0) goto <D.4968>; else goto <D.4969>;
  <D.4968>:
  GC_lock ();
  <D.4969>:
  <D.4961>:
  base.27 = (long unsigned int) base;
  D.4928 = ~base.27;
  new_fo->prolog.hidden_key = D.4928;
  new_fo->fo_fn = fn;
  new_fo->fo_client_data = cd;
  D.4970 = hhdr->hb_sz;
  new_fo->fo_object_size = D.4970;
  new_fo->fo_mark_proc = mp;
  fo_head.28 = fo_head;
  index.29 = (unsigned int) index;
  D.4925 = index.29 * 4;
  D.4926 = fo_head.28 + D.4925;
  D.4971 = *D.4926;
  new_fo->prolog.next = D.4971;
  GC_fo_entries.25 = GC_fo_entries;
  GC_fo_entries.34 = GC_fo_entries.25 + 1;
  GC_fo_entries = GC_fo_entries.34;
  fo_head.28 = fo_head;
  index.29 = (unsigned int) index;
  D.4925 = index.29 * 4;
  D.4926 = fo_head.28 + D.4925;
  *D.4926 = new_fo;
  GC_clear (&GC_allocate_lock);
}


GC_register_finalizer (void * obj, void (*GC_finalization_proc) (void *, void *) fn, void * cd, void (*GC_finalization_proc) (void *, void *) * ofn, void * * ocd)
{
  GC_register_finalizer_inner (obj, fn, cd, ofn, ocd, GC_normal_finalize_mark_proc);
}


GC_register_finalizer_ignore_self (void * obj, void (*GC_finalization_proc) (void *, void *) fn, void * cd, void (*GC_finalization_proc) (void *, void *) * ofn, void * * ocd)
{
  GC_register_finalizer_inner (obj, fn, cd, ofn, ocd, GC_ignore_self_finalize_mark_proc);
}


GC_register_finalizer_no_order (void * obj, void (*GC_finalization_proc) (void *, void *) fn, void * cd, void (*GC_finalization_proc) (void *, void *) * ofn, void * * ocd)
{
  GC_register_finalizer_inner (obj, fn, cd, ofn, ocd, GC_null_finalize_mark_proc);
}


GC_dump_finalization ()
{
  int iftmp.35;
  long int log_fo_table_size.36;
  struct finalizable_object * * fo_head.37;
  unsigned int i.38;
  unsigned int D.4981;
  struct finalizable_object * * D.4982;
  long unsigned int D.4983;
  long unsigned int D.4984;
  long int real_ptr.39;
  struct finalizable_object * curr_fo;
  char * real_ptr;
  int fo_size;
  int i;

  log_fo_table_size.36 = log_fo_table_size;
  if (log_fo_table_size.36 != -1) goto <D.4976>; else goto <D.4977>;
  <D.4976>:
  log_fo_table_size.36 = log_fo_table_size;
  iftmp.35 = 1 << log_fo_table_size.36;
  goto <D.4978>;
  <D.4977>:
  iftmp.35 = 0;
  <D.4978>:
  fo_size = iftmp.35;
  GC_printf ("Disappearing (short) links:\n", 0, 0, 0, 0, 0, 0);
  GC_dump_finalization_links (&GC_dl_hashtbl);
  GC_printf ("Disappearing long links:\n", 0, 0, 0, 0, 0, 0);
  GC_dump_finalization_links (&GC_ll_hashtbl);
  GC_printf ("Finalizers:\n", 0, 0, 0, 0, 0, 0);
  i = 0;
  goto <D.4611>;
  <D.4610>:
  fo_head.37 = fo_head;
  i.38 = (unsigned int) i;
  D.4981 = i.38 * 4;
  D.4982 = fo_head.37 + D.4981;
  curr_fo = *D.4982;
  goto <D.4608>;
  <D.4607>:
  D.4983 = curr_fo->prolog.hidden_key;
  D.4984 = ~D.4983;
  real_ptr = (char *) D.4984;
  real_ptr.39 = (long int) real_ptr;
  GC_printf ("Finalizable object: 0x%lx\n", real_ptr.39, 0, 0, 0, 0, 0);
  curr_fo = curr_fo->prolog.next;
  <D.4608>:
  if (curr_fo != 0B) goto <D.4607>; else goto <D.4609>;
  <D.4609>:
  i = i + 1;
  <D.4611>:
  if (i < fo_size) goto <D.4610>; else goto <D.4612>;
  <D.4612>:
}


GC_dump_finalization_links (struct dl_hashtbl_s * dl_hashtbl)
{
  size_t iftmp.40;
  long int D.4987;
  int D.4990;
  struct disappearing_link * * D.4992;
  unsigned int i.41;
  unsigned int D.4994;
  struct disappearing_link * * D.4995;
  long unsigned int D.4996;
  long unsigned int D.4997;
  long unsigned int D.4998;
  long unsigned int D.4999;
  long int real_ptr.42;
  long int real_link.43;
  unsigned int i.44;
  struct disappearing_link * curr_dl;
  char * real_ptr;
  char * real_link;
  size_t dl_size;
  int i;

  D.4987 = dl_hashtbl->log_size;
  if (D.4987 != -1) goto <D.4988>; else goto <D.4989>;
  <D.4988>:
  D.4987 = dl_hashtbl->log_size;
  D.4990 = 1 << D.4987;
  iftmp.40 = (size_t) D.4990;
  goto <D.4991>;
  <D.4989>:
  iftmp.40 = 0;
  <D.4991>:
  dl_size = iftmp.40;
  i = 0;
  goto <D.4599>;
  <D.4598>:
  D.4992 = dl_hashtbl->head;
  i.41 = (unsigned int) i;
  D.4994 = i.41 * 4;
  D.4995 = D.4992 + D.4994;
  curr_dl = *D.4995;
  goto <D.4596>;
  <D.4595>:
  D.4996 = curr_dl->dl_hidden_obj;
  D.4997 = ~D.4996;
  real_ptr = (char *) D.4997;
  D.4998 = curr_dl->prolog.hidden_key;
  D.4999 = ~D.4998;
  real_link = (char *) D.4999;
  real_ptr.42 = (long int) real_ptr;
  real_link.43 = (long int) real_link;
  GC_printf ("Object: %lx, link: %lx\n", real_ptr.42, real_link.43, 0, 0, 0, 0);
  curr_dl = curr_dl->prolog.next;
  <D.4596>:
  if (curr_dl != 0B) goto <D.4595>; else goto <D.4597>;
  <D.4597>:
  i = i + 1;
  <D.4599>:
  i.44 = (unsigned int) i;
  if (i.44 < dl_size) goto <D.4598>; else goto <D.4600>;
  <D.4600>:
}


GC_finalize ()
{
  int iftmp.45;
  long int log_fo_table_size.46;
  struct finalizable_object * * fo_head.47;
  unsigned int i.48;
  unsigned int D.5010;
  struct finalizable_object * * D.5011;
  long unsigned int D.5012;
  long unsigned int D.5013;
  int D.5014;
  void (*<Tcbe>) () D.5017;
  struct mse * GC_mark_stack_top.49;
  struct mse * GC_mark_stack.50;
  long unsigned int GC_mark_stack_size.51;
  long unsigned int D.5021;
  struct mse * D.5022;
  struct mse * GC_mark_stack_top.52;
  int D.5024;
  int GC_mark_state.53;
  int D.5028;
  int D.5029;
  void (*<T32e>) (char *, GC_word) GC_current_warn_proc.54;
  long unsigned int real_ptr.55;
  int D.5034;
  int GC_java_finalization.56;
  long unsigned int GC_fo_entries.57;
  long unsigned int GC_fo_entries.58;
  struct finalizable_object * GC_finalize_now.59;
  long unsigned int D.5046;
  long unsigned int D.5047;
  int GC_all_interior_pointers.60;
  long unsigned int GC_all_interior_pointers.61;
  long unsigned int D.5050;
  long unsigned int D.5051;
  long unsigned int D.5052;
  long unsigned int D.5053;
  unsigned int GC_all_interior_pointers.62;
  unsigned int D.5055;
  unsigned int D.5056;
  long unsigned int D.5057;
  long unsigned int D.5058;
  long unsigned int D.5059;
  int D.5063;
  struct mse * GC_mark_stack_top.63;
  int D.5069;
  int D.5072;
  struct finalizable_object * curr_fo;
  struct finalizable_object * prev_fo;
  struct finalizable_object * next_fo;
  char * real_ptr;
  register int i;
  int fo_size;

  log_fo_table_size.46 = log_fo_table_size;
  if (log_fo_table_size.46 != -1) goto <D.5005>; else goto <D.5006>;
  <D.5005>:
  log_fo_table_size.46 = log_fo_table_size;
  iftmp.45 = 1 << log_fo_table_size.46;
  goto <D.5007>;
  <D.5006>:
  iftmp.45 = 0;
  <D.5007>:
  fo_size = iftmp.45;
  GC_make_disappearing_links_disappear (&GC_dl_hashtbl);
  i = 0;
  goto <D.4663>;
  <D.4662>:
  fo_head.47 = fo_head;
  i.48 = (unsigned int) i;
  D.5010 = i.48 * 4;
  D.5011 = fo_head.47 + D.5010;
  curr_fo = *D.5011;
  goto <D.4660>;
  <D.4659>:
  D.5012 = curr_fo->prolog.hidden_key;
  D.5013 = ~D.5012;
  real_ptr = (char *) D.5013;
  D.5014 = GC_is_marked (real_ptr);
  if (D.5014 == 0) goto <D.5015>; else goto <D.5016>;
  <D.5015>:
  D.5017 = curr_fo->fo_mark_proc;
  D.5017 (real_ptr);
  goto <D.4654>;
  <D.4653>:
  GC_mark_stack_top.49 = GC_mark_stack_top;
  GC_mark_stack.50 = GC_mark_stack;
  GC_mark_stack.50 = GC_mark_stack;
  GC_mark_stack_size.51 = GC_mark_stack_size;
  D.5021 = GC_mark_stack_size.51 * 8;
  D.5022 = GC_mark_stack.50 + D.5021;
  GC_mark_stack_top.52 = GC_mark_from (GC_mark_stack_top.49, GC_mark_stack.50, D.5022);
  GC_mark_stack_top = GC_mark_stack_top.52;
  <D.4654>:
  D.5024 = GC_mark_stack_empty ();
  if (D.5024 == 0) goto <D.4653>; else goto <D.4655>;
  <D.4655>:
  GC_mark_state.53 = GC_mark_state;
  if (GC_mark_state.53 != 0) goto <D.5026>; else goto <D.5027>;
  <D.5026>:
  GC_set_mark_bit (real_ptr);
  goto <D.4657>;
  <D.4656>:
  <D.4657>:
  D.5028 = GC_mark_some (0B);
  if (D.5028 == 0) goto <D.4656>; else goto <D.4658>;
  <D.4658>:
  <D.5027>:
  D.5029 = GC_is_marked (real_ptr);
  if (D.5029 != 0) goto <D.5030>; else goto <D.5031>;
  <D.5030>:
  GC_current_warn_proc.54 = GC_current_warn_proc;
  real_ptr.55 = (long unsigned int) real_ptr;
  GC_current_warn_proc.54 ("GC Warning: Finalization cycle involving %lx\n", real_ptr.55);
  <D.5031>:
  <D.5016>:
  curr_fo = curr_fo->prolog.next;
  <D.4660>:
  if (curr_fo != 0B) goto <D.4659>; else goto <D.4661>;
  <D.4661>:
  i = i + 1;
  <D.4663>:
  if (i < fo_size) goto <D.4662>; else goto <D.4664>;
  <D.4664>:
  GC_arrays._words_finalized = 0;
  i = 0;
  goto <D.4669>;
  <D.4668>:
  fo_head.47 = fo_head;
  i.48 = (unsigned int) i;
  D.5010 = i.48 * 4;
  D.5011 = fo_head.47 + D.5010;
  curr_fo = *D.5011;
  prev_fo = 0B;
  goto <D.4666>;
  <D.4665>:
  D.5012 = curr_fo->prolog.hidden_key;
  D.5013 = ~D.5012;
  real_ptr = (char *) D.5013;
  D.5034 = GC_is_marked (real_ptr);
  if (D.5034 == 0) goto <D.5035>; else goto <D.5036>;
  <D.5035>:
  GC_java_finalization.56 = GC_java_finalization;
  if (GC_java_finalization.56 == 0) goto <D.5038>; else goto <D.5039>;
  <D.5038>:
  GC_set_mark_bit (real_ptr);
  <D.5039>:
  next_fo = curr_fo->prolog.next;
  if (prev_fo == 0B) goto <D.5040>; else goto <D.5041>;
  <D.5040>:
  fo_head.47 = fo_head;
  i.48 = (unsigned int) i;
  D.5010 = i.48 * 4;
  D.5011 = fo_head.47 + D.5010;
  *D.5011 = next_fo;
  goto <D.5042>;
  <D.5041>:
  prev_fo->prolog.next = next_fo;
  <D.5042>:
  GC_fo_entries.57 = GC_fo_entries;
  GC_fo_entries.58 = GC_fo_entries.57 + 4294967295;
  GC_fo_entries = GC_fo_entries.58;
  GC_finalize_now.59 = GC_finalize_now;
  curr_fo->prolog.next = GC_finalize_now.59;
  GC_finalize_now = curr_fo;
  D.5012 = curr_fo->prolog.hidden_key;
  D.5013 = ~D.5012;
  curr_fo->prolog.hidden_key = D.5013;
  D.5046 = GC_arrays._words_finalized;
  D.5047 = curr_fo->fo_object_size;
  GC_all_interior_pointers.60 = GC_all_interior_pointers;
  GC_all_interior_pointers.61 = (long unsigned int) GC_all_interior_pointers.60;
  D.5050 = D.5047 + GC_all_interior_pointers.61;
  D.5051 = D.5050 + 7;
  D.5052 = D.5051 >> 2;
  D.5053 = D.5052 & 4294967294;
  GC_all_interior_pointers.60 = GC_all_interior_pointers;
  GC_all_interior_pointers.62 = (unsigned int) GC_all_interior_pointers.60;
  D.5055 = GC_all_interior_pointers.62 + 31;
  D.5056 = D.5055 >> 2;
  D.5057 = D.5056 & 4294967294;
  D.5058 = D.5053 + D.5057;
  D.5059 = D.5046 + D.5058;
  GC_arrays._words_finalized = D.5059;
  curr_fo = next_fo;
  goto <D.5060>;
  <D.5036>:
  prev_fo = curr_fo;
  curr_fo = curr_fo->prolog.next;
  <D.5060>:
  <D.4666>:
  if (curr_fo != 0B) goto <D.4665>; else goto <D.4667>;
  <D.4667>:
  i = i + 1;
  <D.4669>:
  if (i < fo_size) goto <D.4668>; else goto <D.4670>;
  <D.4670>:
  GC_java_finalization.56 = GC_java_finalization;
  if (GC_java_finalization.56 != 0) goto <D.5061>; else goto <D.5062>;
  <D.5061>:
  curr_fo = GC_finalize_now;
  goto <D.4678>;
  <D.4677>:
  D.5012 = curr_fo->prolog.hidden_key;
  real_ptr = (char *) D.5012;
  D.5063 = GC_is_marked (real_ptr);
  if (D.5063 == 0) goto <D.5064>; else goto <D.5065>;
  <D.5064>:
  D.5017 = curr_fo->fo_mark_proc;
  if (D.5017 == GC_null_finalize_mark_proc) goto <D.5066>; else goto <D.5067>;
  <D.5066>:
  GC_normal_finalize_mark_proc (real_ptr);
  goto <D.4672>;
  <D.4671>:
  GC_mark_stack_top.49 = GC_mark_stack_top;
  GC_mark_stack.50 = GC_mark_stack;
  GC_mark_stack.50 = GC_mark_stack;
  GC_mark_stack_size.51 = GC_mark_stack_size;
  D.5021 = GC_mark_stack_size.51 * 8;
  D.5022 = GC_mark_stack.50 + D.5021;
  GC_mark_stack_top.63 = GC_mark_from (GC_mark_stack_top.49, GC_mark_stack.50, D.5022);
  GC_mark_stack_top = GC_mark_stack_top.63;
  <D.4672>:
  D.5069 = GC_mark_stack_empty ();
  if (D.5069 == 0) goto <D.4671>; else goto <D.4673>;
  <D.4673>:
  GC_mark_state.53 = GC_mark_state;
  if (GC_mark_state.53 != 0) goto <D.5070>; else goto <D.5071>;
  <D.5070>:
  GC_set_mark_bit (real_ptr);
  goto <D.4675>;
  <D.4674>:
  <D.4675>:
  D.5072 = GC_mark_some (0B);
  if (D.5072 == 0) goto <D.4674>; else goto <D.4676>;
  <D.4676>:
  <D.5071>:
  <D.5067>:
  GC_set_mark_bit (real_ptr);
  <D.5065>:
  curr_fo = curr_fo->prolog.next;
  <D.4678>:
  if (curr_fo != 0B) goto <D.4677>; else goto <D.4679>;
  <D.4679>:
  <D.5062>:
  GC_remove_dangling_disappearing_links (&GC_dl_hashtbl);
  GC_make_disappearing_links_disappear (&GC_ll_hashtbl);
  GC_remove_dangling_disappearing_links (&GC_ll_hashtbl);
}


GC_make_disappearing_links_disappear (struct dl_hashtbl_s * dl_hashtbl)
{
  int iftmp.64;
  long int D.5074;
  struct disappearing_link * * D.5078;
  unsigned int i.65;
  unsigned int D.5080;
  struct disappearing_link * * D.5081;
  long unsigned int D.5082;
  long unsigned int D.5083;
  long unsigned int D.5084;
  long unsigned int D.5085;
  int D.5086;
  long unsigned int D.5092;
  long unsigned int D.5093;
  struct disappearing_link * curr_dl;
  struct disappearing_link * prev_dl;
  struct disappearing_link * next_dl;
  char * real_ptr;
  char * real_link;
  register int i;
  int dl_size;

  D.5074 = dl_hashtbl->log_size;
  if (D.5074 != -1) goto <D.5075>; else goto <D.5076>;
  <D.5075>:
  D.5074 = dl_hashtbl->log_size;
  iftmp.64 = 1 << D.5074;
  goto <D.5077>;
  <D.5076>:
  iftmp.64 = 0;
  <D.5077>:
  dl_size = iftmp.64;
  i = 0;
  goto <D.4627>;
  <D.4626>:
  D.5078 = dl_hashtbl->head;
  i.65 = (unsigned int) i;
  D.5080 = i.65 * 4;
  D.5081 = D.5078 + D.5080;
  curr_dl = *D.5081;
  prev_dl = 0B;
  goto <D.4624>;
  <D.4623>:
  D.5082 = curr_dl->dl_hidden_obj;
  D.5083 = ~D.5082;
  real_ptr = (char *) D.5083;
  D.5084 = curr_dl->prolog.hidden_key;
  D.5085 = ~D.5084;
  real_link = (char *) D.5085;
  D.5086 = GC_is_marked (real_ptr);
  if (D.5086 == 0) goto <D.5087>; else goto <D.5088>;
  <D.5087>:
  MEM[(word *)real_link] = 0;
  next_dl = curr_dl->prolog.next;
  if (prev_dl == 0B) goto <D.5089>; else goto <D.5090>;
  <D.5089>:
  D.5078 = dl_hashtbl->head;
  i.65 = (unsigned int) i;
  D.5080 = i.65 * 4;
  D.5081 = D.5078 + D.5080;
  *D.5081 = next_dl;
  goto <D.5091>;
  <D.5090>:
  prev_dl->prolog.next = next_dl;
  <D.5091>:
  GC_clear_mark_bit (curr_dl);
  D.5092 = dl_hashtbl->entries;
  D.5093 = D.5092 + 4294967295;
  dl_hashtbl->entries = D.5093;
  curr_dl = next_dl;
  goto <D.5094>;
  <D.5088>:
  prev_dl = curr_dl;
  curr_dl = curr_dl->prolog.next;
  <D.5094>:
  <D.4624>:
  if (curr_dl != 0B) goto <D.4623>; else goto <D.4625>;
  <D.4625>:
  i = i + 1;
  <D.4627>:
  if (i < dl_size) goto <D.4626>; else goto <D.4628>;
  <D.4628>:
}


GC_remove_dangling_disappearing_links (struct dl_hashtbl_s * dl_hashtbl)
{
  int iftmp.66;
  long int D.5096;
  struct disappearing_link * * D.5100;
  unsigned int i.67;
  unsigned int D.5102;
  struct disappearing_link * * D.5103;
  long unsigned int D.5104;
  long unsigned int D.5105;
  void * D.5106;
  int D.5110;
  long unsigned int D.5115;
  long unsigned int D.5116;
  struct disappearing_link * curr_dl;
  struct disappearing_link * prev_dl;
  struct disappearing_link * next_dl;
  char * real_ptr;
  char * real_link;
  register int i;
  int dl_size;

  D.5096 = dl_hashtbl->log_size;
  if (D.5096 != -1) goto <D.5097>; else goto <D.5098>;
  <D.5097>:
  D.5096 = dl_hashtbl->log_size;
  iftmp.66 = 1 << D.5096;
  goto <D.5099>;
  <D.5098>:
  iftmp.66 = 0;
  <D.5099>:
  dl_size = iftmp.66;
  i = 0;
  goto <D.4643>;
  <D.4642>:
  D.5100 = dl_hashtbl->head;
  i.67 = (unsigned int) i;
  D.5102 = i.67 * 4;
  D.5103 = D.5100 + D.5102;
  curr_dl = *D.5103;
  prev_dl = 0B;
  goto <D.4640>;
  <D.4639>:
  D.5104 = curr_dl->prolog.hidden_key;
  D.5105 = ~D.5104;
  D.5106 = (void *) D.5105;
  real_link = GC_base (D.5106);
  if (real_link != 0B) goto <D.5109>; else goto <D.5107>;
  <D.5109>:
  D.5110 = GC_is_marked (real_link);
  if (D.5110 == 0) goto <D.5111>; else goto <D.5107>;
  <D.5111>:
  next_dl = curr_dl->prolog.next;
  if (prev_dl == 0B) goto <D.5112>; else goto <D.5113>;
  <D.5112>:
  D.5100 = dl_hashtbl->head;
  i.67 = (unsigned int) i;
  D.5102 = i.67 * 4;
  D.5103 = D.5100 + D.5102;
  *D.5103 = next_dl;
  goto <D.5114>;
  <D.5113>:
  prev_dl->prolog.next = next_dl;
  <D.5114>:
  GC_clear_mark_bit (curr_dl);
  D.5115 = dl_hashtbl->entries;
  D.5116 = D.5115 + 4294967295;
  dl_hashtbl->entries = D.5116;
  curr_dl = next_dl;
  goto <D.5108>;
  <D.5107>:
  prev_dl = curr_dl;
  curr_dl = curr_dl->prolog.next;
  <D.5108>:
  <D.4640>:
  if (curr_dl != 0B) goto <D.4639>; else goto <D.4641>;
  <D.4641>:
  i = i + 1;
  <D.4643>:
  if (i < dl_size) goto <D.4642>; else goto <D.4644>;
  <D.4644>:
}


GC_enqueue_all_finalizers ()
{
  int iftmp.68;
  long int log_fo_table_size.69;
  struct finalizable_object * * fo_head.70;
  unsigned int i.71;
  unsigned int D.5124;
  struct finalizable_object * * D.5125;
  long unsigned int D.5126;
  long unsigned int D.5127;
  struct mse * GC_mark_stack_top.72;
  struct mse * GC_mark_stack.73;
  long unsigned int GC_mark_stack_size.74;
  long unsigned int D.5131;
  struct mse * D.5132;
  struct mse * GC_mark_stack_top.75;
  int D.5134;
  int GC_mark_state.76;
  int D.5138;
  long unsigned int GC_fo_entries.77;
  long unsigned int GC_fo_entries.78;
  struct finalizable_object * GC_finalize_now.79;
  long unsigned int D.5145;
  long unsigned int D.5146;
  int GC_all_interior_pointers.80;
  long unsigned int GC_all_interior_pointers.81;
  long unsigned int D.5149;
  long unsigned int D.5150;
  long unsigned int D.5151;
  long unsigned int D.5152;
  unsigned int GC_all_interior_pointers.82;
  unsigned int D.5154;
  unsigned int D.5155;
  long unsigned int D.5156;
  long unsigned int D.5157;
  long unsigned int D.5158;
  struct finalizable_object * curr_fo;
  struct finalizable_object * prev_fo;
  struct finalizable_object * next_fo;
  char * real_ptr;
  register int i;
  int fo_size;

  log_fo_table_size.69 = log_fo_table_size;
  if (log_fo_table_size.69 != -1) goto <D.5119>; else goto <D.5120>;
  <D.5119>:
  log_fo_table_size.69 = log_fo_table_size;
  iftmp.68 = 1 << log_fo_table_size.69;
  goto <D.5121>;
  <D.5120>:
  iftmp.68 = 0;
  <D.5121>:
  fo_size = iftmp.68;
  GC_arrays._words_finalized = 0;
  i = 0;
  goto <D.4698>;
  <D.4697>:
  fo_head.70 = fo_head;
  i.71 = (unsigned int) i;
  D.5124 = i.71 * 4;
  D.5125 = fo_head.70 + D.5124;
  curr_fo = *D.5125;
  prev_fo = 0B;
  goto <D.4695>;
  <D.4694>:
  D.5126 = curr_fo->prolog.hidden_key;
  D.5127 = ~D.5126;
  real_ptr = (char *) D.5127;
  GC_normal_finalize_mark_proc (real_ptr);
  goto <D.4689>;
  <D.4688>:
  GC_mark_stack_top.72 = GC_mark_stack_top;
  GC_mark_stack.73 = GC_mark_stack;
  GC_mark_stack.73 = GC_mark_stack;
  GC_mark_stack_size.74 = GC_mark_stack_size;
  D.5131 = GC_mark_stack_size.74 * 8;
  D.5132 = GC_mark_stack.73 + D.5131;
  GC_mark_stack_top.75 = GC_mark_from (GC_mark_stack_top.72, GC_mark_stack.73, D.5132);
  GC_mark_stack_top = GC_mark_stack_top.75;
  <D.4689>:
  D.5134 = GC_mark_stack_empty ();
  if (D.5134 == 0) goto <D.4688>; else goto <D.4690>;
  <D.4690>:
  GC_mark_state.76 = GC_mark_state;
  if (GC_mark_state.76 != 0) goto <D.5136>; else goto <D.5137>;
  <D.5136>:
  GC_set_mark_bit (real_ptr);
  goto <D.4692>;
  <D.4691>:
  <D.4692>:
  D.5138 = GC_mark_some (0B);
  if (D.5138 == 0) goto <D.4691>; else goto <D.4693>;
  <D.4693>:
  <D.5137>:
  GC_set_mark_bit (real_ptr);
  next_fo = curr_fo->prolog.next;
  if (prev_fo == 0B) goto <D.5139>; else goto <D.5140>;
  <D.5139>:
  fo_head.70 = fo_head;
  i.71 = (unsigned int) i;
  D.5124 = i.71 * 4;
  D.5125 = fo_head.70 + D.5124;
  *D.5125 = next_fo;
  goto <D.5141>;
  <D.5140>:
  prev_fo->prolog.next = next_fo;
  <D.5141>:
  GC_fo_entries.77 = GC_fo_entries;
  GC_fo_entries.78 = GC_fo_entries.77 + 4294967295;
  GC_fo_entries = GC_fo_entries.78;
  GC_finalize_now.79 = GC_finalize_now;
  curr_fo->prolog.next = GC_finalize_now.79;
  GC_finalize_now = curr_fo;
  D.5126 = curr_fo->prolog.hidden_key;
  D.5127 = ~D.5126;
  curr_fo->prolog.hidden_key = D.5127;
  D.5145 = GC_arrays._words_finalized;
  D.5146 = curr_fo->fo_object_size;
  GC_all_interior_pointers.80 = GC_all_interior_pointers;
  GC_all_interior_pointers.81 = (long unsigned int) GC_all_interior_pointers.80;
  D.5149 = D.5146 + GC_all_interior_pointers.81;
  D.5150 = D.5149 + 7;
  D.5151 = D.5150 >> 2;
  D.5152 = D.5151 & 4294967294;
  GC_all_interior_pointers.80 = GC_all_interior_pointers;
  GC_all_interior_pointers.82 = (unsigned int) GC_all_interior_pointers.80;
  D.5154 = GC_all_interior_pointers.82 + 31;
  D.5155 = D.5154 >> 2;
  D.5156 = D.5155 & 4294967294;
  D.5157 = D.5152 + D.5156;
  D.5158 = D.5145 + D.5157;
  GC_arrays._words_finalized = D.5158;
  curr_fo = next_fo;
  <D.4695>:
  if (curr_fo != 0B) goto <D.4694>; else goto <D.4696>;
  <D.4696>:
  i = i + 1;
  <D.4698>:
  if (i < fo_size) goto <D.4697>; else goto <D.4699>;
  <D.4699>:
  return;
}


GC_finalize_all ()
{
  int D.5160;
  int D.5163;
  long unsigned int GC_fo_entries.83;

  D.5160 = _test_and_set (&GC_allocate_lock, 1);
  if (D.5160 != 0) goto <D.5161>; else goto <D.5162>;
  <D.5161>:
  GC_lock ();
  <D.5162>:
  goto <D.4703>;
  <D.4702>:
  GC_enqueue_all_finalizers ();
  GC_clear (&GC_allocate_lock);
  GC_notify_or_invoke_finalizers ();
  D.5163 = _test_and_set (&GC_allocate_lock, 1);
  if (D.5163 != 0) goto <D.5164>; else goto <D.5165>;
  <D.5164>:
  GC_lock ();
  <D.5165>:
  <D.4703>:
  GC_fo_entries.83 = GC_fo_entries;
  if (GC_fo_entries.83 != 0) goto <D.4702>; else goto <D.4704>;
  <D.4704>:
  GC_clear (&GC_allocate_lock);
}


GC_should_invoke_finalizers ()
{
  int D.5167;
  struct finalizable_object * GC_finalize_now.84;
  _Bool D.5169;

  GC_finalize_now.84 = GC_finalize_now;
  D.5169 = GC_finalize_now.84 != 0B;
  D.5167 = (int) D.5169;
  return D.5167;
}


GC_invoke_finalizers ()
{
  int D.5171;
  struct hash_chain_entry * GC_finalize_now.85;
  void (*<T30f>) (void *, void *) D.5180;
  long unsigned int D.5181;
  void * D.5182;
  char * D.5183;
  struct finalizable_object * GC_finalize_now.86;
  long unsigned int D.5187;
  int D.5190;
  long unsigned int D.5193;
  long unsigned int D.5194;
  long unsigned int D.5195;
  int D.5196;
  struct finalizable_object * curr_fo;
  int count;
  word mem_freed_before;

  count = 0;
  goto <D.4715>;
  <D.4714>:
  D.5171 = _test_and_set (&GC_allocate_lock, 1);
  if (D.5171 != 0) goto <D.5172>; else goto <D.5173>;
  <D.5172>:
  GC_lock ();
  <D.5173>:
  if (count == 0) goto <D.5174>; else goto <D.5175>;
  <D.5174>:
  mem_freed_before = GC_arrays._mem_freed;
  <D.5175>:
  curr_fo = GC_finalize_now;
  if (curr_fo != 0B) goto <D.5176>; else goto <D.5177>;
  <D.5176>:
  GC_finalize_now.85 = curr_fo->prolog.next;
  GC_finalize_now = GC_finalize_now.85;
  <D.5177>:
  GC_clear (&GC_allocate_lock);
  if (curr_fo == 0B) goto <D.4713>; else goto <D.5179>;
  <D.5179>:
  curr_fo->prolog.next = 0B;
  D.5180 = curr_fo->fo_fn;
  D.5181 = curr_fo->prolog.hidden_key;
  D.5182 = (void *) D.5181;
  D.5183 = curr_fo->fo_client_data;
  D.5180 (D.5182, D.5183);
  curr_fo->fo_client_data = 0B;
  count = count + 1;
  <D.4715>:
  GC_finalize_now.86 = GC_finalize_now;
  if (GC_finalize_now.86 != 0B) goto <D.4714>; else goto <D.4713>;
  <D.4713>:
  if (count != 0) goto <D.5185>; else goto <D.5186>;
  <D.5185>:
  D.5187 = GC_arrays._mem_freed;
  if (D.5187 != mem_freed_before) goto <D.5188>; else goto <D.5189>;
  <D.5188>:
  D.5190 = _test_and_set (&GC_allocate_lock, 1);
  if (D.5190 != 0) goto <D.5191>; else goto <D.5192>;
  <D.5191>:
  GC_lock ();
  <D.5192>:
  D.5193 = GC_arrays._finalizer_mem_freed;
  D.5187 = GC_arrays._mem_freed;
  D.5194 = D.5187 - mem_freed_before;
  D.5195 = D.5193 + D.5194;
  GC_arrays._finalizer_mem_freed = D.5195;
  GC_clear (&GC_allocate_lock);
  <D.5189>:
  <D.5186>:
  D.5196 = count;
  return D.5196;
}


GC_notify_or_invoke_finalizers ()
{
  struct finalizable_object * GC_finalize_now.87;
  int GC_finalize_on_demand.88;
  void (*<T2b8>) (void) GC_finalizer_notifier.89;
  long unsigned int last_finalizer_notification.90;
  long unsigned int GC_gc_no.91;

  GC_finalize_now.87 = GC_finalize_now;
  if (GC_finalize_now.87 == 0B) goto <D.5199>; else goto <D.5200>;
  <D.5199>:
  return;
  <D.5200>:
  GC_finalize_on_demand.88 = GC_finalize_on_demand;
  if (GC_finalize_on_demand.88 == 0) goto <D.5202>; else goto <D.5203>;
  <D.5202>:
  GC_invoke_finalizers ();
  return;
  <D.5203>:
  GC_finalizer_notifier.89 = GC_finalizer_notifier;
  if (GC_finalizer_notifier.89 != 0B) goto <D.5205>; else goto <D.5206>;
  <D.5205>:
  last_finalizer_notification.90 = last_finalizer_notification;
  GC_gc_no.91 = GC_gc_no;
  if (last_finalizer_notification.90 != GC_gc_no.91) goto <D.5209>; else goto <D.5210>;
  <D.5209>:
  GC_gc_no.91 = GC_gc_no;
  last_finalizer_notification = GC_gc_no.91;
  GC_finalizer_notifier.89 = GC_finalizer_notifier;
  GC_finalizer_notifier.89 ();
  <D.5210>:
  <D.5206>:
}


GC_call_with_alloc_lock (void * (*GC_fn_type) (void *) fn, void * client_data)
{
  int D.5212;
  long unsigned int GC_lock_holder.92;
  void * D.5216;
  void * result;

  D.5212 = _test_and_set (&GC_allocate_lock, 1);
  if (D.5212 != 0) goto <D.5213>; else goto <D.5214>;
  <D.5213>:
  GC_lock ();
  <D.5214>:
  GC_lock_holder.92 = pthread_self ();
  GC_lock_holder = GC_lock_holder.92;
  result = fn (client_data);
  GC_lock_holder = 4294967295;
  GC_clear (&GC_allocate_lock);
  D.5216 = result;
  return D.5216;
}


GC_print_finalization_stats ()
{
  long unsigned int GC_fo_entries.93;
  long int GC_fo_entries.94;
  long unsigned int D.5220;
  long int D.5221;
  long unsigned int D.5222;
  long int D.5223;
  long int ready.95;
  struct finalizable_object * fo;
  size_t ready;

  fo = GC_finalize_now;
  ready = 0;
  GC_fo_entries.93 = GC_fo_entries;
  GC_fo_entries.94 = (long int) GC_fo_entries.93;
  D.5220 = GC_dl_hashtbl.entries;
  D.5221 = (long int) D.5220;
  D.5222 = GC_ll_hashtbl.entries;
  D.5223 = (long int) D.5222;
  GC_printf ("%lu finalization table entries; %lu/%lu short/long disappearing links alive\n", GC_fo_entries.94, D.5221, D.5223, 0, 0, 0);
  goto <D.4733>;
  <D.4732>:
  ready = ready + 1;
  fo = fo->prolog.next;
  <D.4733>:
  if (fo != 0B) goto <D.4732>; else goto <D.4734>;
  <D.4734>:
  ready.95 = (long int) ready;
  GC_printf ("%lu objects are eligible for immediate finalization\n", ready.95, 0, 0, 0, 0, 0);
}


