GC_push_finalizer_structures ()
{
  char * D.5244;
  char * D.5245;
  char * D.5246;
  char * D.5247;

  D.5244 = &GC_ll_hashtbl.head + 8;
  GC_push_all (&GC_ll_hashtbl.head, D.5244);
  D.5245 = &GC_dl_hashtbl.head + 8;
  GC_push_all (&GC_dl_hashtbl.head, D.5245);
  D.5246 = &fo_head + 8;
  GC_push_all (&fo_head, D.5246);
  D.5247 = &GC_finalize_now + 8;
  GC_push_all (&GC_finalize_now, D.5247);
}


GC_grow_table (struct hash_chain_entry * * * table, signed_word * log_size_ptr)
{
  long int D.5248;
  word iftmp.0;
  int D.5252;
  int D.5254;
  long unsigned int D.5255;
  struct hash_chain_entry * * D.5261;
  long unsigned int D.5262;
  struct hash_chain_entry * * D.5263;
  long unsigned int D.5264;
  long unsigned int D.5265;
  long unsigned int real_key.1;
  long unsigned int D.5267;
  unsigned int D.5268;
  int D.5269;
  long unsigned int D.5270;
  unsigned int D.5271;
  unsigned int D.5272;
  unsigned int D.5273;
  unsigned int D.5274;
  unsigned int D.5275;
  long unsigned int D.5276;
  long unsigned int D.5277;
  struct hash_chain_entry * * D.5278;
  struct hash_chain_entry * D.5279;
  long int D.5280;
  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;

  D.5248 = *log_size_ptr;
  log_old_size = (int) D.5248;
  log_new_size = log_old_size + 1;
  if (log_old_size != -1) goto <D.5250>; else goto <D.5251>;
  <D.5250>:
  D.5252 = 1 << log_old_size;
  iftmp.0 = (word) D.5252;
  goto <D.5253>;
  <D.5251>:
  iftmp.0 = 0;
  <D.5253>:
  old_size = iftmp.0;
  D.5254 = 1 << log_new_size;
  new_size = (word) D.5254;
  D.5255 = new_size * 8;
  new_table = GC_generic_malloc_inner_ignore_off_page (D.5255, 1);
  if (new_table == 0B) goto <D.5256>; else goto <D.5257>;
  <D.5256>:
  if (table == 0B) goto <D.5258>; else goto <D.5259>;
  <D.5258>:
  GC_abort ("Insufficient space for initial table allocation");
  goto <D.5260>;
  <D.5259>:
  return;
  <D.5260>:
  <D.5257>:
  i = 0;
  goto <D.4988>;
  <D.4987>:
  D.5261 = *table;
  D.5262 = i * 8;
  D.5263 = D.5261 + D.5262;
  p = *D.5263;
  goto <D.4985>;
  <D.4984>:
  {
    register char * real_key;
    register struct hash_chain_entry * next;
    register int new_hash;

    D.5264 = p->hidden_key;
    D.5265 = ~D.5264;
    real_key = (char *) D.5265;
    next = p->next;
    real_key.1 = (long unsigned int) real_key;
    D.5267 = real_key.1 >> 3;
    D.5268 = (unsigned int) D.5267;
    real_key.1 = (long unsigned int) real_key;
    D.5269 = log_new_size + 3;
    D.5270 = real_key.1 >> D.5269;
    D.5271 = (unsigned int) D.5270;
    D.5272 = D.5268 ^ D.5271;
    D.5273 = (unsigned int) new_size;
    D.5274 = D.5273 + 4294967295;
    D.5275 = D.5272 & D.5274;
    new_hash = (int) D.5275;
    D.5276 = (long unsigned int) new_hash;
    D.5277 = D.5276 * 8;
    D.5278 = new_table + D.5277;
    D.5279 = *D.5278;
    p->next = D.5279;
    D.5276 = (long unsigned int) new_hash;
    D.5277 = D.5276 * 8;
    D.5278 = new_table + D.5277;
    *D.5278 = p;
    p = next;
  }
  <D.4985>:
  if (p != 0B) goto <D.4984>; else goto <D.4986>;
  <D.4986>:
  i = i + 1;
  <D.4988>:
  if (i < old_size) goto <D.4987>; else goto <D.4989>;
  <D.4989>:
  D.5280 = (long int) log_new_size;
  *log_size_ptr = D.5280;
  *table = new_table;
}


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

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


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

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


GC_register_disappearing_link_inner (struct dl_hashtbl_s * dl_hashtbl, void * * link, void * obj)
{
  long unsigned int link.2;
  long unsigned int D.5289;
  int D.5292;
  long int D.5297;
  long unsigned int D.5299;
  unsigned int D.5300;
  long unsigned int D.5301;
  struct disappearing_link * * * D.5302;
  signed_word * D.5303;
  int GC_print_stats.3;
  int D.5307;
  long int D.5308;
  long unsigned int D.5309;
  unsigned int D.5310;
  unsigned int D.5311;
  long unsigned int D.5312;
  unsigned int D.5313;
  unsigned int D.5314;
  int D.5315;
  unsigned int D.5316;
  unsigned int D.5317;
  struct disappearing_link * * D.5318;
  long unsigned int D.5319;
  long unsigned int D.5320;
  struct disappearing_link * * D.5321;
  long unsigned int D.5322;
  long unsigned int D.5323;
  long unsigned int obj.4;
  long unsigned int D.5327;
  int D.5328;
  void * (*<T40d>) (size_t) GC_oom_fn.5;
  unsigned int GC_finalization_failures.6;
  unsigned int D.5335;
  int D.5336;
  struct disappearing_link * D.5339;
  long unsigned int D.5340;
  struct disappearing_link * curr_dl;
  int index;
  struct disappearing_link * new_dl;

  link.2 = (long unsigned int) link;
  D.5289 = link.2 & 7;
  if (D.5289 != 0) goto <D.5290>; else goto <D.5291>;
  <D.5290>:
  GC_abort ("Bad arg to GC_general_register_disappearing_link");
  <D.5291>:
  D.5292 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5292 != 0) goto <D.5293>; else goto <D.5294>;
  <D.5293>:
  GC_lock ();
  <D.5294>:
  D.5297 = dl_hashtbl->log_size;
  if (D.5297 == -1) goto <D.5295>; else goto <D.5298>;
  <D.5298>:
  D.5299 = dl_hashtbl->entries;
  D.5297 = dl_hashtbl->log_size;
  D.5300 = (unsigned int) D.5297;
  D.5301 = 1 << D.5300;
  if (D.5299 > D.5301) goto <D.5295>; else goto <D.5296>;
  <D.5295>:
  D.5302 = &dl_hashtbl->head;
  D.5303 = &dl_hashtbl->log_size;
  GC_grow_table (D.5302, D.5303);
  GC_print_stats.3 = GC_print_stats;
  if (GC_print_stats.3 != 0) goto <D.5305>; else goto <D.5306>;
  <D.5305>:
  D.5297 = dl_hashtbl->log_size;
  D.5300 = (unsigned int) D.5297;
  D.5307 = 1 << D.5300;
  D.5308 = (long int) D.5307;
  GC_printf ("Grew dl table to %lu entries\n", D.5308, 0, 0, 0, 0, 0);
  <D.5306>:
  <D.5296>:
  link.2 = (long unsigned int) link;
  D.5309 = link.2 >> 3;
  D.5310 = (unsigned int) D.5309;
  link.2 = (long unsigned int) link;
  D.5297 = dl_hashtbl->log_size;
  D.5300 = (unsigned int) D.5297;
  D.5311 = D.5300 + 3;
  D.5312 = link.2 >> D.5311;
  D.5313 = (unsigned int) D.5312;
  D.5314 = D.5310 ^ D.5313;
  D.5297 = dl_hashtbl->log_size;
  D.5300 = (unsigned int) D.5297;
  D.5307 = 1 << D.5300;
  D.5315 = D.5307 + -1;
  D.5316 = (unsigned int) D.5315;
  D.5317 = D.5314 & D.5316;
  index = (int) D.5317;
  D.5318 = dl_hashtbl->head;
  D.5319 = (long unsigned int) index;
  D.5320 = D.5319 * 8;
  D.5321 = D.5318 + D.5320;
  curr_dl = *D.5321;
  D.5318 = dl_hashtbl->head;
  D.5319 = (long unsigned int) index;
  D.5320 = D.5319 * 8;
  D.5321 = D.5318 + D.5320;
  curr_dl = *D.5321;
  goto <D.5007>;
  <D.5006>:
  D.5322 = curr_dl->prolog.hidden_key;
  link.2 = (long unsigned int) link;
  D.5323 = ~link.2;
  if (D.5322 == D.5323) goto <D.5324>; else goto <D.5325>;
  <D.5324>:
  obj.4 = (long unsigned int) obj;
  D.5327 = ~obj.4;
  curr_dl->dl_hidden_obj = D.5327;
  pthread_mutex_unlock (&GC_allocate_ml);
  D.5328 = 1;
  return D.5328;
  <D.5325>:
  curr_dl = curr_dl->prolog.next;
  <D.5007>:
  if (curr_dl != 0B) goto <D.5006>; else goto <D.5008>;
  <D.5008>:
  new_dl = GC_generic_malloc_inner (24, 1);
  if (new_dl == 0B) goto <D.5329>; else goto <D.5330>;
  <D.5329>:
  pthread_mutex_unlock (&GC_allocate_ml);
  GC_oom_fn.5 = GC_oom_fn;
  new_dl = GC_oom_fn.5 (24);
  if (new_dl == 0B) goto <D.5332>; else goto <D.5333>;
  <D.5332>:
  GC_finalization_failures.6 = GC_finalization_failures;
  D.5335 = GC_finalization_failures.6 + 1;
  GC_finalization_failures = D.5335;
  D.5328 = 0;
  return D.5328;
  <D.5333>:
  D.5336 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5336 != 0) goto <D.5337>; else goto <D.5338>;
  <D.5337>:
  GC_lock ();
  <D.5338>:
  <D.5330>:
  obj.4 = (long unsigned int) obj;
  D.5327 = ~obj.4;
  new_dl->dl_hidden_obj = D.5327;
  link.2 = (long unsigned int) link;
  D.5323 = ~link.2;
  new_dl->prolog.hidden_key = D.5323;
  D.5318 = dl_hashtbl->head;
  D.5319 = (long unsigned int) index;
  D.5320 = D.5319 * 8;
  D.5321 = D.5318 + D.5320;
  D.5339 = *D.5321;
  new_dl->prolog.next = D.5339;
  D.5318 = dl_hashtbl->head;
  D.5319 = (long unsigned int) index;
  D.5320 = D.5319 * 8;
  D.5321 = D.5318 + D.5320;
  *D.5321 = new_dl;
  D.5299 = dl_hashtbl->entries;
  D.5340 = D.5299 + 1;
  dl_hashtbl->entries = D.5340;
  pthread_mutex_unlock (&GC_allocate_ml);
  D.5328 = 0;
  return D.5328;
}


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

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


