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.4808;
  int D.4810;
  unsigned int D.4811;
  struct hash_chain_entry * * D.4817;
  long unsigned int D.4818;
  struct hash_chain_entry * * D.4819;
  long unsigned int D.4820;
  long unsigned int D.4821;
  long unsigned int real_key.1;
  long unsigned int D.4823;
  int D.4824;
  long unsigned int D.4825;
  long unsigned int D.4826;
  long unsigned int D.4827;
  long unsigned int D.4828;
  unsigned int new_hash.2;
  unsigned int D.4830;
  struct hash_chain_entry * * D.4831;
  struct hash_chain_entry * D.4832;
  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.4806>; else goto <D.4807>;
  <D.4806>:
  D.4808 = 1 << log_old_size;
  iftmp.0 = (word) D.4808;
  goto <D.4809>;
  <D.4807>:
  iftmp.0 = 0;
  <D.4809>:
  old_size = iftmp.0;
  D.4810 = 1 << log_new_size;
  new_size = (word) D.4810;
  D.4811 = new_size * 4;
  new_table = GC_generic_malloc_inner_ignore_off_page (D.4811, 1);
  if (new_table == 0B) goto <D.4812>; else goto <D.4813>;
  <D.4812>:
  if (table == 0B) goto <D.4814>; else goto <D.4815>;
  <D.4814>:
  GC_abort ("Insufficient space for initial table allocation");
  goto <D.4816>;
  <D.4815>:
  return;
  <D.4816>:
  <D.4813>:
  i = 0;
  goto <D.4556>;
  <D.4555>:
  D.4817 = *table;
  D.4818 = i * 4;
  D.4819 = D.4817 + D.4818;
  p = *D.4819;
  goto <D.4553>;
  <D.4552>:
  {
    register char * real_key;
    register struct hash_chain_entry * next;
    register int new_hash;

    D.4820 = p->hidden_key;
    D.4821 = ~D.4820;
    real_key = (char *) D.4821;
    next = p->next;
    real_key.1 = (long unsigned int) real_key;
    D.4823 = real_key.1 >> 3;
    real_key.1 = (long unsigned int) real_key;
    D.4824 = log_new_size + 3;
    D.4825 = real_key.1 >> D.4824;
    D.4826 = D.4823 ^ D.4825;
    D.4827 = new_size + 4294967295;
    D.4828 = D.4826 & D.4827;
    new_hash = (int) D.4828;
    new_hash.2 = (unsigned int) new_hash;
    D.4830 = new_hash.2 * 4;
    D.4831 = new_table + D.4830;
    D.4832 = *D.4831;
    p->next = D.4832;
    new_hash.2 = (unsigned int) new_hash;
    D.4830 = new_hash.2 * 4;
    D.4831 = new_table + D.4830;
    *D.4831 = p;
    p = next;
  }
  <D.4553>:
  if (p != 0B) goto <D.4552>; else goto <D.4554>;
  <D.4554>:
  i = i + 1;
  <D.4556>:
  if (i < old_size) goto <D.4555>; else goto <D.4557>;
  <D.4557>:
  *log_size_ptr = log_new_size;
  *table = new_table;
}


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

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


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

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


GC_register_disappearing_link_inner (struct dl_hashtbl_s * dl_hashtbl, void * * link, void * obj)
{
  long unsigned int link.3;
  long unsigned int D.4841;
  int D.4844;
  long int D.4849;
  long unsigned int D.4851;
  long unsigned int D.4852;
  signed_word * D.4853;
  struct disappearing_link * * * D.4854;
  int GC_print_stats.4;
  int D.4858;
  long unsigned int D.4859;
  long int D.4860;
  long unsigned int D.4861;
  long unsigned int D.4862;
  int D.4863;
  long unsigned int D.4864;
  long unsigned int D.4865;
  struct disappearing_link * * D.4866;
  unsigned int index.5;
  unsigned int D.4868;
  struct disappearing_link * * D.4869;
  long unsigned int D.4870;
  long unsigned int D.4871;
  long unsigned int obj.6;
  long unsigned int D.4875;
  int D.4876;
  void * (*<T2bb>) (size_t) GC_oom_fn.7;
  unsigned int GC_finalization_failures.8;
  unsigned int GC_finalization_failures.9;
  int D.4884;
  struct disappearing_link * D.4887;
  long unsigned int D.4888;
  struct disappearing_link * curr_dl;
  int index;
  struct disappearing_link * new_dl;

  link.3 = (long unsigned int) link;
  D.4841 = link.3 & 3;
  if (D.4841 != 0) goto <D.4842>; else goto <D.4843>;
  <D.4842>:
  GC_abort ("Bad arg to GC_general_register_disappearing_link");
  <D.4843>:
  D.4844 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.4844 != 0) goto <D.4845>; else goto <D.4846>;
  <D.4845>:
  GC_lock ();
  <D.4846>:
  D.4849 = dl_hashtbl->log_size;
  if (D.4849 == -1) goto <D.4847>; else goto <D.4850>;
  <D.4850>:
  D.4851 = dl_hashtbl->entries;
  D.4849 = dl_hashtbl->log_size;
  D.4852 = 1 << D.4849;
  if (D.4851 > D.4852) goto <D.4847>; else goto <D.4848>;
  <D.4847>:
  D.4853 = &dl_hashtbl->log_size;
  D.4854 = &dl_hashtbl->head;
  GC_grow_table (D.4854, D.4853);
  GC_print_stats.4 = GC_print_stats;
  if (GC_print_stats.4 != 0) goto <D.4856>; else goto <D.4857>;
  <D.4856>:
  D.4849 = dl_hashtbl->log_size;
  D.4858 = 1 << D.4849;
  GC_printf ("Grew dl table to %lu entries\n", D.4858, 0, 0, 0, 0, 0);
  <D.4857>:
  <D.4848>:
  link.3 = (long unsigned int) link;
  D.4859 = link.3 >> 3;
  link.3 = (long unsigned int) link;
  D.4849 = dl_hashtbl->log_size;
  D.4860 = D.4849 + 3;
  D.4861 = link.3 >> D.4860;
  D.4862 = D.4859 ^ D.4861;
  D.4849 = dl_hashtbl->log_size;
  D.4858 = 1 << D.4849;
  D.4863 = D.4858 + -1;
  D.4864 = (long unsigned int) D.4863;
  D.4865 = D.4862 & D.4864;
  index = (int) D.4865;
  D.4866 = dl_hashtbl->head;
  index.5 = (unsigned int) index;
  D.4868 = index.5 * 4;
  D.4869 = D.4866 + D.4868;
  curr_dl = *D.4869;
  D.4866 = dl_hashtbl->head;
  index.5 = (unsigned int) index;
  D.4868 = index.5 * 4;
  D.4869 = D.4866 + D.4868;
  curr_dl = *D.4869;
  goto <D.4575>;
  <D.4574>:
  D.4870 = curr_dl->prolog.hidden_key;
  link.3 = (long unsigned int) link;
  D.4871 = ~link.3;
  if (D.4870 == D.4871) goto <D.4872>; else goto <D.4873>;
  <D.4872>:
  obj.6 = (long unsigned int) obj;
  D.4875 = ~obj.6;
  curr_dl->dl_hidden_obj = D.4875;
  pthread_mutex_unlock (&GC_allocate_ml);
  D.4876 = 1;
  return D.4876;
  <D.4873>:
  curr_dl = curr_dl->prolog.next;
  <D.4575>:
  if (curr_dl != 0B) goto <D.4574>; else goto <D.4576>;
  <D.4576>:
  new_dl = GC_generic_malloc_inner (12, 1);
  if (new_dl == 0B) goto <D.4877>; else goto <D.4878>;
  <D.4877>:
  pthread_mutex_unlock (&GC_allocate_ml);
  GC_oom_fn.7 = GC_oom_fn;
  new_dl = GC_oom_fn.7 (12);
  if (new_dl == 0B) goto <D.4880>; else goto <D.4881>;
  <D.4880>:
  GC_finalization_failures.8 = GC_finalization_failures;
  GC_finalization_failures.9 = GC_finalization_failures.8 + 1;
  GC_finalization_failures = GC_finalization_failures.9;
  D.4876 = 0;
  return D.4876;
  <D.4881>:
  D.4884 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.4884 != 0) goto <D.4885>; else goto <D.4886>;
  <D.4885>:
  GC_lock ();
  <D.4886>:
  <D.4878>:
  obj.6 = (long unsigned int) obj;
  D.4875 = ~obj.6;
  new_dl->dl_hidden_obj = D.4875;
  link.3 = (long unsigned int) link;
  D.4871 = ~link.3;
  new_dl->prolog.hidden_key = D.4871;
  D.4866 = dl_hashtbl->head;
  index.5 = (unsigned int) index;
  D.4868 = index.5 * 4;
  D.4869 = D.4866 + D.4868;
  D.4887 = *D.4869;
  new_dl->prolog.next = D.4887;
  D.4866 = dl_hashtbl->head;
  index.5 = (unsigned int) index;
  D.4868 = index.5 * 4;
  D.4869 = D.4866 + D.4868;
  *D.4869 = new_dl;
  D.4851 = dl_hashtbl->entries;
  D.4888 = D.4851 + 1;
  dl_hashtbl->entries = D.4888;
  pthread_mutex_unlock (&GC_allocate_ml);
  D.4876 = 0;
  return D.4876;
}


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

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


