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.7316;
  int D.7318;
  unsigned int D.7319;
  struct hash_chain_entry * * D.7325;
  long unsigned int D.7326;
  struct hash_chain_entry * * D.7327;
  long unsigned int D.7328;
  long unsigned int D.7329;
  long unsigned int real_key.1;
  long unsigned int D.7331;
  int D.7332;
  long unsigned int D.7333;
  long unsigned int D.7334;
  long unsigned int D.7335;
  long unsigned int D.7336;
  unsigned int new_hash.2;
  unsigned int D.7338;
  struct hash_chain_entry * * D.7339;
  struct hash_chain_entry * D.7340;
  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.7314>; else goto <D.7315>;
  <D.7314>:
  D.7316 = 1 << log_old_size;
  iftmp.0 = (word) D.7316;
  goto <D.7317>;
  <D.7315>:
  iftmp.0 = 0;
  <D.7317>:
  old_size = iftmp.0;
  D.7318 = 1 << log_new_size;
  new_size = (word) D.7318;
  D.7319 = new_size * 4;
  new_table = GC_generic_malloc_inner_ignore_off_page (D.7319, 1);
  if (new_table == 0B) goto <D.7320>; else goto <D.7321>;
  <D.7320>:
  if (table == 0B) goto <D.7322>; else goto <D.7323>;
  <D.7322>:
  GC_abort ("Insufficient space for initial table allocation");
  goto <D.7324>;
  <D.7323>:
  return;
  <D.7324>:
  <D.7321>:
  i = 0;
  goto <D.7062>;
  <D.7061>:
  D.7325 = *table;
  D.7326 = i * 4;
  D.7327 = D.7325 + D.7326;
  p = *D.7327;
  goto <D.7059>;
  <D.7058>:
  {
    register char * real_key;
    register struct hash_chain_entry * next;
    register int new_hash;

    D.7328 = p->hidden_key;
    D.7329 = ~D.7328;
    real_key = (char *) D.7329;
    next = p->next;
    real_key.1 = (long unsigned int) real_key;
    D.7331 = real_key.1 >> 3;
    real_key.1 = (long unsigned int) real_key;
    D.7332 = log_new_size + 3;
    D.7333 = real_key.1 >> D.7332;
    D.7334 = D.7331 ^ D.7333;
    D.7335 = new_size + 4294967295;
    D.7336 = D.7334 & D.7335;
    new_hash = (int) D.7336;
    new_hash.2 = (unsigned int) new_hash;
    D.7338 = new_hash.2 * 4;
    D.7339 = new_table + D.7338;
    D.7340 = *D.7339;
    p->next = D.7340;
    new_hash.2 = (unsigned int) new_hash;
    D.7338 = new_hash.2 * 4;
    D.7339 = new_table + D.7338;
    *D.7339 = p;
    p = next;
  }
  <D.7059>:
  if (p != 0B) goto <D.7058>; else goto <D.7060>;
  <D.7060>:
  i = i + 1;
  <D.7062>:
  if (i < old_size) goto <D.7061>; else goto <D.7063>;
  <D.7063>:
  *log_size_ptr = log_new_size;
  *table = new_table;
}


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

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


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

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


GC_register_disappearing_link_inner (struct dl_hashtbl_s * dl_hashtbl, void * * link, void * obj)
{
  long unsigned int link.3;
  long unsigned int D.7349;
  int D.7352;
  long int D.7357;
  long unsigned int D.7359;
  long unsigned int D.7360;
  struct disappearing_link * * * D.7361;
  signed_word * D.7362;
  int GC_print_stats.4;
  int D.7366;
  long unsigned int D.7367;
  long int D.7368;
  long unsigned int D.7369;
  long unsigned int D.7370;
  int D.7371;
  long unsigned int D.7372;
  long unsigned int D.7373;
  struct disappearing_link * * D.7374;
  unsigned int index.5;
  unsigned int D.7376;
  struct disappearing_link * * D.7377;
  long unsigned int D.7378;
  long unsigned int D.7379;
  long unsigned int obj.6;
  long unsigned int D.7383;
  int D.7384;
  void * (*<Td4e>) (size_t) GC_oom_fn.7;
  unsigned int GC_finalization_failures.8;
  unsigned int GC_finalization_failures.9;
  int D.7392;
  struct disappearing_link * D.7395;
  long unsigned int D.7396;
  struct disappearing_link * curr_dl;
  int index;
  struct disappearing_link * new_dl;

  link.3 = (long unsigned int) link;
  D.7349 = link.3 & 3;
  if (D.7349 != 0) goto <D.7350>; else goto <D.7351>;
  <D.7350>:
  GC_abort ("Bad arg to GC_general_register_disappearing_link");
  <D.7351>:
  D.7352 = GC_test_and_set (&GC_allocate_lock);
  if (D.7352 != 0) goto <D.7353>; else goto <D.7354>;
  <D.7353>:
  GC_lock ();
  <D.7354>:
  D.7357 = dl_hashtbl->log_size;
  if (D.7357 == -1) goto <D.7355>; else goto <D.7358>;
  <D.7358>:
  D.7359 = dl_hashtbl->entries;
  D.7357 = dl_hashtbl->log_size;
  D.7360 = 1 << D.7357;
  if (D.7359 > D.7360) goto <D.7355>; else goto <D.7356>;
  <D.7355>:
  D.7361 = &dl_hashtbl->head;
  D.7362 = &dl_hashtbl->log_size;
  GC_grow_table (D.7361, D.7362);
  GC_print_stats.4 = GC_print_stats;
  if (GC_print_stats.4 != 0) goto <D.7364>; else goto <D.7365>;
  <D.7364>:
  D.7357 = dl_hashtbl->log_size;
  D.7366 = 1 << D.7357;
  GC_printf ("Grew dl table to %lu entries\n", D.7366, 0, 0, 0, 0, 0);
  <D.7365>:
  <D.7356>:
  link.3 = (long unsigned int) link;
  D.7367 = link.3 >> 3;
  link.3 = (long unsigned int) link;
  D.7357 = dl_hashtbl->log_size;
  D.7368 = D.7357 + 3;
  D.7369 = link.3 >> D.7368;
  D.7370 = D.7367 ^ D.7369;
  D.7357 = dl_hashtbl->log_size;
  D.7366 = 1 << D.7357;
  D.7371 = D.7366 + -1;
  D.7372 = (long unsigned int) D.7371;
  D.7373 = D.7370 & D.7372;
  index = (int) D.7373;
  D.7374 = dl_hashtbl->head;
  index.5 = (unsigned int) index;
  D.7376 = index.5 * 4;
  D.7377 = D.7374 + D.7376;
  curr_dl = *D.7377;
  D.7374 = dl_hashtbl->head;
  index.5 = (unsigned int) index;
  D.7376 = index.5 * 4;
  D.7377 = D.7374 + D.7376;
  curr_dl = *D.7377;
  goto <D.7081>;
  <D.7080>:
  D.7378 = curr_dl->prolog.hidden_key;
  link.3 = (long unsigned int) link;
  D.7379 = ~link.3;
  if (D.7378 == D.7379) goto <D.7380>; else goto <D.7381>;
  <D.7380>:
  obj.6 = (long unsigned int) obj;
  D.7383 = ~obj.6;
  curr_dl->dl_hidden_obj = D.7383;
  GC_clear (&GC_allocate_lock);
  D.7384 = 1;
  return D.7384;
  <D.7381>:
  curr_dl = curr_dl->prolog.next;
  <D.7081>:
  if (curr_dl != 0B) goto <D.7080>; else goto <D.7082>;
  <D.7082>:
  new_dl = GC_generic_malloc_inner (12, 1);
  if (new_dl == 0B) goto <D.7385>; else goto <D.7386>;
  <D.7385>:
  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.7388>; else goto <D.7389>;
  <D.7388>:
  GC_finalization_failures.8 = GC_finalization_failures;
  GC_finalization_failures.9 = GC_finalization_failures.8 + 1;
  GC_finalization_failures = GC_finalization_failures.9;
  D.7384 = 0;
  return D.7384;
  <D.7389>:
  D.7392 = GC_test_and_set (&GC_allocate_lock);
  if (D.7392 != 0) goto <D.7393>; else goto <D.7394>;
  <D.7393>:
  GC_lock ();
  <D.7394>:
  <D.7386>:
  obj.6 = (long unsigned int) obj;
  D.7383 = ~obj.6;
  new_dl->dl_hidden_obj = D.7383;
  link.3 = (long unsigned int) link;
  D.7379 = ~link.3;
  new_dl->prolog.hidden_key = D.7379;
  D.7374 = dl_hashtbl->head;
  index.5 = (unsigned int) index;
  D.7376 = index.5 * 4;
  D.7377 = D.7374 + D.7376;
  D.7395 = *D.7377;
  new_dl->prolog.next = D.7395;
  D.7374 = dl_hashtbl->head;
  index.5 = (unsigned int) index;
  D.7376 = index.5 * 4;
  D.7377 = D.7374 + D.7376;
  *D.7377 = new_dl;
  D.7359 = dl_hashtbl->entries;
  D.7396 = D.7359 + 1;
  dl_hashtbl->entries = D.7396;
  GC_clear (&GC_allocate_lock);
  D.7384 = 0;
  return D.7384;
}