GC_unregister_disappearing_link_inner (struct dl_hashtbl_s * dl_hashtbl, void * * link)
{
  int D.5344;
  long unsigned int link.7;
  long unsigned int D.5348;
  unsigned int D.5349;
  long int D.5350;
  unsigned int D.5351;
  unsigned int D.5352;
  long unsigned int D.5353;
  unsigned int D.5354;
  unsigned int D.5355;
  int D.5356;
  int D.5357;
  unsigned int D.5358;
  unsigned int D.5359;
  long unsigned int D.5360;
  struct disappearing_link * * D.5362;
  long unsigned int D.5363;
  long unsigned int D.5364;
  struct disappearing_link * * D.5365;
  long unsigned int D.5366;
  long unsigned int D.5367;
  struct hash_chain_entry * D.5372;
  long unsigned int D.5374;
  long unsigned int D.5375;
  int D.5376;
  struct disappearing_link * curr_dl;
  struct disappearing_link * prev_dl;
  int index;
  void out = <<< error >>>;

  D.5344 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5344 != 0) goto <D.5345>; else goto <D.5346>;
  <D.5345>:
  GC_lock ();
  <D.5346>:
  link.7 = (long unsigned int) link;
  D.5348 = link.7 >> 3;
  D.5349 = (unsigned int) D.5348;
  link.7 = (long unsigned int) link;
  D.5350 = dl_hashtbl->log_size;
  D.5351 = (unsigned int) D.5350;
  D.5352 = D.5351 + 3;
  D.5353 = link.7 >> D.5352;
  D.5354 = (unsigned int) D.5353;
  D.5355 = D.5349 ^ D.5354;
  D.5350 = dl_hashtbl->log_size;
  D.5351 = (unsigned int) D.5350;
  D.5356 = 1 << D.5351;
  D.5357 = D.5356 + -1;
  D.5358 = (unsigned int) D.5357;
  D.5359 = D.5355 & D.5358;
  index = (int) D.5359;
  link.7 = (long unsigned int) link;
  D.5360 = link.7 & 7;
  if (D.5360 != 0) goto out; else goto <D.5361>;
  <D.5361>:
  prev_dl = 0B;
  D.5362 = dl_hashtbl->head;
  D.5363 = (long unsigned int) index;
  D.5364 = D.5363 * 8;
  D.5365 = D.5362 + D.5364;
  curr_dl = *D.5365;
  goto <D.5021>;
  <D.5020>:
  D.5366 = curr_dl->prolog.hidden_key;
  link.7 = (long unsigned int) link;
  D.5367 = ~link.7;
  if (D.5366 == D.5367) goto <D.5368>; else goto <D.5369>;
  <D.5368>:
  if (prev_dl == 0B) goto <D.5370>; else goto <D.5371>;
  <D.5370>:
  D.5362 = dl_hashtbl->head;
  D.5363 = (long unsigned int) index;
  D.5364 = D.5363 * 8;
  D.5365 = D.5362 + D.5364;
  D.5372 = curr_dl->prolog.next;
  *D.5365 = D.5372;
  goto <D.5373>;
  <D.5371>:
  D.5372 = curr_dl->prolog.next;
  prev_dl->prolog.next = D.5372;
  <D.5373>:
  D.5374 = dl_hashtbl->entries;
  D.5375 = D.5374 + 18446744073709551615;
  dl_hashtbl->entries = D.5375;
  pthread_mutex_unlock (&GC_allocate_ml);
  GC_free (curr_dl);
  D.5376 = 1;
  return D.5376;
  <D.5369>:
  prev_dl = curr_dl;
  curr_dl = curr_dl->prolog.next;
  <D.5021>:
  if (curr_dl != 0B) goto <D.5020>; else goto <D.5022>;
  <D.5022>:
  out:
  pthread_mutex_unlock (&GC_allocate_ml);
  D.5376 = 0;
  return D.5376;
}


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

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


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

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