GC_unregister_disappearing_link_inner (struct dl_hashtbl_s * dl_hashtbl, void * * link)
{
  int D.4892;
  long unsigned int link.10;
  long unsigned int D.4896;
  long int D.4897;
  long int D.4898;
  long unsigned int D.4899;
  long unsigned int D.4900;
  int D.4901;
  int D.4902;
  long unsigned int D.4903;
  long unsigned int D.4904;
  long unsigned int D.4905;
  struct disappearing_link * * D.4907;
  unsigned int index.11;
  unsigned int D.4909;
  struct disappearing_link * * D.4910;
  long unsigned int D.4911;
  long unsigned int D.4912;
  struct hash_chain_entry * D.4917;
  long unsigned int D.4919;
  long unsigned int D.4920;
  int D.4921;
  struct disappearing_link * curr_dl;
  struct disappearing_link * prev_dl;
  int index;
  void out = <<< error >>>;

  D.4892 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.4892 != 0) goto <D.4893>; else goto <D.4894>;
  <D.4893>:
  GC_lock ();
  <D.4894>:
  link.10 = (long unsigned int) link;
  D.4896 = link.10 >> 3;
  link.10 = (long unsigned int) link;
  D.4897 = dl_hashtbl->log_size;
  D.4898 = D.4897 + 3;
  D.4899 = link.10 >> D.4898;
  D.4900 = D.4896 ^ D.4899;
  D.4897 = dl_hashtbl->log_size;
  D.4901 = 1 << D.4897;
  D.4902 = D.4901 + -1;
  D.4903 = (long unsigned int) D.4902;
  D.4904 = D.4900 & D.4903;
  index = (int) D.4904;
  link.10 = (long unsigned int) link;
  D.4905 = link.10 & 3;
  if (D.4905 != 0) goto out; else goto <D.4906>;
  <D.4906>:
  prev_dl = 0B;
  D.4907 = dl_hashtbl->head;
  index.11 = (unsigned int) index;
  D.4909 = index.11 * 4;
  D.4910 = D.4907 + D.4909;
  curr_dl = *D.4910;
  goto <D.4589>;
  <D.4588>:
  D.4911 = curr_dl->prolog.hidden_key;
  link.10 = (long unsigned int) link;
  D.4912 = ~link.10;
  if (D.4911 == D.4912) goto <D.4913>; else goto <D.4914>;
  <D.4913>:
  if (prev_dl == 0B) goto <D.4915>; else goto <D.4916>;
  <D.4915>:
  D.4907 = dl_hashtbl->head;
  index.11 = (unsigned int) index;
  D.4909 = index.11 * 4;
  D.4910 = D.4907 + D.4909;
  D.4917 = curr_dl->prolog.next;
  *D.4910 = D.4917;
  goto <D.4918>;
  <D.4916>:
  D.4917 = curr_dl->prolog.next;
  prev_dl->prolog.next = D.4917;
  <D.4918>:
  D.4919 = dl_hashtbl->entries;
  D.4920 = D.4919 + 4294967295;
  dl_hashtbl->entries = D.4920;
  pthread_mutex_unlock (&GC_allocate_ml);
  GC_free (curr_dl);
  D.4921 = 1;
  return D.4921;
  <D.4914>:
  prev_dl = curr_dl;
  curr_dl = curr_dl->prolog.next;
  <D.4589>:
  if (curr_dl != 0B) goto <D.4588>; else goto <D.4590>;
  <D.4590>:
  out:
  pthread_mutex_unlock (&GC_allocate_ml);
  D.4921 = 0;
  return D.4921;
}


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

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


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

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


GC_normal_finalize_mark_proc (char * p)
{
  long unsigned int p.12;
  long unsigned int D.4928;
  struct bottom_index * D.4929;
  long unsigned int D.4930;
  long unsigned int D.4931;
  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.4939;
  struct GC_ms_entry * D.4940;
  struct mse * GC_mark_stack_top.17;
  struct mse * GC_mark_stack_top.18;
  struct mse * GC_mark_stack_top.19;
  struct mse * GC_mark_stack_top.20;
  struct mse * GC_mark_stack_top.21;
  struct hdr * hhdr;

  p.12 = (long unsigned int) p;
  D.4928 = p.12 >> 22;
  D.4929 = GC_arrays._top_index[D.4928];
  p.12 = (long unsigned int) p;
  D.4930 = p.12 >> 12;
  D.4931 = D.4930 & 1023;
  hhdr = D.4929->index[D.4931];
  {
    register word _descr;

    _descr = hhdr->hb_descr;
    if (_descr == 0) goto <D.4932>; else goto <D.4933>;
    <D.4932>:
    goto <D.4934>;
    <D.4933>:
    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.4939 = GC_mark_stack_size.16 * 8;
    D.4940 = GC_mark_stack.15 + D.4939;
    GC_mark_stack_top.17 = GC_mark_stack_top;
    if (D.4940 <= GC_mark_stack_top.17) goto <D.4942>; else goto <D.4943>;
    <D.4942>:
    GC_mark_stack_top.18 = GC_mark_stack_top;
    GC_mark_stack_top.19 = GC_signal_mark_stack_overflow (GC_mark_stack_top.18);
    GC_mark_stack_top = GC_mark_stack_top.19;
    <D.4943>:
    GC_mark_stack_top.20 = GC_mark_stack_top;
    GC_mark_stack_top.20->mse_start = p;
    GC_mark_stack_top.21 = GC_mark_stack_top;
    GC_mark_stack_top.21->mse_descr = _descr;
    <D.4934>:
  }
}