GC_test_and_set (volatile unsigned int * addr)
{
  int D.7398;
  unsigned int D.7399;

  D.7399 = __sync_lock_test_and_set_4 (addr, 1);
  D.7398 = (int) D.7399;
  return D.7398;
}


GC_clear (volatile unsigned int * addr)
{
  __sync_synchronize ();
  *addr = 0;
}


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

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


GC_unregister_disappearing_link_inner (struct dl_hashtbl_s * dl_hashtbl, void * * link)
{
  int D.7403;
  long unsigned int link.10;
  long unsigned int D.7407;
  long int D.7408;
  long int D.7409;
  long unsigned int D.7410;
  long unsigned int D.7411;
  int D.7412;
  int D.7413;
  long unsigned int D.7414;
  long unsigned int D.7415;
  long unsigned int D.7416;
  struct disappearing_link * * D.7418;
  unsigned int index.11;
  unsigned int D.7420;
  struct disappearing_link * * D.7421;
  long unsigned int D.7422;
  long unsigned int D.7423;
  struct hash_chain_entry * D.7428;
  long unsigned int D.7430;
  long unsigned int D.7431;
  int D.7432;
  struct disappearing_link * curr_dl;
  struct disappearing_link * prev_dl;
  int index;
  void out = <<< error >>>;

  D.7403 = GC_test_and_set (&GC_allocate_lock);
  if (D.7403 != 0) goto <D.7404>; else goto <D.7405>;
  <D.7404>:
  GC_lock ();
  <D.7405>:
  link.10 = (long unsigned int) link;
  D.7407 = link.10 >> 3;
  link.10 = (long unsigned int) link;
  D.7408 = dl_hashtbl->log_size;
  D.7409 = D.7408 + 3;
  D.7410 = link.10 >> D.7409;
  D.7411 = D.7407 ^ D.7410;
  D.7408 = dl_hashtbl->log_size;
  D.7412 = 1 << D.7408;
  D.7413 = D.7412 + -1;
  D.7414 = (long unsigned int) D.7413;
  D.7415 = D.7411 & D.7414;
  index = (int) D.7415;
  link.10 = (long unsigned int) link;
  D.7416 = link.10 & 3;
  if (D.7416 != 0) goto out; else goto <D.7417>;
  <D.7417>:
  prev_dl = 0B;
  D.7418 = dl_hashtbl->head;
  index.11 = (unsigned int) index;
  D.7420 = index.11 * 4;
  D.7421 = D.7418 + D.7420;
  curr_dl = *D.7421;
  goto <D.7095>;
  <D.7094>:
  D.7422 = curr_dl->prolog.hidden_key;
  link.10 = (long unsigned int) link;
  D.7423 = ~link.10;
  if (D.7422 == D.7423) goto <D.7424>; else goto <D.7425>;
  <D.7424>:
  if (prev_dl == 0B) goto <D.7426>; else goto <D.7427>;
  <D.7426>:
  D.7418 = dl_hashtbl->head;
  index.11 = (unsigned int) index;
  D.7420 = index.11 * 4;
  D.7421 = D.7418 + D.7420;
  D.7428 = curr_dl->prolog.next;
  *D.7421 = D.7428;
  goto <D.7429>;
  <D.7427>:
  D.7428 = curr_dl->prolog.next;
  prev_dl->prolog.next = D.7428;
  <D.7429>:
  D.7430 = dl_hashtbl->entries;
  D.7431 = D.7430 + 4294967295;
  dl_hashtbl->entries = D.7431;
  GC_clear (&GC_allocate_lock);
  GC_free (curr_dl);
  D.7432 = 1;
  return D.7432;
  <D.7425>:
  prev_dl = curr_dl;
  curr_dl = curr_dl->prolog.next;
  <D.7095>:
  if (curr_dl != 0B) goto <D.7094>; else goto <D.7096>;
  <D.7096>:
  out:
  GC_clear (&GC_allocate_lock);
  D.7432 = 0;
  return D.7432;
}


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

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


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

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