GC_normal_finalize_mark_proc (char * p)
{
  struct mse * GC_mark_stack_top.8;
  struct mse * D.5386;
  struct mse * GC_mark_stack.9;
  long unsigned int GC_mark_stack_size.10;
  long unsigned int D.5389;
  struct mse * D.5390;
  struct mse * GC_mark_stack_top.11;
  struct mse * GC_mark_stack_top.12;
  struct mse * D.5395;
  struct mse * GC_mark_stack_top.13;
  struct mse * GC_mark_stack_top.14;
  struct hdr * hhdr;

  hhdr = GC_find_header (p);
  {
    register word _descr;

    _descr = hhdr->hb_descr;
    if (_descr == 0) goto <D.5382>; else goto <D.5383>;
    <D.5382>:
    goto <D.5384>;
    <D.5383>:
    GC_mark_stack_top.8 = GC_mark_stack_top;
    D.5386 = GC_mark_stack_top.8 + 16;
    GC_mark_stack_top = D.5386;
    GC_mark_stack.9 = GC_mark_stack;
    GC_mark_stack_size.10 = GC_mark_stack_size;
    D.5389 = GC_mark_stack_size.10 * 16;
    D.5390 = GC_mark_stack.9 + D.5389;
    GC_mark_stack_top.11 = GC_mark_stack_top;
    if (D.5390 <= GC_mark_stack_top.11) goto <D.5392>; else goto <D.5393>;
    <D.5392>:
    GC_mark_stack_top.12 = GC_mark_stack_top;
    D.5395 = GC_signal_mark_stack_overflow (GC_mark_stack_top.12);
    GC_mark_stack_top = D.5395;
    <D.5393>:
    GC_mark_stack_top.13 = GC_mark_stack_top;
    GC_mark_stack_top.13->mse_start = p;
    GC_mark_stack_top.14 = GC_mark_stack_top;
    GC_mark_stack_top.14->mse_descr = _descr;
    <D.5384>:
  }
}