GC_ignore_self_finalize_mark_proc (char * p)
{
  long unsigned int p.22;
  long unsigned int D.4949;
  struct bottom_index * D.4950;
  long unsigned int D.4951;
  long unsigned int D.4952;
  long unsigned int D.4953;
  long unsigned int D.4954;
  sizetype D.4955;
  long unsigned int D.4956;
  sizetype D.4959;
  _Bool D.4961;
  _Bool D.4962;
  _Bool D.4963;
  void * GC_least_plausible_heap_addr.23;
  void * GC_greatest_plausible_heap_addr.24;
  struct mse * GC_mark_stack_limit.25;
  struct mse * GC_mark_stack_top.26;
  struct GC_ms_entry * GC_mark_stack_top.27;
  struct hdr * hhdr;
  word descr;
  char * q;
  char * r;
  char * scan_limit;
  char * target_limit;

  p.22 = (long unsigned int) p;
  D.4949 = p.22 >> 22;
  D.4950 = GC_arrays._top_index[D.4949];
  p.22 = (long unsigned int) p;
  D.4951 = p.22 >> 12;
  D.4952 = D.4951 & 1023;
  hhdr = D.4950->index[D.4952];
  descr = hhdr->hb_descr;
  D.4953 = hhdr->hb_sz;
  D.4954 = D.4953 << 2;
  D.4955 = D.4954 + 4294967295;
  target_limit = p + D.4955;
  D.4956 = descr & 3;
  if (D.4956 == 0) goto <D.4957>; else goto <D.4958>;
  <D.4957>:
  D.4959 = descr + 4294967292;
  scan_limit = p + D.4959;
  goto <D.4960>;
  <D.4958>:
  scan_limit = target_limit + 4294967293;
  <D.4960>:
  q = p;
  goto <D.4613>;
  <D.4612>:
  r = MEM[(char * *)q];
  D.4961 = r < p;
  D.4962 = r > target_limit;
  D.4963 = D.4961 | D.4962;
  if (D.4963 != 0) goto <D.4964>; else goto <D.4965>;
  <D.4964>:
  GC_least_plausible_heap_addr.23 = GC_least_plausible_heap_addr;
  if (r >= GC_least_plausible_heap_addr.23) goto <D.4967>; else goto <D.4968>;
  <D.4967>:
  GC_greatest_plausible_heap_addr.24 = GC_greatest_plausible_heap_addr;
  if (r < GC_greatest_plausible_heap_addr.24) goto <D.4970>; else goto <D.4971>;
  <D.4970>:
  GC_mark_stack_limit.25 = GC_mark_stack_limit;
  GC_mark_stack_top.26 = GC_mark_stack_top;
  GC_mark_stack_top.27 = GC_mark_and_push (r, GC_mark_stack_top.26, GC_mark_stack_limit.25, q);
  GC_mark_stack_top = GC_mark_stack_top.27;
  <D.4971>:
  <D.4968>:
  <D.4965>:
  q = q + 4;
  <D.4613>:
  if (q <= scan_limit) goto <D.4612>; else goto <D.4614>;
  <D.4614>:
}


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 (*<Tcfc>) () mp)
{
  int D.4975;
  long int log_fo_table_size.28;
  long unsigned int D.4982;
  long unsigned int GC_fo_entries.29;
  int GC_print_stats.30;
  int D.4987;
  long unsigned int base.31;
  long unsigned int D.4989;
  long int D.4990;
  long unsigned int D.4991;
  long unsigned int D.4992;
  int D.4993;
  long unsigned int D.4994;
  long unsigned int D.4995;
  struct finalizable_object * * fo_head.32;
  unsigned int index.33;
  unsigned int D.4998;
  struct finalizable_object * * D.4999;
  long unsigned int D.5000;
  long unsigned int D.5001;
  char * D.5006;
  void (*<T31f>) (void *, void *) D.5009;
  struct hash_chain_entry * D.5012;
  long unsigned int GC_fo_entries.34;
  long unsigned int D.5027;
  struct bottom_index * D.5028;
  long unsigned int D.5029;
  long unsigned int D.5030;
  void * (*<T2bb>) (size_t) GC_oom_fn.35;
  unsigned int GC_finalization_failures.36;
  unsigned int GC_finalization_failures.37;
  int D.5040;
  long unsigned int D.5043;
  struct finalizable_object * D.5044;
  long unsigned int GC_fo_entries.38;
  char * base;
  struct finalizable_object * curr_fo;
  struct finalizable_object * prev_fo;
  int index;
  struct finalizable_object * new_fo;
  struct hdr * hhdr;

  D.4975 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.4975 != 0) goto <D.4976>; else goto <D.4977>;
  <D.4976>:
  GC_lock ();
  <D.4977>:
  log_fo_table_size.28 = log_fo_table_size;
  if (log_fo_table_size.28 == -1) goto <D.4978>; else goto <D.4981>;
  <D.4981>:
  log_fo_table_size.28 = log_fo_table_size;
  D.4982 = 1 << log_fo_table_size.28;
  GC_fo_entries.29 = GC_fo_entries;
  if (D.4982 < GC_fo_entries.29) goto <D.4978>; else goto <D.4979>;
  <D.4978>:
  GC_grow_table (&fo_head, &log_fo_table_size);
  GC_print_stats.30 = GC_print_stats;
  if (GC_print_stats.30 != 0) goto <D.4985>; else goto <D.4986>;
  <D.4985>:
  log_fo_table_size.28 = log_fo_table_size;
  D.4987 = 1 << log_fo_table_size.28;
  GC_printf ("Grew fo table to %lu entries\n", D.4987, 0, 0, 0, 0, 0);
  <D.4986>:
  <D.4979>:
  base = obj;
  base.31 = (long unsigned int) base;
  D.4989 = base.31 >> 3;
  base.31 = (long unsigned int) base;
  log_fo_table_size.28 = log_fo_table_size;
  D.4990 = log_fo_table_size.28 + 3;
  D.4991 = base.31 >> D.4990;
  D.4992 = D.4989 ^ D.4991;
  log_fo_table_size.28 = log_fo_table_size;
  D.4987 = 1 << log_fo_table_size.28;
  D.4993 = D.4987 + -1;
  D.4994 = (long unsigned int) D.4993;
  D.4995 = D.4992 & D.4994;
  index = (int) D.4995;
  prev_fo = 0B;
  fo_head.32 = fo_head;
  index.33 = (unsigned int) index;
  D.4998 = index.33 * 4;
  D.4999 = fo_head.32 + D.4998;
  curr_fo = *D.4999;
  goto <D.4633>;
  <D.4632>:
  D.5000 = curr_fo->prolog.hidden_key;
  base.31 = (long unsigned int) base;
  D.5001 = ~base.31;
  if (D.5000 == D.5001) goto <D.5002>; else goto <D.5003>;
  <D.5002>:
  if (ocd != 0B) goto <D.5004>; else goto <D.5005>;
  <D.5004>:
  D.5006 = curr_fo->fo_client_data;
  *ocd = D.5006;
  <D.5005>:
  if (ofn != 0B) goto <D.5007>; else goto <D.5008>;
  <D.5007>:
  D.5009 = curr_fo->fo_fn;
  *ofn = D.5009;
  <D.5008>:
  if (prev_fo == 0B) goto <D.5010>; else goto <D.5011>;
  <D.5010>:
  fo_head.32 = fo_head;
  index.33 = (unsigned int) index;
  D.4998 = index.33 * 4;
  D.4999 = fo_head.32 + D.4998;
  D.5012 = curr_fo->prolog.next;
  *D.4999 = D.5012;
  goto <D.5013>;
  <D.5011>:
  D.5012 = curr_fo->prolog.next;
  prev_fo->prolog.next = D.5012;
  <D.5013>:
  if (fn == 0B) goto <D.5014>; else goto <D.5015>;
  <D.5014>:
  GC_fo_entries.29 = GC_fo_entries;
  GC_fo_entries.34 = GC_fo_entries.29 + 4294967295;
  GC_fo_entries = GC_fo_entries.34;
  goto <D.5017>;
  <D.5015>:
  curr_fo->fo_fn = fn;
  curr_fo->fo_client_data = cd;
  curr_fo->fo_mark_proc = mp;
  if (prev_fo == 0B) goto <D.5018>; else goto <D.5019>;
  <D.5018>:
  fo_head.32 = fo_head;
  index.33 = (unsigned int) index;
  D.4998 = index.33 * 4;
  D.4999 = fo_head.32 + D.4998;
  *D.4999 = curr_fo;
  goto <D.5020>;
  <D.5019>:
  prev_fo->prolog.next = curr_fo;
  <D.5020>:
  <D.5017>:
  pthread_mutex_unlock (&GC_allocate_ml);
  return;
  <D.5003>:
  prev_fo = curr_fo;
  curr_fo = curr_fo->prolog.next;
  <D.4633>:
  if (curr_fo != 0B) goto <D.4632>; else goto <D.4634>;
  <D.4634>:
  if (ofn != 0B) goto <D.5021>; else goto <D.5022>;
  <D.5021>:
  *ofn = 0B;
  <D.5022>:
  if (ocd != 0B) goto <D.5023>; else goto <D.5024>;
  <D.5023>:
  *ocd = 0B;
  <D.5024>:
  if (fn == 0B) goto <D.5025>; else goto <D.5026>;
  <D.5025>:
  pthread_mutex_unlock (&GC_allocate_ml);
  return;
  <D.5026>:
  base.31 = (long unsigned int) base;
  D.5027 = base.31 >> 22;
  D.5028 = GC_arrays._top_index[D.5027];
  base.31 = (long unsigned int) base;
  D.5029 = base.31 >> 12;
  D.5030 = D.5029 & 1023;
  hhdr = D.5028->index[D.5030];
  if (hhdr == 0B) goto <D.5031>; else goto <D.5032>;
  <D.5031>:
  pthread_mutex_unlock (&GC_allocate_ml);
  return;
  <D.5032>:
  new_fo = GC_generic_malloc_inner (24, 1);
  if (new_fo == 0B) goto <D.5033>; else goto <D.5034>;
  <D.5033>:
  pthread_mutex_unlock (&GC_allocate_ml);
  GC_oom_fn.35 = GC_oom_fn;
  new_fo = GC_oom_fn.35 (24);
  if (new_fo == 0B) goto <D.5036>; else goto <D.5037>;
  <D.5036>:
  GC_finalization_failures.36 = GC_finalization_failures;
  GC_finalization_failures.37 = GC_finalization_failures.36 + 1;
  GC_finalization_failures = GC_finalization_failures.37;
  return;
  <D.5037>:
  D.5040 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5040 != 0) goto <D.5041>; else goto <D.5042>;
  <D.5041>:
  GC_lock ();
  <D.5042>:
  <D.5034>:
  base.31 = (long unsigned int) base;
  D.5001 = ~base.31;
  new_fo->prolog.hidden_key = D.5001;
  new_fo->fo_fn = fn;
  new_fo->fo_client_data = cd;
  D.5043 = hhdr->hb_sz;
  new_fo->fo_object_size = D.5043;
  new_fo->fo_mark_proc = mp;
  fo_head.32 = fo_head;
  index.33 = (unsigned int) index;
  D.4998 = index.33 * 4;
  D.4999 = fo_head.32 + D.4998;
  D.5044 = *D.4999;
  new_fo->prolog.next = D.5044;
  GC_fo_entries.29 = GC_fo_entries;
  GC_fo_entries.38 = GC_fo_entries.29 + 1;
  GC_fo_entries = GC_fo_entries.38;
  fo_head.32 = fo_head;
  index.33 = (unsigned int) index;
  D.4998 = index.33 * 4;
  D.4999 = fo_head.32 + D.4998;
  *D.4999 = new_fo;
  pthread_mutex_unlock (&GC_allocate_ml);
}


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.39;
  long int log_fo_table_size.40;
  struct finalizable_object * * fo_head.41;
  unsigned int i.42;
  unsigned int D.5054;
  struct finalizable_object * * D.5055;
  long unsigned int D.5056;
  long unsigned int D.5057;
  long int real_ptr.43;
  struct finalizable_object * curr_fo;
  char * real_ptr;
  int fo_size;
  int i;

  log_fo_table_size.40 = log_fo_table_size;
  if (log_fo_table_size.40 != -1) goto <D.5049>; else goto <D.5050>;
  <D.5049>:
  log_fo_table_size.40 = log_fo_table_size;
  iftmp.39 = 1 << log_fo_table_size.40;
  goto <D.5051>;
  <D.5050>:
  iftmp.39 = 0;
  <D.5051>:
  fo_size = iftmp.39;
  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.4680>;
  <D.4679>:
  fo_head.41 = fo_head;
  i.42 = (unsigned int) i;
  D.5054 = i.42 * 4;
  D.5055 = fo_head.41 + D.5054;
  curr_fo = *D.5055;
  goto <D.4677>;
  <D.4676>:
  D.5056 = curr_fo->prolog.hidden_key;
  D.5057 = ~D.5056;
  real_ptr = (char *) D.5057;
  real_ptr.43 = (long int) real_ptr;
  GC_printf ("Finalizable object: 0x%lx\n", real_ptr.43, 0, 0, 0, 0, 0);
  curr_fo = curr_fo->prolog.next;
  <D.4677>:
  if (curr_fo != 0B) goto <D.4676>; else goto <D.4678>;
  <D.4678>:
  i = i + 1;
  <D.4680>:
  if (i < fo_size) goto <D.4679>; else goto <D.4681>;
  <D.4681>:
}