GC_normal_finalize_mark_proc (char * p)
{
  long unsigned int p.12;
  long unsigned int D.7439;
  struct bottom_index * D.7440;
  long unsigned int D.7441;
  long unsigned int D.7442;
  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.7450;
  struct mse * D.7451;
  struct mse * GC_mark_stack_top.17;
  struct hdr * hhdr;

  p.12 = (long unsigned int) p;
  D.7439 = p.12 >> 22;
  D.7440 = GC_arrays._top_index[D.7439];
  p.12 = (long unsigned int) p;
  D.7441 = p.12 >> 12;
  D.7442 = D.7441 & 1023;
  hhdr = D.7440->index[D.7442];
  {
    register word _descr;

    _descr = hhdr->hb_descr;
    if (_descr == 0) goto <D.7443>; else goto <D.7444>;
    <D.7443>:
    goto <D.7445>;
    <D.7444>:
    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.7450 = GC_mark_stack_size.16 * 8;
    D.7451 = GC_mark_stack.15 + D.7450;
    GC_mark_stack_top.13 = GC_mark_stack_top;
    if (D.7451 <= GC_mark_stack_top.13) goto <D.7452>; else goto <D.7453>;
    <D.7452>:
    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.7453>:
    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.7445>:
  }
}


GC_ignore_self_finalize_mark_proc (char * p)
{
  long unsigned int p.18;
  long unsigned int D.7456;
  struct bottom_index * D.7457;
  long unsigned int D.7458;
  long unsigned int D.7459;
  long unsigned int D.7460;
  long unsigned int D.7461;
  sizetype D.7462;
  long unsigned int D.7463;
  sizetype D.7466;
  _Bool D.7468;
  _Bool D.7469;
  _Bool D.7470;
  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.7456 = p.18 >> 22;
  D.7457 = GC_arrays._top_index[D.7456];
  p.18 = (long unsigned int) p;
  D.7458 = p.18 >> 12;
  D.7459 = D.7458 & 1023;
  hhdr = D.7457->index[D.7459];
  descr = hhdr->hb_descr;
  D.7460 = hhdr->hb_sz;
  D.7461 = D.7460 << 2;
  D.7462 = D.7461 + 4294967295;
  target_limit = p + D.7462;
  D.7463 = descr & 3;
  if (D.7463 == 0) goto <D.7464>; else goto <D.7465>;
  <D.7464>:
  D.7466 = descr + 4294967292;
  scan_limit = p + D.7466;
  goto <D.7467>;
  <D.7465>:
  scan_limit = target_limit + 4294967293;
  <D.7467>:
  q = p;
  goto <D.7119>;
  <D.7118>:
  r = MEM[(char * *)q];
  D.7468 = r < p;
  D.7469 = r > target_limit;
  D.7470 = D.7468 | D.7469;
  if (D.7470 != 0) goto <D.7471>; else goto <D.7472>;
  <D.7471>:
  GC_least_plausible_heap_addr.19 = GC_least_plausible_heap_addr;
  if (r >= GC_least_plausible_heap_addr.19) goto <D.7474>; else goto <D.7475>;
  <D.7474>:
  GC_greatest_plausible_heap_addr.20 = GC_greatest_plausible_heap_addr;
  if (r < GC_greatest_plausible_heap_addr.20) goto <D.7477>; else goto <D.7478>;
  <D.7477>:
  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.7478>:
  <D.7475>:
  <D.7472>:
  q = q + 4;
  <D.7119>:
  if (q <= scan_limit) goto <D.7118>; else goto <D.7120>;
  <D.7120>:
}


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 (*<T1729>) () mp)
{
  int D.7482;
  long int log_fo_table_size.24;
  long unsigned int D.7489;
  long unsigned int GC_fo_entries.25;
  int GC_print_stats.26;
  int D.7494;
  long unsigned int base.27;
  long unsigned int D.7496;
  long int D.7497;
  long unsigned int D.7498;
  long unsigned int D.7499;
  int D.7500;
  long unsigned int D.7501;
  long unsigned int D.7502;
  struct finalizable_object * * fo_head.28;
  unsigned int index.29;
  unsigned int D.7505;
  struct finalizable_object * * D.7506;
  long unsigned int D.7507;
  long unsigned int D.7508;
  char * D.7513;
  void (*<Tdb2>) (void *, void *) D.7516;
  struct hash_chain_entry * D.7519;
  long unsigned int GC_fo_entries.30;
  long unsigned int D.7534;
  struct bottom_index * D.7535;
  long unsigned int D.7536;
  long unsigned int D.7537;
  void * (*<Td4e>) (size_t) GC_oom_fn.31;
  unsigned int GC_finalization_failures.32;
  unsigned int GC_finalization_failures.33;
  int D.7547;
  long unsigned int D.7550;
  struct finalizable_object * D.7551;
  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.7482 = GC_test_and_set (&GC_allocate_lock);
  if (D.7482 != 0) goto <D.7483>; else goto <D.7484>;
  <D.7483>:
  GC_lock ();
  <D.7484>:
  log_fo_table_size.24 = log_fo_table_size;
  if (log_fo_table_size.24 == -1) goto <D.7485>; else goto <D.7488>;
  <D.7488>:
  log_fo_table_size.24 = log_fo_table_size;
  D.7489 = 1 << log_fo_table_size.24;
  GC_fo_entries.25 = GC_fo_entries;
  if (D.7489 < GC_fo_entries.25) goto <D.7485>; else goto <D.7486>;
  <D.7485>:
  GC_grow_table (&fo_head, &log_fo_table_size);
  GC_print_stats.26 = GC_print_stats;
  if (GC_print_stats.26 != 0) goto <D.7492>; else goto <D.7493>;
  <D.7492>:
  log_fo_table_size.24 = log_fo_table_size;
  D.7494 = 1 << log_fo_table_size.24;
  GC_printf ("Grew fo table to %lu entries\n", D.7494, 0, 0, 0, 0, 0);
  <D.7493>:
  <D.7486>:
  base = obj;
  base.27 = (long unsigned int) base;
  D.7496 = base.27 >> 3;
  base.27 = (long unsigned int) base;
  log_fo_table_size.24 = log_fo_table_size;
  D.7497 = log_fo_table_size.24 + 3;
  D.7498 = base.27 >> D.7497;
  D.7499 = D.7496 ^ D.7498;
  log_fo_table_size.24 = log_fo_table_size;
  D.7494 = 1 << log_fo_table_size.24;
  D.7500 = D.7494 + -1;
  D.7501 = (long unsigned int) D.7500;
  D.7502 = D.7499 & D.7501;
  index = (int) D.7502;
  prev_fo = 0B;
  fo_head.28 = fo_head;
  index.29 = (unsigned int) index;
  D.7505 = index.29 * 4;
  D.7506 = fo_head.28 + D.7505;
  curr_fo = *D.7506;
  goto <D.7139>;
  <D.7138>:
  D.7507 = curr_fo->prolog.hidden_key;
  base.27 = (long unsigned int) base;
  D.7508 = ~base.27;
  if (D.7507 == D.7508) goto <D.7509>; else goto <D.7510>;
  <D.7509>:
  if (ocd != 0B) goto <D.7511>; else goto <D.7512>;
  <D.7511>:
  D.7513 = curr_fo->fo_client_data;
  *ocd = D.7513;
  <D.7512>:
  if (ofn != 0B) goto <D.7514>; else goto <D.7515>;
  <D.7514>:
  D.7516 = curr_fo->fo_fn;
  *ofn = D.7516;
  <D.7515>:
  if (prev_fo == 0B) goto <D.7517>; else goto <D.7518>;
  <D.7517>:
  fo_head.28 = fo_head;
  index.29 = (unsigned int) index;
  D.7505 = index.29 * 4;
  D.7506 = fo_head.28 + D.7505;
  D.7519 = curr_fo->prolog.next;
  *D.7506 = D.7519;
  goto <D.7520>;
  <D.7518>:
  D.7519 = curr_fo->prolog.next;
  prev_fo->prolog.next = D.7519;
  <D.7520>:
  if (fn == 0B) goto <D.7521>; else goto <D.7522>;
  <D.7521>:
  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.7524>;
  <D.7522>:
  curr_fo->fo_fn = fn;
  curr_fo->fo_client_data = cd;
  curr_fo->fo_mark_proc = mp;
  if (prev_fo == 0B) goto <D.7525>; else goto <D.7526>;
  <D.7525>:
  fo_head.28 = fo_head;
  index.29 = (unsigned int) index;
  D.7505 = index.29 * 4;
  D.7506 = fo_head.28 + D.7505;
  *D.7506 = curr_fo;
  goto <D.7527>;
  <D.7526>:
  prev_fo->prolog.next = curr_fo;
  <D.7527>:
  <D.7524>:
  GC_clear (&GC_allocate_lock);
  return;
  <D.7510>:
  prev_fo = curr_fo;
  curr_fo = curr_fo->prolog.next;
  <D.7139>:
  if (curr_fo != 0B) goto <D.7138>; else goto <D.7140>;
  <D.7140>:
  if (ofn != 0B) goto <D.7528>; else goto <D.7529>;
  <D.7528>:
  *ofn = 0B;
  <D.7529>:
  if (ocd != 0B) goto <D.7530>; else goto <D.7531>;
  <D.7530>:
  *ocd = 0B;
  <D.7531>:
  if (fn == 0B) goto <D.7532>; else goto <D.7533>;
  <D.7532>:
  GC_clear (&GC_allocate_lock);
  return;
  <D.7533>:
  base.27 = (long unsigned int) base;
  D.7534 = base.27 >> 22;
  D.7535 = GC_arrays._top_index[D.7534];
  base.27 = (long unsigned int) base;
  D.7536 = base.27 >> 12;
  D.7537 = D.7536 & 1023;
  hhdr = D.7535->index[D.7537];
  if (hhdr == 0B) goto <D.7538>; else goto <D.7539>;
  <D.7538>:
  GC_clear (&GC_allocate_lock);
  return;
  <D.7539>:
  new_fo = GC_generic_malloc_inner (24, 1);
  if (new_fo == 0B) goto <D.7540>; else goto <D.7541>;
  <D.7540>:
  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.7543>; else goto <D.7544>;
  <D.7543>:
  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.7544>:
  D.7547 = GC_test_and_set (&GC_allocate_lock);
  if (D.7547 != 0) goto <D.7548>; else goto <D.7549>;
  <D.7548>:
  GC_lock ();
  <D.7549>:
  <D.7541>:
  base.27 = (long unsigned int) base;
  D.7508 = ~base.27;
  new_fo->prolog.hidden_key = D.7508;
  new_fo->fo_fn = fn;
  new_fo->fo_client_data = cd;
  D.7550 = hhdr->hb_sz;
  new_fo->fo_object_size = D.7550;
  new_fo->fo_mark_proc = mp;
  fo_head.28 = fo_head;
  index.29 = (unsigned int) index;
  D.7505 = index.29 * 4;
  D.7506 = fo_head.28 + D.7505;
  D.7551 = *D.7506;
  new_fo->prolog.next = D.7551;
  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.7505 = index.29 * 4;
  D.7506 = fo_head.28 + D.7505;
  *D.7506 = 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.7561;
  struct finalizable_object * * D.7562;
  long unsigned int D.7563;
  long unsigned int D.7564;
  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.7556>; else goto <D.7557>;
  <D.7556>:
  log_fo_table_size.36 = log_fo_table_size;
  iftmp.35 = 1 << log_fo_table_size.36;
  goto <D.7558>;
  <D.7557>:
  iftmp.35 = 0;
  <D.7558>:
  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.7186>;
  <D.7185>:
  fo_head.37 = fo_head;
  i.38 = (unsigned int) i;
  D.7561 = i.38 * 4;
  D.7562 = fo_head.37 + D.7561;
  curr_fo = *D.7562;
  goto <D.7183>;
  <D.7182>:
  D.7563 = curr_fo->prolog.hidden_key;
  D.7564 = ~D.7563;
  real_ptr = (char *) D.7564;
  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.7183>:
  if (curr_fo != 0B) goto <D.7182>; else goto <D.7184>;
  <D.7184>:
  i = i + 1;
  <D.7186>:
  if (i < fo_size) goto <D.7185>; else goto <D.7187>;
  <D.7187>:
}