GC_ignore_self_finalize_mark_proc (char * p)
{
  long unsigned int D.5398;
  long unsigned int D.5399;
  sizetype D.5400;
  long unsigned int D.5401;
  sizetype D.5404;
  void * GC_least_plausible_heap_addr.15;
  void * GC_greatest_plausible_heap_addr.16;
  struct mse * GC_mark_stack_top.17;
  struct mse * GC_mark_stack_limit.18;
  struct GC_ms_entry * D.5417;
  struct hdr * hhdr;
  word descr;
  char * q;
  char * r;
  char * scan_limit;
  char * target_limit;

  hhdr = GC_find_header (p);
  descr = hhdr->hb_descr;
  D.5398 = hhdr->hb_sz;
  D.5399 = D.5398 << 3;
  D.5400 = D.5399 + 18446744073709551615;
  target_limit = p + D.5400;
  D.5401 = descr & 3;
  if (D.5401 == 0) goto <D.5402>; else goto <D.5403>;
  <D.5402>:
  D.5404 = descr + 18446744073709551608;
  scan_limit = p + D.5404;
  goto <D.5405>;
  <D.5403>:
  scan_limit = target_limit + 18446744073709551609;
  <D.5405>:
  q = p;
  goto <D.5045>;
  <D.5044>:
  r = MEM[(char * *)q];
  if (r < p) goto <D.5406>; else goto <D.5408>;
  <D.5408>:
  if (r > target_limit) goto <D.5406>; else goto <D.5407>;
  <D.5406>:
  GC_least_plausible_heap_addr.15 = GC_least_plausible_heap_addr;
  if (r >= GC_least_plausible_heap_addr.15) goto <D.5410>; else goto <D.5411>;
  <D.5410>:
  GC_greatest_plausible_heap_addr.16 = GC_greatest_plausible_heap_addr;
  if (r < GC_greatest_plausible_heap_addr.16) goto <D.5413>; else goto <D.5414>;
  <D.5413>:
  GC_mark_stack_top.17 = GC_mark_stack_top;
  GC_mark_stack_limit.18 = GC_mark_stack_limit;
  D.5417 = GC_mark_and_push (r, GC_mark_stack_top.17, GC_mark_stack_limit.18, q);
  GC_mark_stack_top = D.5417;
  <D.5414>:
  <D.5411>:
  <D.5407>:
  q = q + 8;
  <D.5045>:
  if (q <= scan_limit) goto <D.5044>; else goto <D.5046>;
  <D.5046>:
}


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 (*<Te60>) () mp)
{
  int D.5418;
  long int log_fo_table_size.19;
  unsigned int D.5425;
  long unsigned int D.5426;
  long unsigned int GC_fo_entries.20;
  int GC_print_stats.21;
  int D.5431;
  long int D.5432;
  long unsigned int base.22;
  long unsigned int D.5434;
  unsigned int D.5435;
  unsigned int D.5436;
  long unsigned int D.5437;
  unsigned int D.5438;
  unsigned int D.5439;
  int D.5440;
  unsigned int D.5441;
  unsigned int D.5442;
  struct finalizable_object * * fo_head.23;
  long unsigned int D.5444;
  long unsigned int D.5445;
  struct finalizable_object * * D.5446;
  long unsigned int D.5447;
  long unsigned int D.5448;
  char * D.5453;
  void (*<T471>) (void *, void *) D.5456;
  struct hash_chain_entry * D.5459;
  long unsigned int D.5463;
  long unsigned int D.5474;
  long unsigned int D.5475;
  struct bottom_index * D.5477;
  long unsigned int D.5478;
  long unsigned int D.5479;
  void * (*<T40d>) (size_t) GC_oom_fn.24;
  unsigned int GC_finalization_failures.25;
  unsigned int D.5488;
  int D.5489;
  long unsigned int D.5492;
  struct finalizable_object * D.5493;
  long unsigned int D.5494;
  char * base;
  struct finalizable_object * curr_fo;
  struct finalizable_object * prev_fo;
  int index;
  struct finalizable_object * new_fo;
  struct hdr * hhdr;

  D.5418 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5418 != 0) goto <D.5419>; else goto <D.5420>;
  <D.5419>:
  GC_lock ();
  <D.5420>:
  log_fo_table_size.19 = log_fo_table_size;
  if (log_fo_table_size.19 == -1) goto <D.5421>; else goto <D.5424>;
  <D.5424>:
  log_fo_table_size.19 = log_fo_table_size;
  D.5425 = (unsigned int) log_fo_table_size.19;
  D.5426 = 1 << D.5425;
  GC_fo_entries.20 = GC_fo_entries;
  if (D.5426 < GC_fo_entries.20) goto <D.5421>; else goto <D.5422>;
  <D.5421>:
  GC_grow_table (&fo_head, &log_fo_table_size);
  GC_print_stats.21 = GC_print_stats;
  if (GC_print_stats.21 != 0) goto <D.5429>; else goto <D.5430>;
  <D.5429>:
  log_fo_table_size.19 = log_fo_table_size;
  D.5425 = (unsigned int) log_fo_table_size.19;
  D.5431 = 1 << D.5425;
  D.5432 = (long int) D.5431;
  GC_printf ("Grew fo table to %lu entries\n", D.5432, 0, 0, 0, 0, 0);
  <D.5430>:
  <D.5422>:
  base = obj;
  base.22 = (long unsigned int) base;
  D.5434 = base.22 >> 3;
  D.5435 = (unsigned int) D.5434;
  base.22 = (long unsigned int) base;
  log_fo_table_size.19 = log_fo_table_size;
  D.5425 = (unsigned int) log_fo_table_size.19;
  D.5436 = D.5425 + 3;
  D.5437 = base.22 >> D.5436;
  D.5438 = (unsigned int) D.5437;
  D.5439 = D.5435 ^ D.5438;
  log_fo_table_size.19 = log_fo_table_size;
  D.5425 = (unsigned int) log_fo_table_size.19;
  D.5431 = 1 << D.5425;
  D.5440 = D.5431 + -1;
  D.5441 = (unsigned int) D.5440;
  D.5442 = D.5439 & D.5441;
  index = (int) D.5442;
  prev_fo = 0B;
  fo_head.23 = fo_head;
  D.5444 = (long unsigned int) index;
  D.5445 = D.5444 * 8;
  D.5446 = fo_head.23 + D.5445;
  curr_fo = *D.5446;
  goto <D.5065>;
  <D.5064>:
  D.5447 = curr_fo->prolog.hidden_key;
  base.22 = (long unsigned int) base;
  D.5448 = ~base.22;
  if (D.5447 == D.5448) goto <D.5449>; else goto <D.5450>;
  <D.5449>:
  if (ocd != 0B) goto <D.5451>; else goto <D.5452>;
  <D.5451>:
  D.5453 = curr_fo->fo_client_data;
  *ocd = D.5453;
  <D.5452>:
  if (ofn != 0B) goto <D.5454>; else goto <D.5455>;
  <D.5454>:
  D.5456 = curr_fo->fo_fn;
  *ofn = D.5456;
  <D.5455>:
  if (prev_fo == 0B) goto <D.5457>; else goto <D.5458>;
  <D.5457>:
  fo_head.23 = fo_head;
  D.5444 = (long unsigned int) index;
  D.5445 = D.5444 * 8;
  D.5446 = fo_head.23 + D.5445;
  D.5459 = curr_fo->prolog.next;
  *D.5446 = D.5459;
  goto <D.5460>;
  <D.5458>:
  D.5459 = curr_fo->prolog.next;
  prev_fo->prolog.next = D.5459;
  <D.5460>:
  if (fn == 0B) goto <D.5461>; else goto <D.5462>;
  <D.5461>:
  GC_fo_entries.20 = GC_fo_entries;
  D.5463 = GC_fo_entries.20 + 18446744073709551615;
  GC_fo_entries = D.5463;
  goto <D.5464>;
  <D.5462>:
  curr_fo->fo_fn = fn;
  curr_fo->fo_client_data = cd;
  curr_fo->fo_mark_proc = mp;
  if (prev_fo == 0B) goto <D.5465>; else goto <D.5466>;
  <D.5465>:
  fo_head.23 = fo_head;
  D.5444 = (long unsigned int) index;
  D.5445 = D.5444 * 8;
  D.5446 = fo_head.23 + D.5445;
  *D.5446 = curr_fo;
  goto <D.5467>;
  <D.5466>:
  prev_fo->prolog.next = curr_fo;
  <D.5467>:
  <D.5464>:
  pthread_mutex_unlock (&GC_allocate_ml);
  return;
  <D.5450>:
  prev_fo = curr_fo;
  curr_fo = curr_fo->prolog.next;
  <D.5065>:
  if (curr_fo != 0B) goto <D.5064>; else goto <D.5066>;
  <D.5066>:
  if (ofn != 0B) goto <D.5468>; else goto <D.5469>;
  <D.5468>:
  *ofn = 0B;
  <D.5469>:
  if (ocd != 0B) goto <D.5470>; else goto <D.5471>;
  <D.5470>:
  *ocd = 0B;
  <D.5471>:
  if (fn == 0B) goto <D.5472>; else goto <D.5473>;
  <D.5472>:
  pthread_mutex_unlock (&GC_allocate_ml);
  return;
  <D.5473>:
  {
    register struct hdr * * _ha;

    {
      register struct bottom_index * bi;

      {
        register word hi;
        register struct bottom_index * _bi;

        base.22 = (long unsigned int) base;
        hi = base.22 >> 22;
        D.5474 = hi & 2047;
        _bi = GC_arrays._top_index[D.5474];
        goto <D.5072>;
        <D.5071>:
        _bi = _bi->hash_link;
        <D.5072>:
        D.5475 = _bi->key;
        if (D.5475 != hi) goto <D.5476>; else goto <D.5073>;
        <D.5476>:
        D.5477 = GC_arrays._all_nils;
        if (D.5477 != _bi) goto <D.5071>; else goto <D.5073>;
        <D.5073>:
        bi = _bi;
      }
      base.22 = (long unsigned int) base;
      D.5478 = base.22 >> 12;
      D.5479 = D.5478 & 1023;
      _ha = &bi->index[D.5479];
    }
    hhdr = *_ha;
  }
  if (hhdr == 0B) goto <D.5480>; else goto <D.5481>;
  <D.5480>:
  pthread_mutex_unlock (&GC_allocate_ml);
  return;
  <D.5481>:
  new_fo = GC_generic_malloc_inner (48, 1);
  if (new_fo == 0B) goto <D.5482>; else goto <D.5483>;
  <D.5482>:
  pthread_mutex_unlock (&GC_allocate_ml);
  GC_oom_fn.24 = GC_oom_fn;
  new_fo = GC_oom_fn.24 (48);
  if (new_fo == 0B) goto <D.5485>; else goto <D.5486>;
  <D.5485>:
  GC_finalization_failures.25 = GC_finalization_failures;
  D.5488 = GC_finalization_failures.25 + 1;
  GC_finalization_failures = D.5488;
  return;
  <D.5486>:
  D.5489 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5489 != 0) goto <D.5490>; else goto <D.5491>;
  <D.5490>:
  GC_lock ();
  <D.5491>:
  <D.5483>:
  base.22 = (long unsigned int) base;
  D.5448 = ~base.22;
  new_fo->prolog.hidden_key = D.5448;
  new_fo->fo_fn = fn;
  new_fo->fo_client_data = cd;
  D.5492 = hhdr->hb_sz;
  new_fo->fo_object_size = D.5492;
  new_fo->fo_mark_proc = mp;
  fo_head.23 = fo_head;
  D.5444 = (long unsigned int) index;
  D.5445 = D.5444 * 8;
  D.5446 = fo_head.23 + D.5445;
  D.5493 = *D.5446;
  new_fo->prolog.next = D.5493;
  GC_fo_entries.20 = GC_fo_entries;
  D.5494 = GC_fo_entries.20 + 1;
  GC_fo_entries = D.5494;
  fo_head.23 = fo_head;
  D.5444 = (long unsigned int) index;
  D.5445 = D.5444 * 8;
  D.5446 = fo_head.23 + D.5445;
  *D.5446 = 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.26;
  long int log_fo_table_size.27;
  unsigned int D.5500;
  struct finalizable_object * * fo_head.28;
  long unsigned int D.5503;
  long unsigned int D.5504;
  struct finalizable_object * * D.5505;
  long unsigned int D.5506;
  long unsigned int D.5507;
  long int real_ptr.29;
  struct finalizable_object * curr_fo;
  char * real_ptr;
  int fo_size;
  int i;

  log_fo_table_size.27 = log_fo_table_size;
  if (log_fo_table_size.27 != -1) goto <D.5498>; else goto <D.5499>;
  <D.5498>:
  log_fo_table_size.27 = log_fo_table_size;
  D.5500 = (unsigned int) log_fo_table_size.27;
  iftmp.26 = 1 << D.5500;
  goto <D.5501>;
  <D.5499>:
  iftmp.26 = 0;
  <D.5501>:
  fo_size = iftmp.26;
  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.5119>;
  <D.5118>:
  fo_head.28 = fo_head;
  D.5503 = (long unsigned int) i;
  D.5504 = D.5503 * 8;
  D.5505 = fo_head.28 + D.5504;
  curr_fo = *D.5505;
  goto <D.5116>;
  <D.5115>:
  D.5506 = curr_fo->prolog.hidden_key;
  D.5507 = ~D.5506;
  real_ptr = (char *) D.5507;
  real_ptr.29 = (long int) real_ptr;
  GC_printf ("Finalizable object: 0x%lx\n", real_ptr.29, 0, 0, 0, 0, 0);
  curr_fo = curr_fo->prolog.next;
  <D.5116>:
  if (curr_fo != 0B) goto <D.5115>; else goto <D.5117>;
  <D.5117>:
  i = i + 1;
  <D.5119>:
  if (i < fo_size) goto <D.5118>; else goto <D.5120>;
  <D.5120>:
}