GC_dump_finalization_links (struct dl_hashtbl_s * dl_hashtbl)
{
  size_t iftmp.44;
  long int D.5060;
  int D.5063;
  struct disappearing_link * * D.5065;
  unsigned int i.45;
  unsigned int D.5067;
  struct disappearing_link * * D.5068;
  long unsigned int D.5069;
  long unsigned int D.5070;
  long unsigned int D.5071;
  long unsigned int D.5072;
  long int real_link.46;
  long int real_ptr.47;
  unsigned int i.48;
  struct disappearing_link * curr_dl;
  char * real_ptr;
  char * real_link;
  size_t dl_size;
  int i;

  D.5060 = dl_hashtbl->log_size;
  if (D.5060 != -1) goto <D.5061>; else goto <D.5062>;
  <D.5061>:
  D.5060 = dl_hashtbl->log_size;
  D.5063 = 1 << D.5060;
  iftmp.44 = (size_t) D.5063;
  goto <D.5064>;
  <D.5062>:
  iftmp.44 = 0;
  <D.5064>:
  dl_size = iftmp.44;
  i = 0;
  goto <D.4668>;
  <D.4667>:
  D.5065 = dl_hashtbl->head;
  i.45 = (unsigned int) i;
  D.5067 = i.45 * 4;
  D.5068 = D.5065 + D.5067;
  curr_dl = *D.5068;
  goto <D.4665>;
  <D.4664>:
  D.5069 = curr_dl->dl_hidden_obj;
  D.5070 = ~D.5069;
  real_ptr = (char *) D.5070;
  D.5071 = curr_dl->prolog.hidden_key;
  D.5072 = ~D.5071;
  real_link = (char *) D.5072;
  real_link.46 = (long int) real_link;
  real_ptr.47 = (long int) real_ptr;
  GC_printf ("Object: %lx, link: %lx\n", real_ptr.47, real_link.46, 0, 0, 0, 0);
  curr_dl = curr_dl->prolog.next;
  <D.4665>:
  if (curr_dl != 0B) goto <D.4664>; else goto <D.4666>;
  <D.4666>:
  i = i + 1;
  <D.4668>:
  i.48 = (unsigned int) i;
  if (i.48 < dl_size) goto <D.4667>; else goto <D.4669>;
  <D.4669>:
}