GC_dump_finalization_links (struct dl_hashtbl_s * dl_hashtbl)
{
  size_t iftmp.40;
  long int D.7567;
  int D.7570;
  struct disappearing_link * * D.7572;
  unsigned int i.41;
  unsigned int D.7574;
  struct disappearing_link * * D.7575;
  long unsigned int D.7576;
  long unsigned int D.7577;
  long unsigned int D.7578;
  long unsigned int D.7579;
  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.7567 = dl_hashtbl->log_size;
  if (D.7567 != -1) goto <D.7568>; else goto <D.7569>;
  <D.7568>:
  D.7567 = dl_hashtbl->log_size;
  D.7570 = 1 << D.7567;
  iftmp.40 = (size_t) D.7570;
  goto <D.7571>;
  <D.7569>:
  iftmp.40 = 0;
  <D.7571>:
  dl_size = iftmp.40;
  i = 0;
  goto <D.7174>;
  <D.7173>:
  D.7572 = dl_hashtbl->head;
  i.41 = (unsigned int) i;
  D.7574 = i.41 * 4;
  D.7575 = D.7572 + D.7574;
  curr_dl = *D.7575;
  goto <D.7171>;
  <D.7170>:
  D.7576 = curr_dl->dl_hidden_obj;
  D.7577 = ~D.7576;
  real_ptr = (char *) D.7577;
  D.7578 = curr_dl->prolog.hidden_key;
  D.7579 = ~D.7578;
  real_link = (char *) D.7579;
  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.7171>:
  if (curr_dl != 0B) goto <D.7170>; else goto <D.7172>;
  <D.7172>:
  i = i + 1;
  <D.7174>:
  i.44 = (unsigned int) i;
  if (i.44 < dl_size) goto <D.7173>; else goto <D.7175>;
  <D.7175>:
}


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.7590;
  struct finalizable_object * * D.7591;
  long unsigned int D.7592;
  long unsigned int D.7593;
  int D.7594;
  void (*<T1729>) () D.7597;
  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.7601;
  struct mse * D.7602;
  struct mse * GC_mark_stack_top.52;
  int D.7604;
  int GC_mark_state.53;
  int D.7608;
  int D.7609;
  void (*<Tdd1>) (char *, GC_word) GC_current_warn_proc.54;
  long unsigned int real_ptr.55;
  int D.7614;
  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.7626;
  long unsigned int D.7627;
  int GC_all_interior_pointers.60;
  long unsigned int GC_all_interior_pointers.61;
  long unsigned int D.7630;
  long unsigned int D.7631;
  long unsigned int D.7632;
  long unsigned int D.7633;
  unsigned int GC_all_interior_pointers.62;
  unsigned int D.7635;
  unsigned int D.7636;
  long unsigned int D.7637;
  long unsigned int D.7638;
  long unsigned int D.7639;
  int D.7643;
  struct mse * GC_mark_stack_top.63;
  int D.7649;
  int D.7652;
  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.7585>; else goto <D.7586>;
  <D.7585>:
  log_fo_table_size.46 = log_fo_table_size;
  iftmp.45 = 1 << log_fo_table_size.46;
  goto <D.7587>;
  <D.7586>:
  iftmp.45 = 0;
  <D.7587>:
  fo_size = iftmp.45;
  GC_make_disappearing_links_disappear (&GC_dl_hashtbl);
  i = 0;
  goto <D.7238>;
  <D.7237>:
  fo_head.47 = fo_head;
  i.48 = (unsigned int) i;
  D.7590 = i.48 * 4;
  D.7591 = fo_head.47 + D.7590;
  curr_fo = *D.7591;
  goto <D.7235>;
  <D.7234>:
  D.7592 = curr_fo->prolog.hidden_key;
  D.7593 = ~D.7592;
  real_ptr = (char *) D.7593;
  D.7594 = GC_is_marked (real_ptr);
  if (D.7594 == 0) goto <D.7595>; else goto <D.7596>;
  <D.7595>:
  D.7597 = curr_fo->fo_mark_proc;
  D.7597 (real_ptr);
  goto <D.7229>;
  <D.7228>:
  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.7601 = GC_mark_stack_size.51 * 8;
  D.7602 = GC_mark_stack.50 + D.7601;
  GC_mark_stack_top.52 = GC_mark_from (GC_mark_stack_top.49, GC_mark_stack.50, D.7602);
  GC_mark_stack_top = GC_mark_stack_top.52;
  <D.7229>:
  D.7604 = GC_mark_stack_empty ();
  if (D.7604 == 0) goto <D.7228>; else goto <D.7230>;
  <D.7230>:
  GC_mark_state.53 = GC_mark_state;
  if (GC_mark_state.53 != 0) goto <D.7606>; else goto <D.7607>;
  <D.7606>:
  GC_set_mark_bit (real_ptr);
  goto <D.7232>;
  <D.7231>:
  <D.7232>:
  D.7608 = GC_mark_some (0B);
  if (D.7608 == 0) goto <D.7231>; else goto <D.7233>;
  <D.7233>:
  <D.7607>:
  D.7609 = GC_is_marked (real_ptr);
  if (D.7609 != 0) goto <D.7610>; else goto <D.7611>;
  <D.7610>:
  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.7611>:
  <D.7596>:
  curr_fo = curr_fo->prolog.next;
  <D.7235>:
  if (curr_fo != 0B) goto <D.7234>; else goto <D.7236>;
  <D.7236>:
  i = i + 1;
  <D.7238>:
  if (i < fo_size) goto <D.7237>; else goto <D.7239>;
  <D.7239>:
  GC_arrays._words_finalized = 0;
  i = 0;
  goto <D.7244>;
  <D.7243>:
  fo_head.47 = fo_head;
  i.48 = (unsigned int) i;
  D.7590 = i.48 * 4;
  D.7591 = fo_head.47 + D.7590;
  curr_fo = *D.7591;
  prev_fo = 0B;
  goto <D.7241>;
  <D.7240>:
  D.7592 = curr_fo->prolog.hidden_key;
  D.7593 = ~D.7592;
  real_ptr = (char *) D.7593;
  D.7614 = GC_is_marked (real_ptr);
  if (D.7614 == 0) goto <D.7615>; else goto <D.7616>;
  <D.7615>:
  GC_java_finalization.56 = GC_java_finalization;
  if (GC_java_finalization.56 == 0) goto <D.7618>; else goto <D.7619>;
  <D.7618>:
  GC_set_mark_bit (real_ptr);
  <D.7619>:
  next_fo = curr_fo->prolog.next;
  if (prev_fo == 0B) goto <D.7620>; else goto <D.7621>;
  <D.7620>:
  fo_head.47 = fo_head;
  i.48 = (unsigned int) i;
  D.7590 = i.48 * 4;
  D.7591 = fo_head.47 + D.7590;
  *D.7591 = next_fo;
  goto <D.7622>;
  <D.7621>:
  prev_fo->prolog.next = next_fo;
  <D.7622>:
  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.7592 = curr_fo->prolog.hidden_key;
  D.7593 = ~D.7592;
  curr_fo->prolog.hidden_key = D.7593;
  D.7626 = GC_arrays._words_finalized;
  D.7627 = 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.7630 = D.7627 + GC_all_interior_pointers.61;
  D.7631 = D.7630 + 7;
  D.7632 = D.7631 >> 2;
  D.7633 = D.7632 & 4294967294;
  GC_all_interior_pointers.60 = GC_all_interior_pointers;
  GC_all_interior_pointers.62 = (unsigned int) GC_all_interior_pointers.60;
  D.7635 = GC_all_interior_pointers.62 + 31;
  D.7636 = D.7635 >> 2;
  D.7637 = D.7636 & 4294967294;
  D.7638 = D.7633 + D.7637;
  D.7639 = D.7626 + D.7638;
  GC_arrays._words_finalized = D.7639;
  curr_fo = next_fo;
  goto <D.7640>;
  <D.7616>:
  prev_fo = curr_fo;
  curr_fo = curr_fo->prolog.next;
  <D.7640>:
  <D.7241>:
  if (curr_fo != 0B) goto <D.7240>; else goto <D.7242>;
  <D.7242>:
  i = i + 1;
  <D.7244>:
  if (i < fo_size) goto <D.7243>; else goto <D.7245>;
  <D.7245>:
  GC_java_finalization.56 = GC_java_finalization;
  if (GC_java_finalization.56 != 0) goto <D.7641>; else goto <D.7642>;
  <D.7641>:
  curr_fo = GC_finalize_now;
  goto <D.7253>;
  <D.7252>:
  D.7592 = curr_fo->prolog.hidden_key;
  real_ptr = (char *) D.7592;
  D.7643 = GC_is_marked (real_ptr);
  if (D.7643 == 0) goto <D.7644>; else goto <D.7645>;
  <D.7644>:
  D.7597 = curr_fo->fo_mark_proc;
  if (D.7597 == GC_null_finalize_mark_proc) goto <D.7646>; else goto <D.7647>;
  <D.7646>:
  GC_normal_finalize_mark_proc (real_ptr);
  goto <D.7247>;
  <D.7246>:
  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.7601 = GC_mark_stack_size.51 * 8;
  D.7602 = GC_mark_stack.50 + D.7601;
  GC_mark_stack_top.63 = GC_mark_from (GC_mark_stack_top.49, GC_mark_stack.50, D.7602);
  GC_mark_stack_top = GC_mark_stack_top.63;
  <D.7247>:
  D.7649 = GC_mark_stack_empty ();
  if (D.7649 == 0) goto <D.7246>; else goto <D.7248>;
  <D.7248>:
  GC_mark_state.53 = GC_mark_state;
  if (GC_mark_state.53 != 0) goto <D.7650>; else goto <D.7651>;
  <D.7650>:
  GC_set_mark_bit (real_ptr);
  goto <D.7250>;
  <D.7249>:
  <D.7250>:
  D.7652 = GC_mark_some (0B);
  if (D.7652 == 0) goto <D.7249>; else goto <D.7251>;
  <D.7251>:
  <D.7651>:
  <D.7647>:
  GC_set_mark_bit (real_ptr);
  <D.7645>:
  curr_fo = curr_fo->prolog.next;
  <D.7253>:
  if (curr_fo != 0B) goto <D.7252>; else goto <D.7254>;
  <D.7254>:
  <D.7642>:
  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.7654;
  struct disappearing_link * * D.7658;
  unsigned int i.65;
  unsigned int D.7660;
  struct disappearing_link * * D.7661;
  long unsigned int D.7662;
  long unsigned int D.7663;
  long unsigned int D.7664;
  long unsigned int D.7665;
  int D.7666;
  long unsigned int D.7672;
  long unsigned int D.7673;
  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.7654 = dl_hashtbl->log_size;
  if (D.7654 != -1) goto <D.7655>; else goto <D.7656>;
  <D.7655>:
  D.7654 = dl_hashtbl->log_size;
  iftmp.64 = 1 << D.7654;
  goto <D.7657>;
  <D.7656>:
  iftmp.64 = 0;
  <D.7657>:
  dl_size = iftmp.64;
  i = 0;
  goto <D.7202>;
  <D.7201>:
  D.7658 = dl_hashtbl->head;
  i.65 = (unsigned int) i;
  D.7660 = i.65 * 4;
  D.7661 = D.7658 + D.7660;
  curr_dl = *D.7661;
  prev_dl = 0B;
  goto <D.7199>;
  <D.7198>:
  D.7662 = curr_dl->dl_hidden_obj;
  D.7663 = ~D.7662;
  real_ptr = (char *) D.7663;
  D.7664 = curr_dl->prolog.hidden_key;
  D.7665 = ~D.7664;
  real_link = (char *) D.7665;
  D.7666 = GC_is_marked (real_ptr);
  if (D.7666 == 0) goto <D.7667>; else goto <D.7668>;
  <D.7667>:
  MEM[(word *)real_link] = 0;
  next_dl = curr_dl->prolog.next;
  if (prev_dl == 0B) goto <D.7669>; else goto <D.7670>;
  <D.7669>:
  D.7658 = dl_hashtbl->head;
  i.65 = (unsigned int) i;
  D.7660 = i.65 * 4;
  D.7661 = D.7658 + D.7660;
  *D.7661 = next_dl;
  goto <D.7671>;
  <D.7670>:
  prev_dl->prolog.next = next_dl;
  <D.7671>:
  GC_clear_mark_bit (curr_dl);
  D.7672 = dl_hashtbl->entries;
  D.7673 = D.7672 + 4294967295;
  dl_hashtbl->entries = D.7673;
  curr_dl = next_dl;
  goto <D.7674>;
  <D.7668>:
  prev_dl = curr_dl;
  curr_dl = curr_dl->prolog.next;
  <D.7674>:
  <D.7199>:
  if (curr_dl != 0B) goto <D.7198>; else goto <D.7200>;
  <D.7200>:
  i = i + 1;
  <D.7202>:
  if (i < dl_size) goto <D.7201>; else goto <D.7203>;
  <D.7203>:
}