GC_dump_finalization_links (struct dl_hashtbl_s * dl_hashtbl)
{
  size_t iftmp.30;
  long int D.5510;
  unsigned int D.5513;
  int D.5514;
  struct disappearing_link * * D.5516;
  long unsigned int D.5517;
  long unsigned int D.5518;
  struct disappearing_link * * D.5519;
  long unsigned int D.5520;
  long unsigned int D.5521;
  long unsigned int D.5522;
  long unsigned int D.5523;
  long int real_ptr.31;
  long int real_link.32;
  long unsigned int D.5526;
  struct disappearing_link * curr_dl;
  char * real_ptr;
  char * real_link;
  size_t dl_size;
  int i;

  D.5510 = dl_hashtbl->log_size;
  if (D.5510 != -1) goto <D.5511>; else goto <D.5512>;
  <D.5511>:
  D.5510 = dl_hashtbl->log_size;
  D.5513 = (unsigned int) D.5510;
  D.5514 = 1 << D.5513;
  iftmp.30 = (size_t) D.5514;
  goto <D.5515>;
  <D.5512>:
  iftmp.30 = 0;
  <D.5515>:
  dl_size = iftmp.30;
  i = 0;
  goto <D.5107>;
  <D.5106>:
  D.5516 = dl_hashtbl->head;
  D.5517 = (long unsigned int) i;
  D.5518 = D.5517 * 8;
  D.5519 = D.5516 + D.5518;
  curr_dl = *D.5519;
  goto <D.5104>;
  <D.5103>:
  D.5520 = curr_dl->dl_hidden_obj;
  D.5521 = ~D.5520;
  real_ptr = (char *) D.5521;
  D.5522 = curr_dl->prolog.hidden_key;
  D.5523 = ~D.5522;
  real_link = (char *) D.5523;
  real_ptr.31 = (long int) real_ptr;
  real_link.32 = (long int) real_link;
  GC_printf ("Object: %lx, link: %lx\n", real_ptr.31, real_link.32, 0, 0, 0, 0);
  curr_dl = curr_dl->prolog.next;
  <D.5104>:
  if (curr_dl != 0B) goto <D.5103>; else goto <D.5105>;
  <D.5105>:
  i = i + 1;
  <D.5107>:
  D.5526 = (long unsigned int) i;
  if (D.5526 < dl_size) goto <D.5106>; else goto <D.5108>;
  <D.5108>:
}