GC_finalize ()
{
  int iftmp.49;
  long int log_fo_table_size.50;
  struct finalizable_object * * fo_head.51;
  unsigned int i.52;
  unsigned int D.5083;
  struct finalizable_object * * D.5084;
  long unsigned int D.5085;
  long unsigned int D.5086;
  int D.5087;
  void (*<Tcfc>) () D.5090;
  struct mse * GC_mark_stack.53;
  long unsigned int GC_mark_stack_size.54;
  long unsigned int D.5093;
  struct mse * D.5094;
  struct mse * GC_mark_stack_top.55;
  struct mse * GC_mark_stack_top.56;
  int D.5097;
  int GC_mark_state.57;
  int D.5101;
  int D.5102;
  void (*<T33e>) (char *, GC_word) GC_current_warn_proc.58;
  long unsigned int real_ptr.59;
  int D.5107;
  int GC_java_finalization.60;
  long unsigned int GC_fo_entries.61;
  long unsigned int GC_fo_entries.62;
  struct finalizable_object * GC_finalize_now.63;
  long unsigned int D.5119;
  long unsigned int D.5120;
  int GC_all_interior_pointers.64;
  long unsigned int GC_all_interior_pointers.65;
  long unsigned int D.5123;
  long unsigned int D.5124;
  long unsigned int D.5125;
  long unsigned int D.5126;
  unsigned int GC_all_interior_pointers.66;
  unsigned int D.5128;
  unsigned int D.5129;
  long unsigned int D.5130;
  long unsigned int D.5131;
  long unsigned int D.5132;
  int D.5136;
  struct mse * GC_mark_stack_top.67;
  struct mse * GC_mark_stack_top.68;
  int D.5143;
  int D.5146;
  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.50 = log_fo_table_size;
  if (log_fo_table_size.50 != -1) goto <D.5078>; else goto <D.5079>;
  <D.5078>:
  log_fo_table_size.50 = log_fo_table_size;
  iftmp.49 = 1 << log_fo_table_size.50;
  goto <D.5080>;
  <D.5079>:
  iftmp.49 = 0;
  <D.5080>:
  fo_size = iftmp.49;
  GC_make_disappearing_links_disappear (&GC_dl_hashtbl);
  i = 0;
  goto <D.4732>;
  <D.4731>:
  fo_head.51 = fo_head;
  i.52 = (unsigned int) i;
  D.5083 = i.52 * 4;
  D.5084 = fo_head.51 + D.5083;
  curr_fo = *D.5084;
  goto <D.4729>;
  <D.4728>:
  D.5085 = curr_fo->prolog.hidden_key;
  D.5086 = ~D.5085;
  real_ptr = (char *) D.5086;
  D.5087 = GC_is_marked (real_ptr);
  if (D.5087 == 0) goto <D.5088>; else goto <D.5089>;
  <D.5088>:
  D.5090 = curr_fo->fo_mark_proc;
  D.5090 (real_ptr);
  goto <D.4723>;
  <D.4722>:
  GC_mark_stack.53 = GC_mark_stack;
  GC_mark_stack_size.54 = GC_mark_stack_size;
  D.5093 = GC_mark_stack_size.54 * 8;
  D.5094 = GC_mark_stack.53 + D.5093;
  GC_mark_stack.53 = GC_mark_stack;
  GC_mark_stack_top.55 = GC_mark_stack_top;
  GC_mark_stack_top.56 = GC_mark_from (GC_mark_stack_top.55, GC_mark_stack.53, D.5094);
  GC_mark_stack_top = GC_mark_stack_top.56;
  <D.4723>:
  D.5097 = GC_mark_stack_empty ();
  if (D.5097 == 0) goto <D.4722>; else goto <D.4724>;
  <D.4724>:
  GC_mark_state.57 = GC_mark_state;
  if (GC_mark_state.57 != 0) goto <D.5099>; else goto <D.5100>;
  <D.5099>:
  GC_set_mark_bit (real_ptr);
  goto <D.4726>;
  <D.4725>:
  <D.4726>:
  D.5101 = GC_mark_some (0B);
  if (D.5101 == 0) goto <D.4725>; else goto <D.4727>;
  <D.4727>:
  <D.5100>:
  D.5102 = GC_is_marked (real_ptr);
  if (D.5102 != 0) goto <D.5103>; else goto <D.5104>;
  <D.5103>:
  GC_current_warn_proc.58 = GC_current_warn_proc;
  real_ptr.59 = (long unsigned int) real_ptr;
  GC_current_warn_proc.58 ("GC Warning: Finalization cycle involving %lx\n", real_ptr.59);
  <D.5104>:
  <D.5089>:
  curr_fo = curr_fo->prolog.next;
  <D.4729>:
  if (curr_fo != 0B) goto <D.4728>; else goto <D.4730>;
  <D.4730>:
  i = i + 1;
  <D.4732>:
  if (i < fo_size) goto <D.4731>; else goto <D.4733>;
  <D.4733>:
  GC_arrays._words_finalized = 0;
  i = 0;
  goto <D.4738>;
  <D.4737>:
  fo_head.51 = fo_head;
  i.52 = (unsigned int) i;
  D.5083 = i.52 * 4;
  D.5084 = fo_head.51 + D.5083;
  curr_fo = *D.5084;
  prev_fo = 0B;
  goto <D.4735>;
  <D.4734>:
  D.5085 = curr_fo->prolog.hidden_key;
  D.5086 = ~D.5085;
  real_ptr = (char *) D.5086;
  D.5107 = GC_is_marked (real_ptr);
  if (D.5107 == 0) goto <D.5108>; else goto <D.5109>;
  <D.5108>:
  GC_java_finalization.60 = GC_java_finalization;
  if (GC_java_finalization.60 == 0) goto <D.5111>; else goto <D.5112>;
  <D.5111>:
  GC_set_mark_bit (real_ptr);
  <D.5112>:
  next_fo = curr_fo->prolog.next;
  if (prev_fo == 0B) goto <D.5113>; else goto <D.5114>;
  <D.5113>:
  fo_head.51 = fo_head;
  i.52 = (unsigned int) i;
  D.5083 = i.52 * 4;
  D.5084 = fo_head.51 + D.5083;
  *D.5084 = next_fo;
  goto <D.5115>;
  <D.5114>:
  prev_fo->prolog.next = next_fo;
  <D.5115>:
  GC_fo_entries.61 = GC_fo_entries;
  GC_fo_entries.62 = GC_fo_entries.61 + 4294967295;
  GC_fo_entries = GC_fo_entries.62;
  GC_finalize_now.63 = GC_finalize_now;
  curr_fo->prolog.next = GC_finalize_now.63;
  GC_finalize_now = curr_fo;
  D.5085 = curr_fo->prolog.hidden_key;
  D.5086 = ~D.5085;
  curr_fo->prolog.hidden_key = D.5086;
  D.5119 = GC_arrays._words_finalized;
  D.5120 = curr_fo->fo_object_size;
  GC_all_interior_pointers.64 = GC_all_interior_pointers;
  GC_all_interior_pointers.65 = (long unsigned int) GC_all_interior_pointers.64;
  D.5123 = D.5120 + GC_all_interior_pointers.65;
  D.5124 = D.5123 + 7;
  D.5125 = D.5124 >> 2;
  D.5126 = D.5125 & 4294967294;
  GC_all_interior_pointers.64 = GC_all_interior_pointers;
  GC_all_interior_pointers.66 = (unsigned int) GC_all_interior_pointers.64;
  D.5128 = GC_all_interior_pointers.66 + 31;
  D.5129 = D.5128 >> 2;
  D.5130 = D.5129 & 4294967294;
  D.5131 = D.5126 + D.5130;
  D.5132 = D.5119 + D.5131;
  GC_arrays._words_finalized = D.5132;
  curr_fo = next_fo;
  goto <D.5133>;
  <D.5109>:
  prev_fo = curr_fo;
  curr_fo = curr_fo->prolog.next;
  <D.5133>:
  <D.4735>:
  if (curr_fo != 0B) goto <D.4734>; else goto <D.4736>;
  <D.4736>:
  i = i + 1;
  <D.4738>:
  if (i < fo_size) goto <D.4737>; else goto <D.4739>;
  <D.4739>:
  GC_java_finalization.60 = GC_java_finalization;
  if (GC_java_finalization.60 != 0) goto <D.5134>; else goto <D.5135>;
  <D.5134>:
  curr_fo = GC_finalize_now;
  goto <D.4747>;
  <D.4746>:
  D.5085 = curr_fo->prolog.hidden_key;
  real_ptr = (char *) D.5085;
  D.5136 = GC_is_marked (real_ptr);
  if (D.5136 == 0) goto <D.5137>; else goto <D.5138>;
  <D.5137>:
  D.5090 = curr_fo->fo_mark_proc;
  if (D.5090 == GC_null_finalize_mark_proc) goto <D.5139>; else goto <D.5140>;
  <D.5139>:
  GC_normal_finalize_mark_proc (real_ptr);
  goto <D.4741>;
  <D.4740>:
  GC_mark_stack.53 = GC_mark_stack;
  GC_mark_stack_size.54 = GC_mark_stack_size;
  D.5093 = GC_mark_stack_size.54 * 8;
  D.5094 = GC_mark_stack.53 + D.5093;
  GC_mark_stack.53 = GC_mark_stack;
  GC_mark_stack_top.67 = GC_mark_stack_top;
  GC_mark_stack_top.68 = GC_mark_from (GC_mark_stack_top.67, GC_mark_stack.53, D.5094);
  GC_mark_stack_top = GC_mark_stack_top.68;
  <D.4741>:
  D.5143 = GC_mark_stack_empty ();
  if (D.5143 == 0) goto <D.4740>; else goto <D.4742>;
  <D.4742>:
  GC_mark_state.57 = GC_mark_state;
  if (GC_mark_state.57 != 0) goto <D.5144>; else goto <D.5145>;
  <D.5144>:
  GC_set_mark_bit (real_ptr);
  goto <D.4744>;
  <D.4743>:
  <D.4744>:
  D.5146 = GC_mark_some (0B);
  if (D.5146 == 0) goto <D.4743>; else goto <D.4745>;
  <D.4745>:
  <D.5145>:
  <D.5140>:
  GC_set_mark_bit (real_ptr);
  <D.5138>:
  curr_fo = curr_fo->prolog.next;
  <D.4747>:
  if (curr_fo != 0B) goto <D.4746>; else goto <D.4748>;
  <D.4748>:
  <D.5135>:
  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.69;
  long int D.5148;
  struct disappearing_link * * D.5152;
  unsigned int i.70;
  unsigned int D.5154;
  struct disappearing_link * * D.5155;
  long unsigned int D.5156;
  long unsigned int D.5157;
  long unsigned int D.5158;
  long unsigned int D.5159;
  int D.5160;
  long unsigned int D.5166;
  long unsigned int D.5167;
  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.5148 = dl_hashtbl->log_size;
  if (D.5148 != -1) goto <D.5149>; else goto <D.5150>;
  <D.5149>:
  D.5148 = dl_hashtbl->log_size;
  iftmp.69 = 1 << D.5148;
  goto <D.5151>;
  <D.5150>:
  iftmp.69 = 0;
  <D.5151>:
  dl_size = iftmp.69;
  i = 0;
  goto <D.4696>;
  <D.4695>:
  D.5152 = dl_hashtbl->head;
  i.70 = (unsigned int) i;
  D.5154 = i.70 * 4;
  D.5155 = D.5152 + D.5154;
  curr_dl = *D.5155;
  prev_dl = 0B;
  goto <D.4693>;
  <D.4692>:
  D.5156 = curr_dl->dl_hidden_obj;
  D.5157 = ~D.5156;
  real_ptr = (char *) D.5157;
  D.5158 = curr_dl->prolog.hidden_key;
  D.5159 = ~D.5158;
  real_link = (char *) D.5159;
  D.5160 = GC_is_marked (real_ptr);
  if (D.5160 == 0) goto <D.5161>; else goto <D.5162>;
  <D.5161>:
  MEM[(word *)real_link] = 0;
  next_dl = curr_dl->prolog.next;
  if (prev_dl == 0B) goto <D.5163>; else goto <D.5164>;
  <D.5163>:
  D.5152 = dl_hashtbl->head;
  i.70 = (unsigned int) i;
  D.5154 = i.70 * 4;
  D.5155 = D.5152 + D.5154;
  *D.5155 = next_dl;
  goto <D.5165>;
  <D.5164>:
  prev_dl->prolog.next = next_dl;
  <D.5165>:
  GC_clear_mark_bit (curr_dl);
  D.5166 = dl_hashtbl->entries;
  D.5167 = D.5166 + 4294967295;
  dl_hashtbl->entries = D.5167;
  curr_dl = next_dl;
  goto <D.5168>;
  <D.5162>:
  prev_dl = curr_dl;
  curr_dl = curr_dl->prolog.next;
  <D.5168>:
  <D.4693>:
  if (curr_dl != 0B) goto <D.4692>; else goto <D.4694>;
  <D.4694>:
  i = i + 1;
  <D.4696>:
  if (i < dl_size) goto <D.4695>; else goto <D.4697>;
  <D.4697>:
}