GC_remove_dangling_disappearing_links (struct dl_hashtbl_s * dl_hashtbl)
{
  int iftmp.66;
  long int D.7676;
  struct disappearing_link * * D.7680;
  unsigned int i.67;
  unsigned int D.7682;
  struct disappearing_link * * D.7683;
  long unsigned int D.7684;
  long unsigned int D.7685;
  void * D.7686;
  int D.7690;
  long unsigned int D.7695;
  long unsigned int D.7696;
  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.7676 = dl_hashtbl->log_size;
  if (D.7676 != -1) goto <D.7677>; else goto <D.7678>;
  <D.7677>:
  D.7676 = dl_hashtbl->log_size;
  iftmp.66 = 1 << D.7676;
  goto <D.7679>;
  <D.7678>:
  iftmp.66 = 0;
  <D.7679>:
  dl_size = iftmp.66;
  i = 0;
  goto <D.7218>;
  <D.7217>:
  D.7680 = dl_hashtbl->head;
  i.67 = (unsigned int) i;
  D.7682 = i.67 * 4;
  D.7683 = D.7680 + D.7682;
  curr_dl = *D.7683;
  prev_dl = 0B;
  goto <D.7215>;
  <D.7214>:
  D.7684 = curr_dl->prolog.hidden_key;
  D.7685 = ~D.7684;
  D.7686 = (void *) D.7685;
  real_link = GC_base (D.7686);
  if (real_link != 0B) goto <D.7689>; else goto <D.7687>;
  <D.7689>:
  D.7690 = GC_is_marked (real_link);
  if (D.7690 == 0) goto <D.7691>; else goto <D.7687>;
  <D.7691>:
  next_dl = curr_dl->prolog.next;
  if (prev_dl == 0B) goto <D.7692>; else goto <D.7693>;
  <D.7692>:
  D.7680 = dl_hashtbl->head;
  i.67 = (unsigned int) i;
  D.7682 = i.67 * 4;
  D.7683 = D.7680 + D.7682;
  *D.7683 = next_dl;
  goto <D.7694>;
  <D.7693>:
  prev_dl->prolog.next = next_dl;
  <D.7694>:
  GC_clear_mark_bit (curr_dl);
  D.7695 = dl_hashtbl->entries;
  D.7696 = D.7695 + 4294967295;
  dl_hashtbl->entries = D.7696;
  curr_dl = next_dl;
  goto <D.7688>;
  <D.7687>:
  prev_dl = curr_dl;
  curr_dl = curr_dl->prolog.next;
  <D.7688>:
  <D.7215>:
  if (curr_dl != 0B) goto <D.7214>; else goto <D.7216>;
  <D.7216>:
  i = i + 1;
  <D.7218>:
  if (i < dl_size) goto <D.7217>; else goto <D.7219>;
  <D.7219>:
}


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.7704;
  struct finalizable_object * * D.7705;
  long unsigned int D.7706;
  long unsigned int D.7707;
  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.7711;
  struct mse * D.7712;
  struct mse * GC_mark_stack_top.75;
  int D.7714;
  int GC_mark_state.76;
  int D.7718;
  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.7725;
  long unsigned int D.7726;
  int GC_all_interior_pointers.80;
  long unsigned int GC_all_interior_pointers.81;
  long unsigned int D.7729;
  long unsigned int D.7730;
  long unsigned int D.7731;
  long unsigned int D.7732;
  unsigned int GC_all_interior_pointers.82;
  unsigned int D.7734;
  unsigned int D.7735;
  long unsigned int D.7736;
  long unsigned int D.7737;
  long unsigned int D.7738;
  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.7699>; else goto <D.7700>;
  <D.7699>:
  log_fo_table_size.69 = log_fo_table_size;
  iftmp.68 = 1 << log_fo_table_size.69;
  goto <D.7701>;
  <D.7700>:
  iftmp.68 = 0;
  <D.7701>:
  fo_size = iftmp.68;
  GC_arrays._words_finalized = 0;
  i = 0;
  goto <D.7273>;
  <D.7272>:
  fo_head.70 = fo_head;
  i.71 = (unsigned int) i;
  D.7704 = i.71 * 4;
  D.7705 = fo_head.70 + D.7704;
  curr_fo = *D.7705;
  prev_fo = 0B;
  goto <D.7270>;
  <D.7269>:
  D.7706 = curr_fo->prolog.hidden_key;
  D.7707 = ~D.7706;
  real_ptr = (char *) D.7707;
  GC_normal_finalize_mark_proc (real_ptr);
  goto <D.7264>;
  <D.7263>:
  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.7711 = GC_mark_stack_size.74 * 8;
  D.7712 = GC_mark_stack.73 + D.7711;
  GC_mark_stack_top.75 = GC_mark_from (GC_mark_stack_top.72, GC_mark_stack.73, D.7712);
  GC_mark_stack_top = GC_mark_stack_top.75;
  <D.7264>:
  D.7714 = GC_mark_stack_empty ();
  if (D.7714 == 0) goto <D.7263>; else goto <D.7265>;
  <D.7265>:
  GC_mark_state.76 = GC_mark_state;
  if (GC_mark_state.76 != 0) goto <D.7716>; else goto <D.7717>;
  <D.7716>:
  GC_set_mark_bit (real_ptr);
  goto <D.7267>;
  <D.7266>:
  <D.7267>:
  D.7718 = GC_mark_some (0B);
  if (D.7718 == 0) goto <D.7266>; else goto <D.7268>;
  <D.7268>:
  <D.7717>:
  GC_set_mark_bit (real_ptr);
  next_fo = curr_fo->prolog.next;
  if (prev_fo == 0B) goto <D.7719>; else goto <D.7720>;
  <D.7719>:
  fo_head.70 = fo_head;
  i.71 = (unsigned int) i;
  D.7704 = i.71 * 4;
  D.7705 = fo_head.70 + D.7704;
  *D.7705 = next_fo;
  goto <D.7721>;
  <D.7720>:
  prev_fo->prolog.next = next_fo;
  <D.7721>:
  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.7706 = curr_fo->prolog.hidden_key;
  D.7707 = ~D.7706;
  curr_fo->prolog.hidden_key = D.7707;
  D.7725 = GC_arrays._words_finalized;
  D.7726 = 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.7729 = D.7726 + GC_all_interior_pointers.81;
  D.7730 = D.7729 + 7;
  D.7731 = D.7730 >> 2;
  D.7732 = D.7731 & 4294967294;
  GC_all_interior_pointers.80 = GC_all_interior_pointers;
  GC_all_interior_pointers.82 = (unsigned int) GC_all_interior_pointers.80;
  D.7734 = GC_all_interior_pointers.82 + 31;
  D.7735 = D.7734 >> 2;
  D.7736 = D.7735 & 4294967294;
  D.7737 = D.7732 + D.7736;
  D.7738 = D.7725 + D.7737;
  GC_arrays._words_finalized = D.7738;
  curr_fo = next_fo;
  <D.7270>:
  if (curr_fo != 0B) goto <D.7269>; else goto <D.7271>;
  <D.7271>:
  i = i + 1;
  <D.7273>:
  if (i < fo_size) goto <D.7272>; else goto <D.7274>;
  <D.7274>:
  return;
}