GC_finalize ()
{
  int iftmp.33;
  long int log_fo_table_size.34;
  unsigned int D.5531;
  struct finalizable_object * * fo_head.35;
  long unsigned int D.5534;
  long unsigned int D.5535;
  struct finalizable_object * * D.5536;
  long unsigned int D.5537;
  long unsigned int D.5538;
  int D.5539;
  void (*<Te60>) () D.5542;
  struct mse * GC_mark_stack_top.36;
  struct mse * GC_mark_stack.37;
  long unsigned int GC_mark_stack_size.38;
  long unsigned int D.5546;
  struct mse * D.5547;
  struct mse * D.5548;
  int D.5549;
  int GC_mark_state.39;
  int D.5553;
  int D.5554;
  void (*<T490>) (char *, GC_word) GC_current_warn_proc.40;
  long unsigned int real_ptr.41;
  int D.5559;
  int GC_java_finalization.42;
  long unsigned int GC_fo_entries.43;
  long unsigned int D.5569;
  struct finalizable_object * GC_finalize_now.44;
  long unsigned int D.5571;
  long unsigned int D.5572;
  int GC_all_interior_pointers.45;
  int D.5574;
  long unsigned int D.5575;
  long unsigned int D.5576;
  long unsigned int D.5577;
  long unsigned int D.5578;
  long unsigned int D.5579;
  long unsigned int D.5580;
  long unsigned int D.5581;
  long unsigned int D.5582;
  int D.5586;
  struct mse * GC_mark_stack_top.46;
  struct mse * D.5592;
  int D.5593;
  int D.5596;
  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.34 = log_fo_table_size;
  if (log_fo_table_size.34 != -1) goto <D.5529>; else goto <D.5530>;
  <D.5529>:
  log_fo_table_size.34 = log_fo_table_size;
  D.5531 = (unsigned int) log_fo_table_size.34;
  iftmp.33 = 1 << D.5531;
  goto <D.5532>;
  <D.5530>:
  iftmp.33 = 0;
  <D.5532>:
  fo_size = iftmp.33;
  GC_make_disappearing_links_disappear (&GC_dl_hashtbl);
  i = 0;
  goto <D.5171>;
  <D.5170>:
  fo_head.35 = fo_head;
  D.5534 = (long unsigned int) i;
  D.5535 = D.5534 * 8;
  D.5536 = fo_head.35 + D.5535;
  curr_fo = *D.5536;
  goto <D.5168>;
  <D.5167>:
  D.5537 = curr_fo->prolog.hidden_key;
  D.5538 = ~D.5537;
  real_ptr = (char *) D.5538;
  D.5539 = GC_is_marked (real_ptr);
  if (D.5539 == 0) goto <D.5540>; else goto <D.5541>;
  <D.5540>:
  D.5542 = curr_fo->fo_mark_proc;
  D.5542 (real_ptr);
  goto <D.5162>;
  <D.5161>:
  GC_mark_stack_top.36 = GC_mark_stack_top;
  GC_mark_stack.37 = GC_mark_stack;
  GC_mark_stack.37 = GC_mark_stack;
  GC_mark_stack_size.38 = GC_mark_stack_size;
  D.5546 = GC_mark_stack_size.38 * 16;
  D.5547 = GC_mark_stack.37 + D.5546;
  D.5548 = GC_mark_from (GC_mark_stack_top.36, GC_mark_stack.37, D.5547);
  GC_mark_stack_top = D.5548;
  <D.5162>:
  D.5549 = GC_mark_stack_empty ();
  if (D.5549 == 0) goto <D.5161>; else goto <D.5163>;
  <D.5163>:
  GC_mark_state.39 = GC_mark_state;
  if (GC_mark_state.39 != 0) goto <D.5551>; else goto <D.5552>;
  <D.5551>:
  GC_set_mark_bit (real_ptr);
  goto <D.5165>;
  <D.5164>:
  <D.5165>:
  D.5553 = GC_mark_some (0B);
  if (D.5553 == 0) goto <D.5164>; else goto <D.5166>;
  <D.5166>:
  <D.5552>:
  D.5554 = GC_is_marked (real_ptr);
  if (D.5554 != 0) goto <D.5555>; else goto <D.5556>;
  <D.5555>:
  GC_current_warn_proc.40 = GC_current_warn_proc;
  real_ptr.41 = (long unsigned int) real_ptr;
  GC_current_warn_proc.40 ("GC Warning: Finalization cycle involving %lx\n", real_ptr.41);
  <D.5556>:
  <D.5541>:
  curr_fo = curr_fo->prolog.next;
  <D.5168>:
  if (curr_fo != 0B) goto <D.5167>; else goto <D.5169>;
  <D.5169>:
  i = i + 1;
  <D.5171>:
  if (i < fo_size) goto <D.5170>; else goto <D.5172>;
  <D.5172>:
  GC_arrays._words_finalized = 0;
  i = 0;
  goto <D.5177>;
  <D.5176>:
  fo_head.35 = fo_head;
  D.5534 = (long unsigned int) i;
  D.5535 = D.5534 * 8;
  D.5536 = fo_head.35 + D.5535;
  curr_fo = *D.5536;
  prev_fo = 0B;
  goto <D.5174>;
  <D.5173>:
  D.5537 = curr_fo->prolog.hidden_key;
  D.5538 = ~D.5537;
  real_ptr = (char *) D.5538;
  D.5559 = GC_is_marked (real_ptr);
  if (D.5559 == 0) goto <D.5560>; else goto <D.5561>;
  <D.5560>:
  GC_java_finalization.42 = GC_java_finalization;
  if (GC_java_finalization.42 == 0) goto <D.5563>; else goto <D.5564>;
  <D.5563>:
  GC_set_mark_bit (real_ptr);
  <D.5564>:
  next_fo = curr_fo->prolog.next;
  if (prev_fo == 0B) goto <D.5565>; else goto <D.5566>;
  <D.5565>:
  fo_head.35 = fo_head;
  D.5534 = (long unsigned int) i;
  D.5535 = D.5534 * 8;
  D.5536 = fo_head.35 + D.5535;
  *D.5536 = next_fo;
  goto <D.5567>;
  <D.5566>:
  prev_fo->prolog.next = next_fo;
  <D.5567>:
  GC_fo_entries.43 = GC_fo_entries;
  D.5569 = GC_fo_entries.43 + 18446744073709551615;
  GC_fo_entries = D.5569;
  GC_finalize_now.44 = GC_finalize_now;
  curr_fo->prolog.next = GC_finalize_now.44;
  GC_finalize_now = curr_fo;
  D.5537 = curr_fo->prolog.hidden_key;
  D.5538 = ~D.5537;
  curr_fo->prolog.hidden_key = D.5538;
  D.5571 = GC_arrays._words_finalized;
  D.5572 = curr_fo->fo_object_size;
  GC_all_interior_pointers.45 = GC_all_interior_pointers;
  D.5574 = GC_all_interior_pointers.45 + 7;
  D.5575 = (long unsigned int) D.5574;
  D.5576 = D.5572 + D.5575;
  D.5577 = D.5576 >> 3;
  GC_all_interior_pointers.45 = GC_all_interior_pointers;
  D.5574 = GC_all_interior_pointers.45 + 7;
  D.5578 = (long unsigned int) D.5574;
  D.5579 = D.5578 + 48;
  D.5580 = D.5579 >> 3;
  D.5581 = D.5577 + D.5580;
  D.5582 = D.5571 + D.5581;
  GC_arrays._words_finalized = D.5582;
  curr_fo = next_fo;
  goto <D.5583>;
  <D.5561>:
  prev_fo = curr_fo;
  curr_fo = curr_fo->prolog.next;
  <D.5583>:
  <D.5174>:
  if (curr_fo != 0B) goto <D.5173>; else goto <D.5175>;
  <D.5175>:
  i = i + 1;
  <D.5177>:
  if (i < fo_size) goto <D.5176>; else goto <D.5178>;
  <D.5178>:
  GC_java_finalization.42 = GC_java_finalization;
  if (GC_java_finalization.42 != 0) goto <D.5584>; else goto <D.5585>;
  <D.5584>:
  curr_fo = GC_finalize_now;
  goto <D.5186>;
  <D.5185>:
  D.5537 = curr_fo->prolog.hidden_key;
  real_ptr = (char *) D.5537;
  D.5586 = GC_is_marked (real_ptr);
  if (D.5586 == 0) goto <D.5587>; else goto <D.5588>;
  <D.5587>:
  D.5542 = curr_fo->fo_mark_proc;
  if (D.5542 == GC_null_finalize_mark_proc) goto <D.5589>; else goto <D.5590>;
  <D.5589>:
  GC_normal_finalize_mark_proc (real_ptr);
  goto <D.5180>;
  <D.5179>:
  GC_mark_stack_top.46 = GC_mark_stack_top;
  GC_mark_stack.37 = GC_mark_stack;
  GC_mark_stack.37 = GC_mark_stack;
  GC_mark_stack_size.38 = GC_mark_stack_size;
  D.5546 = GC_mark_stack_size.38 * 16;
  D.5547 = GC_mark_stack.37 + D.5546;
  D.5592 = GC_mark_from (GC_mark_stack_top.46, GC_mark_stack.37, D.5547);
  GC_mark_stack_top = D.5592;
  <D.5180>:
  D.5593 = GC_mark_stack_empty ();
  if (D.5593 == 0) goto <D.5179>; else goto <D.5181>;
  <D.5181>:
  GC_mark_state.39 = GC_mark_state;
  if (GC_mark_state.39 != 0) goto <D.5594>; else goto <D.5595>;
  <D.5594>:
  GC_set_mark_bit (real_ptr);
  goto <D.5183>;
  <D.5182>:
  <D.5183>:
  D.5596 = GC_mark_some (0B);
  if (D.5596 == 0) goto <D.5182>; else goto <D.5184>;
  <D.5184>:
  <D.5595>:
  <D.5590>:
  GC_set_mark_bit (real_ptr);
  <D.5588>:
  curr_fo = curr_fo->prolog.next;
  <D.5186>:
  if (curr_fo != 0B) goto <D.5185>; else goto <D.5187>;
  <D.5187>:
  <D.5585>:
  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.47;
  long int D.5598;
  unsigned int D.5601;
  struct disappearing_link * * D.5603;
  long unsigned int D.5604;
  long unsigned int D.5605;
  struct disappearing_link * * D.5606;
  long unsigned int D.5607;
  long unsigned int D.5608;
  long unsigned int D.5609;
  long unsigned int D.5610;
  int D.5611;
  long unsigned int D.5617;
  long unsigned int D.5618;
  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.5598 = dl_hashtbl->log_size;
  if (D.5598 != -1) goto <D.5599>; else goto <D.5600>;
  <D.5599>:
  D.5598 = dl_hashtbl->log_size;
  D.5601 = (unsigned int) D.5598;
  iftmp.47 = 1 << D.5601;
  goto <D.5602>;
  <D.5600>:
  iftmp.47 = 0;
  <D.5602>:
  dl_size = iftmp.47;
  i = 0;
  goto <D.5135>;
  <D.5134>:
  D.5603 = dl_hashtbl->head;
  D.5604 = (long unsigned int) i;
  D.5605 = D.5604 * 8;
  D.5606 = D.5603 + D.5605;
  curr_dl = *D.5606;
  prev_dl = 0B;
  goto <D.5132>;
  <D.5131>:
  D.5607 = curr_dl->dl_hidden_obj;
  D.5608 = ~D.5607;
  real_ptr = (char *) D.5608;
  D.5609 = curr_dl->prolog.hidden_key;
  D.5610 = ~D.5609;
  real_link = (char *) D.5610;
  D.5611 = GC_is_marked (real_ptr);
  if (D.5611 == 0) goto <D.5612>; else goto <D.5613>;
  <D.5612>:
  MEM[(word *)real_link] = 0;
  next_dl = curr_dl->prolog.next;
  if (prev_dl == 0B) goto <D.5614>; else goto <D.5615>;
  <D.5614>:
  D.5603 = dl_hashtbl->head;
  D.5604 = (long unsigned int) i;
  D.5605 = D.5604 * 8;
  D.5606 = D.5603 + D.5605;
  *D.5606 = next_dl;
  goto <D.5616>;
  <D.5615>:
  prev_dl->prolog.next = next_dl;
  <D.5616>:
  GC_clear_mark_bit (curr_dl);
  D.5617 = dl_hashtbl->entries;
  D.5618 = D.5617 + 18446744073709551615;
  dl_hashtbl->entries = D.5618;
  curr_dl = next_dl;
  goto <D.5619>;
  <D.5613>:
  prev_dl = curr_dl;
  curr_dl = curr_dl->prolog.next;
  <D.5619>:
  <D.5132>:
  if (curr_dl != 0B) goto <D.5131>; else goto <D.5133>;
  <D.5133>:
  i = i + 1;
  <D.5135>:
  if (i < dl_size) goto <D.5134>; else goto <D.5136>;
  <D.5136>:
}