GC_remove_dangling_disappearing_links (struct dl_hashtbl_s * dl_hashtbl)
{
  int iftmp.71;
  long int D.5170;
  struct disappearing_link * * D.5174;
  unsigned int i.72;
  unsigned int D.5176;
  struct disappearing_link * * D.5177;
  long unsigned int D.5178;
  long unsigned int D.5179;
  void * D.5180;
  int D.5184;
  long unsigned int D.5189;
  long unsigned int D.5190;
  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.5170 = dl_hashtbl->log_size;
  if (D.5170 != -1) goto <D.5171>; else goto <D.5172>;
  <D.5171>:
  D.5170 = dl_hashtbl->log_size;
  iftmp.71 = 1 << D.5170;
  goto <D.5173>;
  <D.5172>:
  iftmp.71 = 0;
  <D.5173>:
  dl_size = iftmp.71;
  i = 0;
  goto <D.4712>;
  <D.4711>:
  D.5174 = dl_hashtbl->head;
  i.72 = (unsigned int) i;
  D.5176 = i.72 * 4;
  D.5177 = D.5174 + D.5176;
  curr_dl = *D.5177;
  prev_dl = 0B;
  goto <D.4709>;
  <D.4708>:
  D.5178 = curr_dl->prolog.hidden_key;
  D.5179 = ~D.5178;
  D.5180 = (void *) D.5179;
  real_link = GC_base (D.5180);
  if (real_link != 0B) goto <D.5183>; else goto <D.5181>;
  <D.5183>:
  D.5184 = GC_is_marked (real_link);
  if (D.5184 == 0) goto <D.5185>; else goto <D.5181>;
  <D.5185>:
  next_dl = curr_dl->prolog.next;
  if (prev_dl == 0B) goto <D.5186>; else goto <D.5187>;
  <D.5186>:
  D.5174 = dl_hashtbl->head;
  i.72 = (unsigned int) i;
  D.5176 = i.72 * 4;
  D.5177 = D.5174 + D.5176;
  *D.5177 = next_dl;
  goto <D.5188>;
  <D.5187>:
  prev_dl->prolog.next = next_dl;
  <D.5188>:
  GC_clear_mark_bit (curr_dl);
  D.5189 = dl_hashtbl->entries;
  D.5190 = D.5189 + 4294967295;
  dl_hashtbl->entries = D.5190;
  curr_dl = next_dl;
  goto <D.5182>;
  <D.5181>:
  prev_dl = curr_dl;
  curr_dl = curr_dl->prolog.next;
  <D.5182>:
  <D.4709>:
  if (curr_dl != 0B) goto <D.4708>; else goto <D.4710>;
  <D.4710>:
  i = i + 1;
  <D.4712>:
  if (i < dl_size) goto <D.4711>; else goto <D.4713>;
  <D.4713>:
}