GC_finalize_all ()
{
  int D.7740;
  int D.7743;
  long unsigned int GC_fo_entries.83;

  D.7740 = GC_test_and_set (&GC_allocate_lock);
  if (D.7740 != 0) goto <D.7741>; else goto <D.7742>;
  <D.7741>:
  GC_lock ();
  <D.7742>:
  goto <D.7278>;
  <D.7277>:
  GC_enqueue_all_finalizers ();
  GC_clear (&GC_allocate_lock);
  GC_notify_or_invoke_finalizers ();
  D.7743 = GC_test_and_set (&GC_allocate_lock);
  if (D.7743 != 0) goto <D.7744>; else goto <D.7745>;
  <D.7744>:
  GC_lock ();
  <D.7745>:
  <D.7278>:
  GC_fo_entries.83 = GC_fo_entries;
  if (GC_fo_entries.83 != 0) goto <D.7277>; else goto <D.7279>;
  <D.7279>:
  GC_clear (&GC_allocate_lock);
}


GC_should_invoke_finalizers ()
{
  int D.7747;
  struct finalizable_object * GC_finalize_now.84;
  _Bool D.7749;

  GC_finalize_now.84 = GC_finalize_now;
  D.7749 = GC_finalize_now.84 != 0B;
  D.7747 = (int) D.7749;
  return D.7747;
}