GC_remove_dangling_disappearing_links (struct dl_hashtbl_s * dl_hashtbl)
{
  int iftmp.48;
  long int D.5621;
  unsigned int D.5624;
  struct disappearing_link * * D.5626;
  long unsigned int D.5627;
  long unsigned int D.5628;
  struct disappearing_link * * D.5629;
  long unsigned int D.5630;
  long unsigned int D.5631;
  void * D.5632;
  int D.5636;
  long unsigned int D.5641;
  long unsigned int D.5642;
  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.5621 = dl_hashtbl->log_size;
  if (D.5621 != -1) goto <D.5622>; else goto <D.5623>;
  <D.5622>:
  D.5621 = dl_hashtbl->log_size;
  D.5624 = (unsigned int) D.5621;
  iftmp.48 = 1 << D.5624;
  goto <D.5625>;
  <D.5623>:
  iftmp.48 = 0;
  <D.5625>:
  dl_size = iftmp.48;
  i = 0;
  goto <D.5151>;
  <D.5150>:
  D.5626 = dl_hashtbl->head;
  D.5627 = (long unsigned int) i;
  D.5628 = D.5627 * 8;
  D.5629 = D.5626 + D.5628;
  curr_dl = *D.5629;
  prev_dl = 0B;
  goto <D.5148>;
  <D.5147>:
  D.5630 = curr_dl->prolog.hidden_key;
  D.5631 = ~D.5630;
  D.5632 = (void *) D.5631;
  real_link = GC_base (D.5632);
  if (real_link != 0B) goto <D.5635>; else goto <D.5633>;
  <D.5635>:
  D.5636 = GC_is_marked (real_link);
  if (D.5636 == 0) goto <D.5637>; else goto <D.5633>;
  <D.5637>:
  next_dl = curr_dl->prolog.next;
  if (prev_dl == 0B) goto <D.5638>; else goto <D.5639>;
  <D.5638>:
  D.5626 = dl_hashtbl->head;
  D.5627 = (long unsigned int) i;
  D.5628 = D.5627 * 8;
  D.5629 = D.5626 + D.5628;
  *D.5629 = next_dl;
  goto <D.5640>;
  <D.5639>:
  prev_dl->prolog.next = next_dl;
  <D.5640>:
  GC_clear_mark_bit (curr_dl);
  D.5641 = dl_hashtbl->entries;
  D.5642 = D.5641 + 18446744073709551615;
  dl_hashtbl->entries = D.5642;
  curr_dl = next_dl;
  goto <D.5634>;
  <D.5633>:
  prev_dl = curr_dl;
  curr_dl = curr_dl->prolog.next;
  <D.5634>:
  <D.5148>:
  if (curr_dl != 0B) goto <D.5147>; else goto <D.5149>;
  <D.5149>:
  i = i + 1;
  <D.5151>:
  if (i < dl_size) goto <D.5150>; else goto <D.5152>;
  <D.5152>:
}


GC_enqueue_all_finalizers ()
{
  int iftmp.49;
  long int log_fo_table_size.50;
  unsigned int D.5647;
  struct finalizable_object * * fo_head.51;
  long unsigned int D.5650;
  long unsigned int D.5651;
  struct finalizable_object * * D.5652;
  long unsigned int D.5653;
  long unsigned int D.5654;
  struct mse * GC_mark_stack_top.52;
  struct mse * GC_mark_stack.53;
  long unsigned int GC_mark_stack_size.54;
  long unsigned int D.5658;
  struct mse * D.5659;
  struct mse * D.5660;
  int D.5661;
  int GC_mark_state.55;
  int D.5665;
  long unsigned int GC_fo_entries.56;
  long unsigned int D.5670;
  struct finalizable_object * GC_finalize_now.57;
  long unsigned int D.5672;
  long unsigned int D.5673;
  int GC_all_interior_pointers.58;
  int D.5675;
  long unsigned int D.5676;
  long unsigned int D.5677;
  long unsigned int D.5678;
  long unsigned int D.5679;
  long unsigned int D.5680;
  long unsigned int D.5681;
  long unsigned int D.5682;
  long unsigned int D.5683;
  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.5645>; else goto <D.5646>;
  <D.5645>:
  log_fo_table_size.50 = log_fo_table_size;
  D.5647 = (unsigned int) log_fo_table_size.50;
  iftmp.49 = 1 << D.5647;
  goto <D.5648>;
  <D.5646>:
  iftmp.49 = 0;
  <D.5648>:
  fo_size = iftmp.49;
  GC_arrays._words_finalized = 0;
  i = 0;
  goto <D.5206>;
  <D.5205>:
  fo_head.51 = fo_head;
  D.5650 = (long unsigned int) i;
  D.5651 = D.5650 * 8;
  D.5652 = fo_head.51 + D.5651;
  curr_fo = *D.5652;
  prev_fo = 0B;
  goto <D.5203>;
  <D.5202>:
  D.5653 = curr_fo->prolog.hidden_key;
  D.5654 = ~D.5653;
  real_ptr = (char *) D.5654;
  GC_normal_finalize_mark_proc (real_ptr);
  goto <D.5197>;
  <D.5196>:
  GC_mark_stack_top.52 = GC_mark_stack_top;
  GC_mark_stack.53 = GC_mark_stack;
  GC_mark_stack.53 = GC_mark_stack;
  GC_mark_stack_size.54 = GC_mark_stack_size;
  D.5658 = GC_mark_stack_size.54 * 16;
  D.5659 = GC_mark_stack.53 + D.5658;
  D.5660 = GC_mark_from (GC_mark_stack_top.52, GC_mark_stack.53, D.5659);
  GC_mark_stack_top = D.5660;
  <D.5197>:
  D.5661 = GC_mark_stack_empty ();
  if (D.5661 == 0) goto <D.5196>; else goto <D.5198>;
  <D.5198>:
  GC_mark_state.55 = GC_mark_state;
  if (GC_mark_state.55 != 0) goto <D.5663>; else goto <D.5664>;
  <D.5663>:
  GC_set_mark_bit (real_ptr);
  goto <D.5200>;
  <D.5199>:
  <D.5200>:
  D.5665 = GC_mark_some (0B);
  if (D.5665 == 0) goto <D.5199>; else goto <D.5201>;
  <D.5201>:
  <D.5664>:
  GC_set_mark_bit (real_ptr);
  next_fo = curr_fo->prolog.next;
  if (prev_fo == 0B) goto <D.5666>; else goto <D.5667>;
  <D.5666>:
  fo_head.51 = fo_head;
  D.5650 = (long unsigned int) i;
  D.5651 = D.5650 * 8;
  D.5652 = fo_head.51 + D.5651;
  *D.5652 = next_fo;
  goto <D.5668>;
  <D.5667>:
  prev_fo->prolog.next = next_fo;
  <D.5668>:
  GC_fo_entries.56 = GC_fo_entries;
  D.5670 = GC_fo_entries.56 + 18446744073709551615;
  GC_fo_entries = D.5670;
  GC_finalize_now.57 = GC_finalize_now;
  curr_fo->prolog.next = GC_finalize_now.57;
  GC_finalize_now = curr_fo;
  D.5653 = curr_fo->prolog.hidden_key;
  D.5654 = ~D.5653;
  curr_fo->prolog.hidden_key = D.5654;
  D.5672 = GC_arrays._words_finalized;
  D.5673 = curr_fo->fo_object_size;
  GC_all_interior_pointers.58 = GC_all_interior_pointers;
  D.5675 = GC_all_interior_pointers.58 + 7;
  D.5676 = (long unsigned int) D.5675;
  D.5677 = D.5673 + D.5676;
  D.5678 = D.5677 >> 3;
  GC_all_interior_pointers.58 = GC_all_interior_pointers;
  D.5675 = GC_all_interior_pointers.58 + 7;
  D.5679 = (long unsigned int) D.5675;
  D.5680 = D.5679 + 48;
  D.5681 = D.5680 >> 3;
  D.5682 = D.5678 + D.5681;
  D.5683 = D.5672 + D.5682;
  GC_arrays._words_finalized = D.5683;
  curr_fo = next_fo;
  <D.5203>:
  if (curr_fo != 0B) goto <D.5202>; else goto <D.5204>;
  <D.5204>:
  i = i + 1;
  <D.5206>:
  if (i < fo_size) goto <D.5205>; else goto <D.5207>;
  <D.5207>:
  return;
}