GC_enqueue_all_finalizers ()
{
  int iftmp.73;
  long int log_fo_table_size.74;
  struct finalizable_object * * fo_head.75;
  unsigned int i.76;
  unsigned int D.5198;
  struct finalizable_object * * D.5199;
  long unsigned int D.5200;
  long unsigned int D.5201;
  struct mse * GC_mark_stack.77;
  long unsigned int GC_mark_stack_size.78;
  long unsigned int D.5204;
  struct mse * D.5205;
  struct mse * GC_mark_stack_top.79;
  struct mse * GC_mark_stack_top.80;
  int D.5208;
  int GC_mark_state.81;
  int D.5212;
  long unsigned int GC_fo_entries.82;
  long unsigned int GC_fo_entries.83;
  struct finalizable_object * GC_finalize_now.84;
  long unsigned int D.5219;
  long unsigned int D.5220;
  int GC_all_interior_pointers.85;
  long unsigned int GC_all_interior_pointers.86;
  long unsigned int D.5223;
  long unsigned int D.5224;
  long unsigned int D.5225;
  long unsigned int D.5226;
  unsigned int GC_all_interior_pointers.87;
  unsigned int D.5228;
  unsigned int D.5229;
  long unsigned int D.5230;
  long unsigned int D.5231;
  long unsigned int D.5232;
  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.74 = log_fo_table_size;
  if (log_fo_table_size.74 != -1) goto <D.5193>; else goto <D.5194>;
  <D.5193>:
  log_fo_table_size.74 = log_fo_table_size;
  iftmp.73 = 1 << log_fo_table_size.74;
  goto <D.5195>;
  <D.5194>:
  iftmp.73 = 0;
  <D.5195>:
  fo_size = iftmp.73;
  GC_arrays._words_finalized = 0;
  i = 0;
  goto <D.4767>;
  <D.4766>:
  fo_head.75 = fo_head;
  i.76 = (unsigned int) i;
  D.5198 = i.76 * 4;
  D.5199 = fo_head.75 + D.5198;
  curr_fo = *D.5199;
  prev_fo = 0B;
  goto <D.4764>;
  <D.4763>:
  D.5200 = curr_fo->prolog.hidden_key;
  D.5201 = ~D.5200;
  real_ptr = (char *) D.5201;
  GC_normal_finalize_mark_proc (real_ptr);
  goto <D.4758>;
  <D.4757>:
  GC_mark_stack.77 = GC_mark_stack;
  GC_mark_stack_size.78 = GC_mark_stack_size;
  D.5204 = GC_mark_stack_size.78 * 8;
  D.5205 = GC_mark_stack.77 + D.5204;
  GC_mark_stack.77 = GC_mark_stack;
  GC_mark_stack_top.79 = GC_mark_stack_top;
  GC_mark_stack_top.80 = GC_mark_from (GC_mark_stack_top.79, GC_mark_stack.77, D.5205);
  GC_mark_stack_top = GC_mark_stack_top.80;
  <D.4758>:
  D.5208 = GC_mark_stack_empty ();
  if (D.5208 == 0) goto <D.4757>; else goto <D.4759>;
  <D.4759>:
  GC_mark_state.81 = GC_mark_state;
  if (GC_mark_state.81 != 0) goto <D.5210>; else goto <D.5211>;
  <D.5210>:
  GC_set_mark_bit (real_ptr);
  goto <D.4761>;
  <D.4760>:
  <D.4761>:
  D.5212 = GC_mark_some (0B);
  if (D.5212 == 0) goto <D.4760>; else goto <D.4762>;
  <D.4762>:
  <D.5211>:
  GC_set_mark_bit (real_ptr);
  next_fo = curr_fo->prolog.next;
  if (prev_fo == 0B) goto <D.5213>; else goto <D.5214>;
  <D.5213>:
  fo_head.75 = fo_head;
  i.76 = (unsigned int) i;
  D.5198 = i.76 * 4;
  D.5199 = fo_head.75 + D.5198;
  *D.5199 = next_fo;
  goto <D.5215>;
  <D.5214>:
  prev_fo->prolog.next = next_fo;
  <D.5215>:
  GC_fo_entries.82 = GC_fo_entries;
  GC_fo_entries.83 = GC_fo_entries.82 + 4294967295;
  GC_fo_entries = GC_fo_entries.83;
  GC_finalize_now.84 = GC_finalize_now;
  curr_fo->prolog.next = GC_finalize_now.84;
  GC_finalize_now = curr_fo;
  D.5200 = curr_fo->prolog.hidden_key;
  D.5201 = ~D.5200;
  curr_fo->prolog.hidden_key = D.5201;
  D.5219 = GC_arrays._words_finalized;
  D.5220 = curr_fo->fo_object_size;
  GC_all_interior_pointers.85 = GC_all_interior_pointers;
  GC_all_interior_pointers.86 = (long unsigned int) GC_all_interior_pointers.85;
  D.5223 = D.5220 + GC_all_interior_pointers.86;
  D.5224 = D.5223 + 7;
  D.5225 = D.5224 >> 2;
  D.5226 = D.5225 & 4294967294;
  GC_all_interior_pointers.85 = GC_all_interior_pointers;
  GC_all_interior_pointers.87 = (unsigned int) GC_all_interior_pointers.85;
  D.5228 = GC_all_interior_pointers.87 + 31;
  D.5229 = D.5228 >> 2;
  D.5230 = D.5229 & 4294967294;
  D.5231 = D.5226 + D.5230;
  D.5232 = D.5219 + D.5231;
  GC_arrays._words_finalized = D.5232;
  curr_fo = next_fo;
  <D.4764>:
  if (curr_fo != 0B) goto <D.4763>; else goto <D.4765>;
  <D.4765>:
  i = i + 1;
  <D.4767>:
  if (i < fo_size) goto <D.4766>; else goto <D.4768>;
  <D.4768>:
  return;
}