GC_invoke_finalizers ()
{
  int D.7751;
  struct hash_chain_entry * GC_finalize_now.85;
  void (*<Tdb2>) (void *, void *) D.7760;
  long unsigned int D.7761;
  void * D.7762;
  char * D.7763;
  struct finalizable_object * GC_finalize_now.86;
  long unsigned int D.7767;
  int D.7770;
  long unsigned int D.7773;
  long unsigned int D.7774;
  long unsigned int D.7775;
  int D.7776;
  struct finalizable_object * curr_fo;
  int count;
  word mem_freed_before;

  count = 0;
  goto <D.7290>;
  <D.7289>:
  D.7751 = GC_test_and_set (&GC_allocate_lock);
  if (D.7751 != 0) goto <D.7752>; else goto <D.7753>;
  <D.7752>:
  GC_lock ();
  <D.7753>:
  if (count == 0) goto <D.7754>; else goto <D.7755>;
  <D.7754>:
  mem_freed_before = GC_arrays._mem_freed;
  <D.7755>:
  curr_fo = GC_finalize_now;
  if (curr_fo != 0B) goto <D.7756>; else goto <D.7757>;
  <D.7756>:
  GC_finalize_now.85 = curr_fo->prolog.next;
  GC_finalize_now = GC_finalize_now.85;
  <D.7757>:
  GC_clear (&GC_allocate_lock);
  if (curr_fo == 0B) goto <D.7288>; else goto <D.7759>;
  <D.7759>:
  curr_fo->prolog.next = 0B;
  D.7760 = curr_fo->fo_fn;
  D.7761 = curr_fo->prolog.hidden_key;
  D.7762 = (void *) D.7761;
  D.7763 = curr_fo->fo_client_data;
  D.7760 (D.7762, D.7763);
  curr_fo->fo_client_data = 0B;
  count = count + 1;
  <D.7290>:
  GC_finalize_now.86 = GC_finalize_now;
  if (GC_finalize_now.86 != 0B) goto <D.7289>; else goto <D.7288>;
  <D.7288>:
  if (count != 0) goto <D.7765>; else goto <D.7766>;
  <D.7765>:
  D.7767 = GC_arrays._mem_freed;
  if (D.7767 != mem_freed_before) goto <D.7768>; else goto <D.7769>;
  <D.7768>:
  D.7770 = GC_test_and_set (&GC_allocate_lock);
  if (D.7770 != 0) goto <D.7771>; else goto <D.7772>;
  <D.7771>:
  GC_lock ();
  <D.7772>:
  D.7773 = GC_arrays._finalizer_mem_freed;
  D.7767 = GC_arrays._mem_freed;
  D.7774 = D.7767 - mem_freed_before;
  D.7775 = D.7773 + D.7774;
  GC_arrays._finalizer_mem_freed = D.7775;
  GC_clear (&GC_allocate_lock);
  <D.7769>:
  <D.7766>:
  D.7776 = count;
  return D.7776;
}