GC_finalize_all ()
{
  int D.5685;
  int D.5688;
  long unsigned int GC_fo_entries.59;

  D.5685 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5685 != 0) goto <D.5686>; else goto <D.5687>;
  <D.5686>:
  GC_lock ();
  <D.5687>:
  goto <D.5211>;
  <D.5210>:
  GC_enqueue_all_finalizers ();
  pthread_mutex_unlock (&GC_allocate_ml);
  GC_notify_or_invoke_finalizers ();
  D.5688 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5688 != 0) goto <D.5689>; else goto <D.5690>;
  <D.5689>:
  GC_lock ();
  <D.5690>:
  <D.5211>:
  GC_fo_entries.59 = GC_fo_entries;
  if (GC_fo_entries.59 != 0) goto <D.5210>; else goto <D.5212>;
  <D.5212>:
  pthread_mutex_unlock (&GC_allocate_ml);
}


GC_should_invoke_finalizers ()
{
  int D.5692;
  struct finalizable_object * GC_finalize_now.60;
  _Bool D.5694;

  GC_finalize_now.60 = GC_finalize_now;
  D.5694 = GC_finalize_now.60 != 0B;
  D.5692 = (int) D.5694;
  return D.5692;
}


GC_invoke_finalizers ()
{
  int D.5696;
  struct hash_chain_entry * D.5703;
  void (*<T471>) (void *, void *) D.5705;
  long unsigned int D.5706;
  void * D.5707;
  char * D.5708;
  struct finalizable_object * GC_finalize_now.61;
  long unsigned int D.5712;
  int D.5715;
  long unsigned int D.5718;
  long unsigned int D.5719;
  long unsigned int D.5720;
  int D.5721;
  struct finalizable_object * curr_fo;
  int count;
  word mem_freed_before;

  count = 0;
  goto <D.5223>;
  <D.5222>:
  D.5696 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5696 != 0) goto <D.5697>; else goto <D.5698>;
  <D.5697>:
  GC_lock ();
  <D.5698>:
  if (count == 0) goto <D.5699>; else goto <D.5700>;
  <D.5699>:
  mem_freed_before = GC_arrays._mem_freed;
  <D.5700>:
  curr_fo = GC_finalize_now;
  if (curr_fo != 0B) goto <D.5701>; else goto <D.5702>;
  <D.5701>:
  D.5703 = curr_fo->prolog.next;
  GC_finalize_now = D.5703;
  <D.5702>:
  pthread_mutex_unlock (&GC_allocate_ml);
  if (curr_fo == 0B) goto <D.5221>; else goto <D.5704>;
  <D.5704>:
  curr_fo->prolog.next = 0B;
  D.5705 = curr_fo->fo_fn;
  D.5706 = curr_fo->prolog.hidden_key;
  D.5707 = (void *) D.5706;
  D.5708 = curr_fo->fo_client_data;
  D.5705 (D.5707, D.5708);
  curr_fo->fo_client_data = 0B;
  count = count + 1;
  <D.5223>:
  GC_finalize_now.61 = GC_finalize_now;
  if (GC_finalize_now.61 != 0B) goto <D.5222>; else goto <D.5221>;
  <D.5221>:
  if (count != 0) goto <D.5710>; else goto <D.5711>;
  <D.5710>:
  D.5712 = GC_arrays._mem_freed;
  if (D.5712 != mem_freed_before) goto <D.5713>; else goto <D.5714>;
  <D.5713>:
  D.5715 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5715 != 0) goto <D.5716>; else goto <D.5717>;
  <D.5716>:
  GC_lock ();
  <D.5717>:
  D.5718 = GC_arrays._finalizer_mem_freed;
  D.5712 = GC_arrays._mem_freed;
  D.5719 = D.5712 - mem_freed_before;
  D.5720 = D.5718 + D.5719;
  GC_arrays._finalizer_mem_freed = D.5720;
  pthread_mutex_unlock (&GC_allocate_ml);
  <D.5714>:
  <D.5711>:
  D.5721 = count;
  return D.5721;
}


GC_notify_or_invoke_finalizers ()
{
  struct finalizable_object * GC_finalize_now.62;
  int GC_finalize_on_demand.63;
  void (*<T41a>) (void) GC_finalizer_notifier.64;
  long unsigned int last_finalizer_notification.65;
  long unsigned int GC_gc_no.66;

  GC_finalize_now.62 = GC_finalize_now;
  if (GC_finalize_now.62 == 0B) goto <D.5724>; else goto <D.5725>;
  <D.5724>:
  return;
  <D.5725>:
  GC_finalize_on_demand.63 = GC_finalize_on_demand;
  if (GC_finalize_on_demand.63 == 0) goto <D.5727>; else goto <D.5728>;
  <D.5727>:
  GC_invoke_finalizers ();
  return;
  <D.5728>:
  GC_finalizer_notifier.64 = GC_finalizer_notifier;
  if (GC_finalizer_notifier.64 != 0B) goto <D.5730>; else goto <D.5731>;
  <D.5730>:
  last_finalizer_notification.65 = last_finalizer_notification;
  GC_gc_no.66 = GC_gc_no;
  if (last_finalizer_notification.65 != GC_gc_no.66) goto <D.5734>; else goto <D.5735>;
  <D.5734>:
  GC_gc_no.66 = GC_gc_no;
  last_finalizer_notification = GC_gc_no.66;
  GC_finalizer_notifier.64 = GC_finalizer_notifier;
  GC_finalizer_notifier.64 ();
  <D.5735>:
  <D.5731>:
}


GC_call_with_alloc_lock (void * (*GC_fn_type) (void *) fn, void * client_data)
{
  int D.5737;
  long unsigned int D.5740;
  void * D.5741;
  void * result;

  D.5737 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5737 != 0) goto <D.5738>; else goto <D.5739>;
  <D.5738>:
  GC_lock ();
  <D.5739>:
  D.5740 = pthread_self ();
  GC_lock_holder = D.5740;
  result = fn (client_data);
  GC_lock_holder = 18446744073709551615;
  pthread_mutex_unlock (&GC_allocate_ml);
  D.5741 = result;
  return D.5741;
}


GC_print_finalization_stats ()
{
  long unsigned int GC_fo_entries.67;
  long int GC_fo_entries.68;
  long unsigned int D.5745;
  long int D.5746;
  long unsigned int D.5747;
  long int D.5748;
  long int ready.69;
  struct finalizable_object * fo;
  size_t ready;

  fo = GC_finalize_now;
  ready = 0;
  GC_fo_entries.67 = GC_fo_entries;
  GC_fo_entries.68 = (long int) GC_fo_entries.67;
  D.5745 = GC_dl_hashtbl.entries;
  D.5746 = (long int) D.5745;
  D.5747 = GC_ll_hashtbl.entries;
  D.5748 = (long int) D.5747;
  GC_printf ("%lu finalization table entries; %lu/%lu short/long disappearing links alive\n", GC_fo_entries.68, D.5746, D.5748, 0, 0, 0);
  goto <D.5241>;
  <D.5240>:
  ready = ready + 1;
  fo = fo->prolog.next;
  <D.5241>:
  if (fo != 0B) goto <D.5240>; else goto <D.5242>;
  <D.5242>:
  ready.69 = (long int) ready;
  GC_printf ("%lu objects are eligible for immediate finalization\n", ready.69, 0, 0, 0, 0, 0);
}