GC_finalize_all ()
{
  int D.5234;
  int D.5237;
  long unsigned int GC_fo_entries.88;

  D.5234 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5234 != 0) goto <D.5235>; else goto <D.5236>;
  <D.5235>:
  GC_lock ();
  <D.5236>:
  goto <D.4772>;
  <D.4771>:
  GC_enqueue_all_finalizers ();
  pthread_mutex_unlock (&GC_allocate_ml);
  GC_notify_or_invoke_finalizers ();
  D.5237 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5237 != 0) goto <D.5238>; else goto <D.5239>;
  <D.5238>:
  GC_lock ();
  <D.5239>:
  <D.4772>:
  GC_fo_entries.88 = GC_fo_entries;
  if (GC_fo_entries.88 != 0) goto <D.4771>; else goto <D.4773>;
  <D.4773>:
  pthread_mutex_unlock (&GC_allocate_ml);
}


GC_should_invoke_finalizers ()
{
  int D.5241;
  struct finalizable_object * GC_finalize_now.89;
  _Bool D.5243;

  GC_finalize_now.89 = GC_finalize_now;
  D.5243 = GC_finalize_now.89 != 0B;
  D.5241 = (int) D.5243;
  return D.5241;
}


GC_invoke_finalizers ()
{
  int D.5245;
  struct hash_chain_entry * GC_finalize_now.90;
  void (*<T31f>) (void *, void *) D.5254;
  char * D.5255;
  long unsigned int D.5256;
  void * D.5257;
  struct finalizable_object * GC_finalize_now.91;
  long unsigned int D.5261;
  int D.5264;
  long unsigned int D.5267;
  long unsigned int D.5268;
  long unsigned int D.5269;
  int D.5270;
  struct finalizable_object * curr_fo;
  int count;
  word mem_freed_before;

  count = 0;
  goto <D.4784>;
  <D.4783>:
  D.5245 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5245 != 0) goto <D.5246>; else goto <D.5247>;
  <D.5246>:
  GC_lock ();
  <D.5247>:
  if (count == 0) goto <D.5248>; else goto <D.5249>;
  <D.5248>:
  mem_freed_before = GC_arrays._mem_freed;
  <D.5249>:
  curr_fo = GC_finalize_now;
  if (curr_fo != 0B) goto <D.5250>; else goto <D.5251>;
  <D.5250>:
  GC_finalize_now.90 = curr_fo->prolog.next;
  GC_finalize_now = GC_finalize_now.90;
  <D.5251>:
  pthread_mutex_unlock (&GC_allocate_ml);
  if (curr_fo == 0B) goto <D.4782>; else goto <D.5253>;
  <D.5253>:
  curr_fo->prolog.next = 0B;
  D.5254 = curr_fo->fo_fn;
  D.5255 = curr_fo->fo_client_data;
  D.5256 = curr_fo->prolog.hidden_key;
  D.5257 = (void *) D.5256;
  D.5254 (D.5257, D.5255);
  curr_fo->fo_client_data = 0B;
  count = count + 1;
  <D.4784>:
  GC_finalize_now.91 = GC_finalize_now;
  if (GC_finalize_now.91 != 0B) goto <D.4783>; else goto <D.4782>;
  <D.4782>:
  if (count != 0) goto <D.5259>; else goto <D.5260>;
  <D.5259>:
  D.5261 = GC_arrays._mem_freed;
  if (D.5261 != mem_freed_before) goto <D.5262>; else goto <D.5263>;
  <D.5262>:
  D.5264 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5264 != 0) goto <D.5265>; else goto <D.5266>;
  <D.5265>:
  GC_lock ();
  <D.5266>:
  D.5267 = GC_arrays._finalizer_mem_freed;
  D.5261 = GC_arrays._mem_freed;
  D.5268 = D.5261 - mem_freed_before;
  D.5269 = D.5267 + D.5268;
  GC_arrays._finalizer_mem_freed = D.5269;
  pthread_mutex_unlock (&GC_allocate_ml);
  <D.5263>:
  <D.5260>:
  D.5270 = count;
  return D.5270;
}


GC_notify_or_invoke_finalizers ()
{
  struct finalizable_object * GC_finalize_now.92;
  int GC_finalize_on_demand.93;
  void (*<T2c8>) (void) GC_finalizer_notifier.94;
  long unsigned int last_finalizer_notification.95;
  long unsigned int GC_gc_no.96;

  GC_finalize_now.92 = GC_finalize_now;
  if (GC_finalize_now.92 == 0B) goto <D.5273>; else goto <D.5274>;
  <D.5273>:
  return;
  <D.5274>:
  GC_finalize_on_demand.93 = GC_finalize_on_demand;
  if (GC_finalize_on_demand.93 == 0) goto <D.5276>; else goto <D.5277>;
  <D.5276>:
  GC_invoke_finalizers ();
  return;
  <D.5277>:
  GC_finalizer_notifier.94 = GC_finalizer_notifier;
  if (GC_finalizer_notifier.94 != 0B) goto <D.5279>; else goto <D.5280>;
  <D.5279>:
  last_finalizer_notification.95 = last_finalizer_notification;
  GC_gc_no.96 = GC_gc_no;
  if (last_finalizer_notification.95 != GC_gc_no.96) goto <D.5283>; else goto <D.5284>;
  <D.5283>:
  GC_gc_no.96 = GC_gc_no;
  last_finalizer_notification = GC_gc_no.96;
  GC_finalizer_notifier.94 = GC_finalizer_notifier;
  GC_finalizer_notifier.94 ();
  <D.5284>:
  <D.5280>:
}


GC_call_with_alloc_lock (void * (*GC_fn_type) (void *) fn, void * client_data)
{
  int D.5286;
  long unsigned int GC_lock_holder.97;
  void * D.5290;
  void * result;

  D.5286 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5286 != 0) goto <D.5287>; else goto <D.5288>;
  <D.5287>:
  GC_lock ();
  <D.5288>:
  GC_lock_holder.97 = pthread_self ();
  GC_lock_holder = GC_lock_holder.97;
  result = fn (client_data);
  GC_lock_holder = 4294967295;
  pthread_mutex_unlock (&GC_allocate_ml);
  D.5290 = result;
  return D.5290;
}


GC_print_finalization_stats ()
{
  long unsigned int D.5292;
  long int D.5293;
  long unsigned int D.5294;
  long int D.5295;
  long unsigned int GC_fo_entries.98;
  long int GC_fo_entries.99;
  long int ready.100;
  struct finalizable_object * fo;
  size_t ready;

  fo = GC_finalize_now;
  ready = 0;
  D.5292 = GC_ll_hashtbl.entries;
  D.5293 = (long int) D.5292;
  D.5294 = GC_dl_hashtbl.entries;
  D.5295 = (long int) D.5294;
  GC_fo_entries.98 = GC_fo_entries;
  GC_fo_entries.99 = (long int) GC_fo_entries.98;
  GC_printf ("%lu finalization table entries; %lu/%lu short/long disappearing links alive\n", GC_fo_entries.99, D.5295, D.5293, 0, 0, 0);
  goto <D.4802>;
  <D.4801>:
  ready = ready + 1;
  fo = fo->prolog.next;
  <D.4802>:
  if (fo != 0B) goto <D.4801>; else goto <D.4803>;
  <D.4803>:
  ready.100 = (long int) ready;
  GC_printf ("%lu objects are eligible for immediate finalization\n", ready.100, 0, 0, 0, 0, 0);
}