GC_notify_or_invoke_finalizers ()
{
  struct finalizable_object * GC_finalize_now.87;
  int GC_finalize_on_demand.88;
  void (*<Td5b>) (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.7779>; else goto <D.7780>;
  <D.7779>:
  return;
  <D.7780>:
  GC_finalize_on_demand.88 = GC_finalize_on_demand;
  if (GC_finalize_on_demand.88 == 0) goto <D.7782>; else goto <D.7783>;
  <D.7782>:
  GC_invoke_finalizers ();
  return;
  <D.7783>:
  GC_finalizer_notifier.89 = GC_finalizer_notifier;
  if (GC_finalizer_notifier.89 != 0B) goto <D.7785>; else goto <D.7786>;
  <D.7785>:
  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.7789>; else goto <D.7790>;
  <D.7789>:
  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.7790>:
  <D.7786>:
}


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

  D.7792 = GC_test_and_set (&GC_allocate_lock);
  if (D.7792 != 0) goto <D.7793>; else goto <D.7794>;
  <D.7793>:
  GC_lock ();
  <D.7794>:
  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.7796 = result;
  return D.7796;
}


GC_print_finalization_stats ()
{
  long unsigned int GC_fo_entries.93;
  long int GC_fo_entries.94;
  long unsigned int D.7800;
  long int D.7801;
  long unsigned int D.7802;
  long int D.7803;
  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.7800 = GC_dl_hashtbl.entries;
  D.7801 = (long int) D.7800;
  D.7802 = GC_ll_hashtbl.entries;
  D.7803 = (long int) D.7802;
  GC_printf ("%lu finalization table entries; %lu/%lu short/long disappearing links alive\n", GC_fo_entries.94, D.7801, D.7803, 0, 0, 0);
  goto <D.7308>;
  <D.7307>:
  ready = ready + 1;
  fo = fo->prolog.next;
  <D.7308>:
  if (fo != 0B) goto <D.7307>; else goto <D.7309>;
  <D.7309>:
  ready.95 = (long int) ready;
  GC_printf ("%lu objects are eligible for immediate finalization\n", ready.95, 0, 0, 0, 0, 0);
}


