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


GC_grow_table (struct hash_chain_entry * * * table, signed_word * log_size_ptr)
{
  long int D.5162;
  word iftmp.0;
  int D.5166;
  int D.5168;
  long unsigned int D.5169;
  struct hash_chain_entry * * D.5175;
  long unsigned int D.5176;
  struct hash_chain_entry * * D.5177;
  long unsigned int D.5178;
  long unsigned int D.5179;
  long unsigned int real_key.1;
  long unsigned int D.5181;
  unsigned int D.5182;
  int D.5183;
  long unsigned int D.5184;
  unsigned int D.5185;
  unsigned int D.5186;
  unsigned int D.5187;
  unsigned int D.5188;
  unsigned int D.5189;
  long unsigned int D.5190;
  long unsigned int D.5191;
  struct hash_chain_entry * * D.5192;
  struct hash_chain_entry * D.5193;
  long int D.5194;
  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.5162 = *log_size_ptr;
  log_old_size = (int) D.5162;
  log_new_size = log_old_size + 1;
  if (log_old_size != -1) goto <D.5164>; else goto <D.5165>;
  <D.5164>:
  D.5166 = 1 << log_old_size;
  iftmp.0 = (word) D.5166;
  goto <D.5167>;
  <D.5165>:
  iftmp.0 = 0;
  <D.5167>:
  old_size = iftmp.0;
  D.5168 = 1 << log_new_size;
  new_size = (word) D.5168;
  D.5169 = new_size * 8;
  new_table = GC_generic_malloc_inner_ignore_off_page (D.5169, 1);
  if (new_table == 0B) goto <D.5170>; else goto <D.5171>;
  <D.5170>:
  if (table == 0B) goto <D.5172>; else goto <D.5173>;
  <D.5172>:
  GC_abort ("Insufficient space for initial table allocation");
  goto <D.5174>;
  <D.5173>:
  return;
  <D.5174>:
  <D.5171>:
  i = 0;
  goto <D.4906>;
  <D.4905>:
  D.5175 = *table;
  D.5176 = i * 8;
  D.5177 = D.5175 + D.5176;
  p = *D.5177;
  goto <D.4903>;
  <D.4902>:
  {
    register char * real_key;
    register struct hash_chain_entry * next;
    register int new_hash;

    D.5178 = p->hidden_key;
    D.5179 = ~D.5178;
    real_key = (char *) D.5179;
    next = p->next;
    real_key.1 = (long unsigned int) real_key;
    D.5181 = real_key.1 >> 3;
    D.5182 = (unsigned int) D.5181;
    real_key.1 = (long unsigned int) real_key;
    D.5183 = log_new_size + 3;
    D.5184 = real_key.1 >> D.5183;
    D.5185 = (unsigned int) D.5184;
    D.5186 = D.5182 ^ D.5185;
    D.5187 = (unsigned int) new_size;
    D.5188 = D.5187 + 4294967295;
    D.5189 = D.5186 & D.5188;
    new_hash = (int) D.5189;
    D.5190 = (long unsigned int) new_hash;
    D.5191 = D.5190 * 8;
    D.5192 = new_table + D.5191;
    D.5193 = *D.5192;
    p->next = D.5193;
    D.5190 = (long unsigned int) new_hash;
    D.5191 = D.5190 * 8;
    D.5192 = new_table + D.5191;
    *D.5192 = p;
    p = next;
  }
  <D.4903>:
  if (p != 0B) goto <D.4902>; else goto <D.4904>;
  <D.4904>:
  i = i + 1;
  <D.4906>:
  if (i < old_size) goto <D.4905>; else goto <D.4907>;
  <D.4907>:
  D.5194 = (long int) log_new_size;
  *log_size_ptr = D.5194;
  *table = new_table;
}


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

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


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

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


GC_register_disappearing_link_inner (struct dl_hashtbl_s * dl_hashtbl, void * * link, void * obj)
{
  long unsigned int link.2;
  long unsigned int D.5203;
  int D.5206;
  long int D.5211;
  long unsigned int D.5213;
  int D.5214;
  long unsigned int D.5215;
  signed_word * D.5216;
  struct disappearing_link * * * D.5217;
  int GC_print_stats.3;
  int D.5221;
  long int D.5222;
  long unsigned int D.5223;
  unsigned int D.5224;
  unsigned int D.5225;
  unsigned int D.5226;
  int D.5227;
  long unsigned int D.5228;
  unsigned int D.5229;
  unsigned int D.5230;
  int D.5231;
  unsigned int D.5232;
  unsigned int D.5233;
  struct disappearing_link * * D.5234;
  long unsigned int D.5235;
  long unsigned int D.5236;
  struct disappearing_link * * D.5237;
  long unsigned int D.5238;
  long unsigned int D.5239;
  long unsigned int obj.4;
  long unsigned int D.5243;
  int D.5244;
  void * (*<T397>) (size_t) GC_oom_fn.5;
  unsigned int GC_finalization_failures.6;
  unsigned int GC_finalization_failures.7;
  int D.5252;
  struct disappearing_link * D.5255;
  long unsigned int D.5256;
  struct disappearing_link * curr_dl;
  int index;
  struct disappearing_link * new_dl;

  link.2 = (long unsigned int) link;
  D.5203 = link.2 & 7;
  if (D.5203 != 0) goto <D.5204>; else goto <D.5205>;
  <D.5204>:
  GC_abort ("Bad arg to GC_general_register_disappearing_link");
  <D.5205>:
  D.5206 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5206 != 0) goto <D.5207>; else goto <D.5208>;
  <D.5207>:
  GC_lock ();
  <D.5208>:
  D.5211 = dl_hashtbl->log_size;
  if (D.5211 == -1) goto <D.5209>; else goto <D.5212>;
  <D.5212>:
  D.5213 = dl_hashtbl->entries;
  D.5211 = dl_hashtbl->log_size;
  D.5214 = (int) D.5211;
  D.5215 = 1 << D.5214;
  if (D.5213 > D.5215) goto <D.5209>; else goto <D.5210>;
  <D.5209>:
  D.5216 = &dl_hashtbl->log_size;
  D.5217 = &dl_hashtbl->head;
  GC_grow_table (D.5217, D.5216);
  GC_print_stats.3 = GC_print_stats;
  if (GC_print_stats.3 != 0) goto <D.5219>; else goto <D.5220>;
  <D.5219>:
  D.5211 = dl_hashtbl->log_size;
  D.5214 = (int) D.5211;
  D.5221 = 1 << D.5214;
  D.5222 = (long int) D.5221;
  GC_printf ("Grew dl table to %lu entries\n", D.5222, 0, 0, 0, 0, 0);
  <D.5220>:
  <D.5210>:
  link.2 = (long unsigned int) link;
  D.5223 = link.2 >> 3;
  D.5224 = (unsigned int) D.5223;
  link.2 = (long unsigned int) link;
  D.5211 = dl_hashtbl->log_size;
  D.5225 = (unsigned int) D.5211;
  D.5226 = D.5225 + 3;
  D.5227 = (int) D.5226;
  D.5228 = link.2 >> D.5227;
  D.5229 = (unsigned int) D.5228;
  D.5230 = D.5224 ^ D.5229;
  D.5211 = dl_hashtbl->log_size;
  D.5214 = (int) D.5211;
  D.5221 = 1 << D.5214;
  D.5231 = D.5221 + -1;
  D.5232 = (unsigned int) D.5231;
  D.5233 = D.5230 & D.5232;
  index = (int) D.5233;
  D.5234 = dl_hashtbl->head;
  D.5235 = (long unsigned int) index;
  D.5236 = D.5235 * 8;
  D.5237 = D.5234 + D.5236;
  curr_dl = *D.5237;
  D.5234 = dl_hashtbl->head;
  D.5235 = (long unsigned int) index;
  D.5236 = D.5235 * 8;
  D.5237 = D.5234 + D.5236;
  curr_dl = *D.5237;
  goto <D.4925>;
  <D.4924>:
  D.5238 = curr_dl->prolog.hidden_key;
  link.2 = (long unsigned int) link;
  D.5239 = ~link.2;
  if (D.5238 == D.5239) goto <D.5240>; else goto <D.5241>;
  <D.5240>:
  obj.4 = (long unsigned int) obj;
  D.5243 = ~obj.4;
  curr_dl->dl_hidden_obj = D.5243;
  pthread_mutex_unlock (&GC_allocate_ml);
  D.5244 = 1;
  return D.5244;
  <D.5241>:
  curr_dl = curr_dl->prolog.next;
  <D.4925>:
  if (curr_dl != 0B) goto <D.4924>; else goto <D.4926>;
  <D.4926>:
  new_dl = GC_generic_malloc_inner (24, 1);
  if (new_dl == 0B) goto <D.5245>; else goto <D.5246>;
  <D.5245>:
  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.5248>; else goto <D.5249>;
  <D.5248>:
  GC_finalization_failures.6 = GC_finalization_failures;
  GC_finalization_failures.7 = GC_finalization_failures.6 + 1;
  GC_finalization_failures = GC_finalization_failures.7;
  D.5244 = 0;
  return D.5244;
  <D.5249>:
  D.5252 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5252 != 0) goto <D.5253>; else goto <D.5254>;
  <D.5253>:
  GC_lock ();
  <D.5254>:
  <D.5246>:
  obj.4 = (long unsigned int) obj;
  D.5243 = ~obj.4;
  new_dl->dl_hidden_obj = D.5243;
  link.2 = (long unsigned int) link;
  D.5239 = ~link.2;
  new_dl->prolog.hidden_key = D.5239;
  D.5234 = dl_hashtbl->head;
  D.5235 = (long unsigned int) index;
  D.5236 = D.5235 * 8;
  D.5237 = D.5234 + D.5236;
  D.5255 = *D.5237;
  new_dl->prolog.next = D.5255;
  D.5234 = dl_hashtbl->head;
  D.5235 = (long unsigned int) index;
  D.5236 = D.5235 * 8;
  D.5237 = D.5234 + D.5236;
  *D.5237 = new_dl;
  D.5213 = dl_hashtbl->entries;
  D.5256 = D.5213 + 1;
  dl_hashtbl->entries = D.5256;
  pthread_mutex_unlock (&GC_allocate_ml);
  D.5244 = 0;
  return D.5244;
}


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

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


GC_unregister_disappearing_link_inner (struct dl_hashtbl_s * dl_hashtbl, void * * link)
{
  int D.5260;
  long unsigned int link.8;
  long unsigned int D.5264;
  unsigned int D.5265;
  long int D.5266;
  unsigned int D.5267;
  unsigned int D.5268;
  int D.5269;
  long unsigned int D.5270;
  unsigned int D.5271;
  unsigned int D.5272;
  int D.5273;
  int D.5274;
  int D.5275;
  unsigned int D.5276;
  unsigned int D.5277;
  long unsigned int D.5278;
  struct disappearing_link * * D.5280;
  long unsigned int D.5281;
  long unsigned int D.5282;
  struct disappearing_link * * D.5283;
  long unsigned int D.5284;
  long unsigned int D.5285;
  struct hash_chain_entry * D.5290;
  long unsigned int D.5292;
  long unsigned int D.5293;
  int D.5294;
  struct disappearing_link * curr_dl;
  struct disappearing_link * prev_dl;
  int index;
  void out = <<< error >>>;

  D.5260 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5260 != 0) goto <D.5261>; else goto <D.5262>;
  <D.5261>:
  GC_lock ();
  <D.5262>:
  link.8 = (long unsigned int) link;
  D.5264 = link.8 >> 3;
  D.5265 = (unsigned int) D.5264;
  link.8 = (long unsigned int) link;
  D.5266 = dl_hashtbl->log_size;
  D.5267 = (unsigned int) D.5266;
  D.5268 = D.5267 + 3;
  D.5269 = (int) D.5268;
  D.5270 = link.8 >> D.5269;
  D.5271 = (unsigned int) D.5270;
  D.5272 = D.5265 ^ D.5271;
  D.5266 = dl_hashtbl->log_size;
  D.5273 = (int) D.5266;
  D.5274 = 1 << D.5273;
  D.5275 = D.5274 + -1;
  D.5276 = (unsigned int) D.5275;
  D.5277 = D.5272 & D.5276;
  index = (int) D.5277;
  link.8 = (long unsigned int) link;
  D.5278 = link.8 & 7;
  if (D.5278 != 0) goto out; else goto <D.5279>;
  <D.5279>:
  prev_dl = 0B;
  D.5280 = dl_hashtbl->head;
  D.5281 = (long unsigned int) index;
  D.5282 = D.5281 * 8;
  D.5283 = D.5280 + D.5282;
  curr_dl = *D.5283;
  goto <D.4939>;
  <D.4938>:
  D.5284 = curr_dl->prolog.hidden_key;
  link.8 = (long unsigned int) link;
  D.5285 = ~link.8;
  if (D.5284 == D.5285) goto <D.5286>; else goto <D.5287>;
  <D.5286>:
  if (prev_dl == 0B) goto <D.5288>; else goto <D.5289>;
  <D.5288>:
  D.5280 = dl_hashtbl->head;
  D.5281 = (long unsigned int) index;
  D.5282 = D.5281 * 8;
  D.5283 = D.5280 + D.5282;
  D.5290 = curr_dl->prolog.next;
  *D.5283 = D.5290;
  goto <D.5291>;
  <D.5289>:
  D.5290 = curr_dl->prolog.next;
  prev_dl->prolog.next = D.5290;
  <D.5291>:
  D.5292 = dl_hashtbl->entries;
  D.5293 = D.5292 + 18446744073709551615;
  dl_hashtbl->entries = D.5293;
  pthread_mutex_unlock (&GC_allocate_ml);
  GC_free (curr_dl);
  D.5294 = 1;
  return D.5294;
  <D.5287>:
  prev_dl = curr_dl;
  curr_dl = curr_dl->prolog.next;
  <D.4939>:
  if (curr_dl != 0B) goto <D.4938>; else goto <D.4940>;
  <D.4940>:
  out:
  pthread_mutex_unlock (&GC_allocate_ml);
  D.5294 = 0;
  return D.5294;
}


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

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


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

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


GC_normal_finalize_mark_proc (char * p)
{
  struct mse * GC_mark_stack_top.9;
  struct mse * GC_mark_stack_top.10;
  struct mse * GC_mark_stack.11;
  long unsigned int GC_mark_stack_size.12;
  long unsigned int D.5307;
  struct GC_ms_entry * D.5308;
  struct mse * GC_mark_stack_top.13;
  struct mse * GC_mark_stack_top.14;
  struct mse * GC_mark_stack_top.15;
  struct mse * GC_mark_stack_top.16;
  struct mse * GC_mark_stack_top.17;
  struct hdr * hhdr;

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

    _descr = hhdr->hb_descr;
    if (_descr == 0) goto <D.5300>; else goto <D.5301>;
    <D.5300>:
    goto <D.5302>;
    <D.5301>:
    GC_mark_stack_top.9 = GC_mark_stack_top;
    GC_mark_stack_top.10 = GC_mark_stack_top.9 + 16;
    GC_mark_stack_top = GC_mark_stack_top.10;
    GC_mark_stack.11 = GC_mark_stack;
    GC_mark_stack_size.12 = GC_mark_stack_size;
    D.5307 = GC_mark_stack_size.12 * 16;
    D.5308 = GC_mark_stack.11 + D.5307;
    GC_mark_stack_top.13 = GC_mark_stack_top;
    if (D.5308 <= GC_mark_stack_top.13) goto <D.5310>; else goto <D.5311>;
    <D.5310>:
    GC_mark_stack_top.14 = GC_mark_stack_top;
    GC_mark_stack_top.15 = GC_signal_mark_stack_overflow (GC_mark_stack_top.14);
    GC_mark_stack_top = GC_mark_stack_top.15;
    <D.5311>:
    GC_mark_stack_top.16 = GC_mark_stack_top;
    GC_mark_stack_top.16->mse_start = p;
    GC_mark_stack_top.17 = GC_mark_stack_top;
    GC_mark_stack_top.17->mse_descr = _descr;
    <D.5302>:
  }
}


GC_ignore_self_finalize_mark_proc (char * p)
{
  long unsigned int D.5316;
  long unsigned int D.5317;
  sizetype D.5318;
  long unsigned int D.5319;
  sizetype D.5322;
  _Bool D.5324;
  _Bool D.5325;
  _Bool D.5326;
  void * GC_least_plausible_heap_addr.18;
  void * GC_greatest_plausible_heap_addr.19;
  struct mse * GC_mark_stack_limit.20;
  struct mse * GC_mark_stack_top.21;
  struct GC_ms_entry * GC_mark_stack_top.22;
  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.5316 = hhdr->hb_sz;
  D.5317 = D.5316 << 3;
  D.5318 = D.5317 + 18446744073709551615;
  target_limit = p + D.5318;
  D.5319 = descr & 3;
  if (D.5319 == 0) goto <D.5320>; else goto <D.5321>;
  <D.5320>:
  D.5322 = descr + 18446744073709551608;
  scan_limit = p + D.5322;
  goto <D.5323>;
  <D.5321>:
  scan_limit = target_limit + 18446744073709551609;
  <D.5323>:
  q = p;
  goto <D.4963>;
  <D.4962>:
  r = MEM[(char * *)q];
  D.5324 = r < p;
  D.5325 = r > target_limit;
  D.5326 = D.5324 | D.5325;
  if (D.5326 != 0) goto <D.5327>; else goto <D.5328>;
  <D.5327>:
  GC_least_plausible_heap_addr.18 = GC_least_plausible_heap_addr;
  if (r >= GC_least_plausible_heap_addr.18) goto <D.5330>; else goto <D.5331>;
  <D.5330>:
  GC_greatest_plausible_heap_addr.19 = GC_greatest_plausible_heap_addr;
  if (r < GC_greatest_plausible_heap_addr.19) goto <D.5333>; else goto <D.5334>;
  <D.5333>:
  GC_mark_stack_limit.20 = GC_mark_stack_limit;
  GC_mark_stack_top.21 = GC_mark_stack_top;
  GC_mark_stack_top.22 = GC_mark_and_push (r, GC_mark_stack_top.21, GC_mark_stack_limit.20, q);
  GC_mark_stack_top = GC_mark_stack_top.22;
  <D.5334>:
  <D.5331>:
  <D.5328>:
  q = q + 8;
  <D.4963>:
  if (q <= scan_limit) goto <D.4962>; else goto <D.4964>;
  <D.4964>:
}


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 (*<Tdbe>) () mp)
{
  int D.5338;
  long int log_fo_table_size.23;
  int D.5345;
  long unsigned int D.5346;
  long unsigned int GC_fo_entries.24;
  int GC_print_stats.25;
  int D.5351;
  long int D.5352;
  long unsigned int base.26;
  long unsigned int D.5354;
  unsigned int D.5355;
  unsigned int D.5356;
  unsigned int D.5357;
  int D.5358;
  long unsigned int D.5359;
  unsigned int D.5360;
  unsigned int D.5361;
  int D.5362;
  unsigned int D.5363;
  unsigned int D.5364;
  struct finalizable_object * * fo_head.27;
  long unsigned int D.5366;
  long unsigned int D.5367;
  struct finalizable_object * * D.5368;
  long unsigned int D.5369;
  long unsigned int D.5370;
  char * D.5375;
  void (*<T3fb>) (void *, void *) D.5378;
  struct hash_chain_entry * D.5381;
  long unsigned int GC_fo_entries.28;
  long unsigned int D.5396;
  long unsigned int D.5397;
  struct bottom_index * D.5399;
  long unsigned int D.5400;
  long unsigned int D.5401;
  void * (*<T397>) (size_t) GC_oom_fn.29;
  unsigned int GC_finalization_failures.30;
  unsigned int GC_finalization_failures.31;
  int D.5411;
  long unsigned int D.5414;
  struct finalizable_object * D.5415;
  long unsigned int GC_fo_entries.32;
  char * base;
  struct finalizable_object * curr_fo;
  struct finalizable_object * prev_fo;
  int index;
  struct finalizable_object * new_fo;
  struct hdr * hhdr;

  D.5338 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5338 != 0) goto <D.5339>; else goto <D.5340>;
  <D.5339>:
  GC_lock ();
  <D.5340>:
  log_fo_table_size.23 = log_fo_table_size;
  if (log_fo_table_size.23 == -1) goto <D.5341>; else goto <D.5344>;
  <D.5344>:
  log_fo_table_size.23 = log_fo_table_size;
  D.5345 = (int) log_fo_table_size.23;
  D.5346 = 1 << D.5345;
  GC_fo_entries.24 = GC_fo_entries;
  if (D.5346 < GC_fo_entries.24) goto <D.5341>; else goto <D.5342>;
  <D.5341>:
  GC_grow_table (&fo_head, &log_fo_table_size);
  GC_print_stats.25 = GC_print_stats;
  if (GC_print_stats.25 != 0) goto <D.5349>; else goto <D.5350>;
  <D.5349>:
  log_fo_table_size.23 = log_fo_table_size;
  D.5345 = (int) log_fo_table_size.23;
  D.5351 = 1 << D.5345;
  D.5352 = (long int) D.5351;
  GC_printf ("Grew fo table to %lu entries\n", D.5352, 0, 0, 0, 0, 0);
  <D.5350>:
  <D.5342>:
  base = obj;
  base.26 = (long unsigned int) base;
  D.5354 = base.26 >> 3;
  D.5355 = (unsigned int) D.5354;
  base.26 = (long unsigned int) base;
  log_fo_table_size.23 = log_fo_table_size;
  D.5356 = (unsigned int) log_fo_table_size.23;
  D.5357 = D.5356 + 3;
  D.5358 = (int) D.5357;
  D.5359 = base.26 >> D.5358;
  D.5360 = (unsigned int) D.5359;
  D.5361 = D.5355 ^ D.5360;
  log_fo_table_size.23 = log_fo_table_size;
  D.5345 = (int) log_fo_table_size.23;
  D.5351 = 1 << D.5345;
  D.5362 = D.5351 + -1;
  D.5363 = (unsigned int) D.5362;
  D.5364 = D.5361 & D.5363;
  index = (int) D.5364;
  prev_fo = 0B;
  fo_head.27 = fo_head;
  D.5366 = (long unsigned int) index;
  D.5367 = D.5366 * 8;
  D.5368 = fo_head.27 + D.5367;
  curr_fo = *D.5368;
  goto <D.4983>;
  <D.4982>:
  D.5369 = curr_fo->prolog.hidden_key;
  base.26 = (long unsigned int) base;
  D.5370 = ~base.26;
  if (D.5369 == D.5370) goto <D.5371>; else goto <D.5372>;
  <D.5371>:
  if (ocd != 0B) goto <D.5373>; else goto <D.5374>;
  <D.5373>:
  D.5375 = curr_fo->fo_client_data;
  *ocd = D.5375;
  <D.5374>:
  if (ofn != 0B) goto <D.5376>; else goto <D.5377>;
  <D.5376>:
  D.5378 = curr_fo->fo_fn;
  *ofn = D.5378;
  <D.5377>:
  if (prev_fo == 0B) goto <D.5379>; else goto <D.5380>;
  <D.5379>:
  fo_head.27 = fo_head;
  D.5366 = (long unsigned int) index;
  D.5367 = D.5366 * 8;
  D.5368 = fo_head.27 + D.5367;
  D.5381 = curr_fo->prolog.next;
  *D.5368 = D.5381;
  goto <D.5382>;
  <D.5380>:
  D.5381 = curr_fo->prolog.next;
  prev_fo->prolog.next = D.5381;
  <D.5382>:
  if (fn == 0B) goto <D.5383>; else goto <D.5384>;
  <D.5383>:
  GC_fo_entries.24 = GC_fo_entries;
  GC_fo_entries.28 = GC_fo_entries.24 + 18446744073709551615;
  GC_fo_entries = GC_fo_entries.28;
  goto <D.5386>;
  <D.5384>:
  curr_fo->fo_fn = fn;
  curr_fo->fo_client_data = cd;
  curr_fo->fo_mark_proc = mp;
  if (prev_fo == 0B) goto <D.5387>; else goto <D.5388>;
  <D.5387>:
  fo_head.27 = fo_head;
  D.5366 = (long unsigned int) index;
  D.5367 = D.5366 * 8;
  D.5368 = fo_head.27 + D.5367;
  *D.5368 = curr_fo;
  goto <D.5389>;
  <D.5388>:
  prev_fo->prolog.next = curr_fo;
  <D.5389>:
  <D.5386>:
  pthread_mutex_unlock (&GC_allocate_ml);
  return;
  <D.5372>:
  prev_fo = curr_fo;
  curr_fo = curr_fo->prolog.next;
  <D.4983>:
  if (curr_fo != 0B) goto <D.4982>; else goto <D.4984>;
  <D.4984>:
  if (ofn != 0B) goto <D.5390>; else goto <D.5391>;
  <D.5390>:
  *ofn = 0B;
  <D.5391>:
  if (ocd != 0B) goto <D.5392>; else goto <D.5393>;
  <D.5392>:
  *ocd = 0B;
  <D.5393>:
  if (fn == 0B) goto <D.5394>; else goto <D.5395>;
  <D.5394>:
  pthread_mutex_unlock (&GC_allocate_ml);
  return;
  <D.5395>:
  {
    register struct hdr * * _ha;

    {
      register struct bottom_index * bi;

      {
        register word hi;
        register struct bottom_index * _bi;

        base.26 = (long unsigned int) base;
        hi = base.26 >> 22;
        D.5396 = hi & 2047;
        _bi = GC_arrays._top_index[D.5396];
        goto <D.4990>;
        <D.4989>:
        _bi = _bi->hash_link;
        <D.4990>:
        D.5397 = _bi->key;
        if (D.5397 != hi) goto <D.5398>; else goto <D.4991>;
        <D.5398>:
        D.5399 = GC_arrays._all_nils;
        if (D.5399 != _bi) goto <D.4989>; else goto <D.4991>;
        <D.4991>:
        bi = _bi;
      }
      base.26 = (long unsigned int) base;
      D.5400 = base.26 >> 12;
      D.5401 = D.5400 & 1023;
      _ha = &bi->index[D.5401];
    }
    hhdr = *_ha;
  }
  if (hhdr == 0B) goto <D.5402>; else goto <D.5403>;
  <D.5402>:
  pthread_mutex_unlock (&GC_allocate_ml);
  return;
  <D.5403>:
  new_fo = GC_generic_malloc_inner (48, 1);
  if (new_fo == 0B) goto <D.5404>; else goto <D.5405>;
  <D.5404>:
  pthread_mutex_unlock (&GC_allocate_ml);
  GC_oom_fn.29 = GC_oom_fn;
  new_fo = GC_oom_fn.29 (48);
  if (new_fo == 0B) goto <D.5407>; else goto <D.5408>;
  <D.5407>:
  GC_finalization_failures.30 = GC_finalization_failures;
  GC_finalization_failures.31 = GC_finalization_failures.30 + 1;
  GC_finalization_failures = GC_finalization_failures.31;
  return;
  <D.5408>:
  D.5411 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5411 != 0) goto <D.5412>; else goto <D.5413>;
  <D.5412>:
  GC_lock ();
  <D.5413>:
  <D.5405>:
  base.26 = (long unsigned int) base;
  D.5370 = ~base.26;
  new_fo->prolog.hidden_key = D.5370;
  new_fo->fo_fn = fn;
  new_fo->fo_client_data = cd;
  D.5414 = hhdr->hb_sz;
  new_fo->fo_object_size = D.5414;
  new_fo->fo_mark_proc = mp;
  fo_head.27 = fo_head;
  D.5366 = (long unsigned int) index;
  D.5367 = D.5366 * 8;
  D.5368 = fo_head.27 + D.5367;
  D.5415 = *D.5368;
  new_fo->prolog.next = D.5415;
  GC_fo_entries.24 = GC_fo_entries;
  GC_fo_entries.32 = GC_fo_entries.24 + 1;
  GC_fo_entries = GC_fo_entries.32;
  fo_head.27 = fo_head;
  D.5366 = (long unsigned int) index;
  D.5367 = D.5366 * 8;
  D.5368 = fo_head.27 + D.5367;
  *D.5368 = 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.33;
  long int log_fo_table_size.34;
  int D.5422;
  struct finalizable_object * * fo_head.35;
  long unsigned int D.5425;
  long unsigned int D.5426;
  struct finalizable_object * * D.5427;
  long unsigned int D.5428;
  long unsigned int D.5429;
  long int real_ptr.36;
  struct finalizable_object * curr_fo;
  char * real_ptr;
  int fo_size;
  int i;

  log_fo_table_size.34 = log_fo_table_size;
  if (log_fo_table_size.34 != -1) goto <D.5420>; else goto <D.5421>;
  <D.5420>:
  log_fo_table_size.34 = log_fo_table_size;
  D.5422 = (int) log_fo_table_size.34;
  iftmp.33 = 1 << D.5422;
  goto <D.5423>;
  <D.5421>:
  iftmp.33 = 0;
  <D.5423>:
  fo_size = iftmp.33;
  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.5037>;
  <D.5036>:
  fo_head.35 = fo_head;
  D.5425 = (long unsigned int) i;
  D.5426 = D.5425 * 8;
  D.5427 = fo_head.35 + D.5426;
  curr_fo = *D.5427;
  goto <D.5034>;
  <D.5033>:
  D.5428 = curr_fo->prolog.hidden_key;
  D.5429 = ~D.5428;
  real_ptr = (char *) D.5429;
  real_ptr.36 = (long int) real_ptr;
  GC_printf ("Finalizable object: 0x%lx\n", real_ptr.36, 0, 0, 0, 0, 0);
  curr_fo = curr_fo->prolog.next;
  <D.5034>:
  if (curr_fo != 0B) goto <D.5033>; else goto <D.5035>;
  <D.5035>:
  i = i + 1;
  <D.5037>:
  if (i < fo_size) goto <D.5036>; else goto <D.5038>;
  <D.5038>:
}


GC_dump_finalization_links (struct dl_hashtbl_s * dl_hashtbl)
{
  size_t iftmp.37;
  long int D.5432;
  int D.5435;
  int D.5436;
  struct disappearing_link * * D.5438;
  long unsigned int D.5439;
  long unsigned int D.5440;
  struct disappearing_link * * D.5441;
  long unsigned int D.5442;
  long unsigned int D.5443;
  long unsigned int D.5444;
  long unsigned int D.5445;
  long int real_link.38;
  long int real_ptr.39;
  long unsigned int D.5448;
  struct disappearing_link * curr_dl;
  char * real_ptr;
  char * real_link;
  size_t dl_size;
  int i;

  D.5432 = dl_hashtbl->log_size;
  if (D.5432 != -1) goto <D.5433>; else goto <D.5434>;
  <D.5433>:
  D.5432 = dl_hashtbl->log_size;
  D.5435 = (int) D.5432;
  D.5436 = 1 << D.5435;
  iftmp.37 = (size_t) D.5436;
  goto <D.5437>;
  <D.5434>:
  iftmp.37 = 0;
  <D.5437>:
  dl_size = iftmp.37;
  i = 0;
  goto <D.5025>;
  <D.5024>:
  D.5438 = dl_hashtbl->head;
  D.5439 = (long unsigned int) i;
  D.5440 = D.5439 * 8;
  D.5441 = D.5438 + D.5440;
  curr_dl = *D.5441;
  goto <D.5022>;
  <D.5021>:
  D.5442 = curr_dl->dl_hidden_obj;
  D.5443 = ~D.5442;
  real_ptr = (char *) D.5443;
  D.5444 = curr_dl->prolog.hidden_key;
  D.5445 = ~D.5444;
  real_link = (char *) D.5445;
  real_link.38 = (long int) real_link;
  real_ptr.39 = (long int) real_ptr;
  GC_printf ("Object: %lx, link: %lx\n", real_ptr.39, real_link.38, 0, 0, 0, 0);
  curr_dl = curr_dl->prolog.next;
  <D.5022>:
  if (curr_dl != 0B) goto <D.5021>; else goto <D.5023>;
  <D.5023>:
  i = i + 1;
  <D.5025>:
  D.5448 = (long unsigned int) i;
  if (D.5448 < dl_size) goto <D.5024>; else goto <D.5026>;
  <D.5026>:
}


GC_finalize ()
{
  int iftmp.40;
  long int log_fo_table_size.41;
  int D.5453;
  struct finalizable_object * * fo_head.42;
  long unsigned int D.5456;
  long unsigned int D.5457;
  struct finalizable_object * * D.5458;
  long unsigned int D.5459;
  long unsigned int D.5460;
  int D.5461;
  void (*<Tdbe>) () D.5464;
  struct mse * GC_mark_stack.43;
  long unsigned int GC_mark_stack_size.44;
  long unsigned int D.5467;
  struct mse * D.5468;
  struct mse * GC_mark_stack_top.45;
  struct mse * GC_mark_stack_top.46;
  int D.5471;
  int GC_mark_state.47;
  int D.5475;
  int D.5476;
  void (*<T41a>) (char *, GC_word) GC_current_warn_proc.48;
  long unsigned int real_ptr.49;
  int D.5481;
  int GC_java_finalization.50;
  long unsigned int GC_fo_entries.51;
  long unsigned int GC_fo_entries.52;
  struct finalizable_object * GC_finalize_now.53;
  long unsigned int D.5493;
  long unsigned int D.5494;
  int GC_all_interior_pointers.54;
  int D.5496;
  long unsigned int D.5497;
  long unsigned int D.5498;
  long unsigned int D.5499;
  long unsigned int D.5500;
  long unsigned int D.5501;
  long unsigned int D.5502;
  long unsigned int D.5503;
  long unsigned int D.5504;
  int D.5508;
  struct mse * GC_mark_stack_top.55;
  struct mse * GC_mark_stack_top.56;
  int D.5515;
  int D.5518;
  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.41 = log_fo_table_size;
  if (log_fo_table_size.41 != -1) goto <D.5451>; else goto <D.5452>;
  <D.5451>:
  log_fo_table_size.41 = log_fo_table_size;
  D.5453 = (int) log_fo_table_size.41;
  iftmp.40 = 1 << D.5453;
  goto <D.5454>;
  <D.5452>:
  iftmp.40 = 0;
  <D.5454>:
  fo_size = iftmp.40;
  GC_make_disappearing_links_disappear (&GC_dl_hashtbl);
  i = 0;
  goto <D.5089>;
  <D.5088>:
  fo_head.42 = fo_head;
  D.5456 = (long unsigned int) i;
  D.5457 = D.5456 * 8;
  D.5458 = fo_head.42 + D.5457;
  curr_fo = *D.5458;
  goto <D.5086>;
  <D.5085>:
  D.5459 = curr_fo->prolog.hidden_key;
  D.5460 = ~D.5459;
  real_ptr = (char *) D.5460;
  D.5461 = GC_is_marked (real_ptr);
  if (D.5461 == 0) goto <D.5462>; else goto <D.5463>;
  <D.5462>:
  D.5464 = curr_fo->fo_mark_proc;
  D.5464 (real_ptr);
  goto <D.5080>;
  <D.5079>:
  GC_mark_stack.43 = GC_mark_stack;
  GC_mark_stack_size.44 = GC_mark_stack_size;
  D.5467 = GC_mark_stack_size.44 * 16;
  D.5468 = GC_mark_stack.43 + D.5467;
  GC_mark_stack.43 = GC_mark_stack;
  GC_mark_stack_top.45 = GC_mark_stack_top;
  GC_mark_stack_top.46 = GC_mark_from (GC_mark_stack_top.45, GC_mark_stack.43, D.5468);
  GC_mark_stack_top = GC_mark_stack_top.46;
  <D.5080>:
  D.5471 = GC_mark_stack_empty ();
  if (D.5471 == 0) goto <D.5079>; else goto <D.5081>;
  <D.5081>:
  GC_mark_state.47 = GC_mark_state;
  if (GC_mark_state.47 != 0) goto <D.5473>; else goto <D.5474>;
  <D.5473>:
  GC_set_mark_bit (real_ptr);
  goto <D.5083>;
  <D.5082>:
  <D.5083>:
  D.5475 = GC_mark_some (0B);
  if (D.5475 == 0) goto <D.5082>; else goto <D.5084>;
  <D.5084>:
  <D.5474>:
  D.5476 = GC_is_marked (real_ptr);
  if (D.5476 != 0) goto <D.5477>; else goto <D.5478>;
  <D.5477>:
  GC_current_warn_proc.48 = GC_current_warn_proc;
  real_ptr.49 = (long unsigned int) real_ptr;
  GC_current_warn_proc.48 ("GC Warning: Finalization cycle involving %lx\n", real_ptr.49);
  <D.5478>:
  <D.5463>:
  curr_fo = curr_fo->prolog.next;
  <D.5086>:
  if (curr_fo != 0B) goto <D.5085>; else goto <D.5087>;
  <D.5087>:
  i = i + 1;
  <D.5089>:
  if (i < fo_size) goto <D.5088>; else goto <D.5090>;
  <D.5090>:
  GC_arrays._words_finalized = 0;
  i = 0;
  goto <D.5095>;
  <D.5094>:
  fo_head.42 = fo_head;
  D.5456 = (long unsigned int) i;
  D.5457 = D.5456 * 8;
  D.5458 = fo_head.42 + D.5457;
  curr_fo = *D.5458;
  prev_fo = 0B;
  goto <D.5092>;
  <D.5091>:
  D.5459 = curr_fo->prolog.hidden_key;
  D.5460 = ~D.5459;
  real_ptr = (char *) D.5460;
  D.5481 = GC_is_marked (real_ptr);
  if (D.5481 == 0) goto <D.5482>; else goto <D.5483>;
  <D.5482>:
  GC_java_finalization.50 = GC_java_finalization;
  if (GC_java_finalization.50 == 0) goto <D.5485>; else goto <D.5486>;
  <D.5485>:
  GC_set_mark_bit (real_ptr);
  <D.5486>:
  next_fo = curr_fo->prolog.next;
  if (prev_fo == 0B) goto <D.5487>; else goto <D.5488>;
  <D.5487>:
  fo_head.42 = fo_head;
  D.5456 = (long unsigned int) i;
  D.5457 = D.5456 * 8;
  D.5458 = fo_head.42 + D.5457;
  *D.5458 = next_fo;
  goto <D.5489>;
  <D.5488>:
  prev_fo->prolog.next = next_fo;
  <D.5489>:
  GC_fo_entries.51 = GC_fo_entries;
  GC_fo_entries.52 = GC_fo_entries.51 + 18446744073709551615;
  GC_fo_entries = GC_fo_entries.52;
  GC_finalize_now.53 = GC_finalize_now;
  curr_fo->prolog.next = GC_finalize_now.53;
  GC_finalize_now = curr_fo;
  D.5459 = curr_fo->prolog.hidden_key;
  D.5460 = ~D.5459;
  curr_fo->prolog.hidden_key = D.5460;
  D.5493 = GC_arrays._words_finalized;
  D.5494 = curr_fo->fo_object_size;
  GC_all_interior_pointers.54 = GC_all_interior_pointers;
  D.5496 = GC_all_interior_pointers.54 + 7;
  D.5497 = (long unsigned int) D.5496;
  D.5498 = D.5494 + D.5497;
  D.5499 = D.5498 >> 3;
  GC_all_interior_pointers.54 = GC_all_interior_pointers;
  D.5496 = GC_all_interior_pointers.54 + 7;
  D.5500 = (long unsigned int) D.5496;
  D.5501 = D.5500 + 48;
  D.5502 = D.5501 >> 3;
  D.5503 = D.5499 + D.5502;
  D.5504 = D.5493 + D.5503;
  GC_arrays._words_finalized = D.5504;
  curr_fo = next_fo;
  goto <D.5505>;
  <D.5483>:
  prev_fo = curr_fo;
  curr_fo = curr_fo->prolog.next;
  <D.5505>:
  <D.5092>:
  if (curr_fo != 0B) goto <D.5091>; else goto <D.5093>;
  <D.5093>:
  i = i + 1;
  <D.5095>:
  if (i < fo_size) goto <D.5094>; else goto <D.5096>;
  <D.5096>:
  GC_java_finalization.50 = GC_java_finalization;
  if (GC_java_finalization.50 != 0) goto <D.5506>; else goto <D.5507>;
  <D.5506>:
  curr_fo = GC_finalize_now;
  goto <D.5104>;
  <D.5103>:
  D.5459 = curr_fo->prolog.hidden_key;
  real_ptr = (char *) D.5459;
  D.5508 = GC_is_marked (real_ptr);
  if (D.5508 == 0) goto <D.5509>; else goto <D.5510>;
  <D.5509>:
  D.5464 = curr_fo->fo_mark_proc;
  if (D.5464 == GC_null_finalize_mark_proc) goto <D.5511>; else goto <D.5512>;
  <D.5511>:
  GC_normal_finalize_mark_proc (real_ptr);
  goto <D.5098>;
  <D.5097>:
  GC_mark_stack.43 = GC_mark_stack;
  GC_mark_stack_size.44 = GC_mark_stack_size;
  D.5467 = GC_mark_stack_size.44 * 16;
  D.5468 = GC_mark_stack.43 + D.5467;
  GC_mark_stack.43 = GC_mark_stack;
  GC_mark_stack_top.55 = GC_mark_stack_top;
  GC_mark_stack_top.56 = GC_mark_from (GC_mark_stack_top.55, GC_mark_stack.43, D.5468);
  GC_mark_stack_top = GC_mark_stack_top.56;
  <D.5098>:
  D.5515 = GC_mark_stack_empty ();
  if (D.5515 == 0) goto <D.5097>; else goto <D.5099>;
  <D.5099>:
  GC_mark_state.47 = GC_mark_state;
  if (GC_mark_state.47 != 0) goto <D.5516>; else goto <D.5517>;
  <D.5516>:
  GC_set_mark_bit (real_ptr);
  goto <D.5101>;
  <D.5100>:
  <D.5101>:
  D.5518 = GC_mark_some (0B);
  if (D.5518 == 0) goto <D.5100>; else goto <D.5102>;
  <D.5102>:
  <D.5517>:
  <D.5512>:
  GC_set_mark_bit (real_ptr);
  <D.5510>:
  curr_fo = curr_fo->prolog.next;
  <D.5104>:
  if (curr_fo != 0B) goto <D.5103>; else goto <D.5105>;
  <D.5105>:
  <D.5507>:
  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.57;
  long int D.5520;
  int D.5523;
  struct disappearing_link * * D.5525;
  long unsigned int D.5526;
  long unsigned int D.5527;
  struct disappearing_link * * D.5528;
  long unsigned int D.5529;
  long unsigned int D.5530;
  long unsigned int D.5531;
  long unsigned int D.5532;
  int D.5533;
  long unsigned int D.5539;
  long unsigned int D.5540;
  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.5520 = dl_hashtbl->log_size;
  if (D.5520 != -1) goto <D.5521>; else goto <D.5522>;
  <D.5521>:
  D.5520 = dl_hashtbl->log_size;
  D.5523 = (int) D.5520;
  iftmp.57 = 1 << D.5523;
  goto <D.5524>;
  <D.5522>:
  iftmp.57 = 0;
  <D.5524>:
  dl_size = iftmp.57;
  i = 0;
  goto <D.5053>;
  <D.5052>:
  D.5525 = dl_hashtbl->head;
  D.5526 = (long unsigned int) i;
  D.5527 = D.5526 * 8;
  D.5528 = D.5525 + D.5527;
  curr_dl = *D.5528;
  prev_dl = 0B;
  goto <D.5050>;
  <D.5049>:
  D.5529 = curr_dl->dl_hidden_obj;
  D.5530 = ~D.5529;
  real_ptr = (char *) D.5530;
  D.5531 = curr_dl->prolog.hidden_key;
  D.5532 = ~D.5531;
  real_link = (char *) D.5532;
  D.5533 = GC_is_marked (real_ptr);
  if (D.5533 == 0) goto <D.5534>; else goto <D.5535>;
  <D.5534>:
  MEM[(word *)real_link] = 0;
  next_dl = curr_dl->prolog.next;
  if (prev_dl == 0B) goto <D.5536>; else goto <D.5537>;
  <D.5536>:
  D.5525 = dl_hashtbl->head;
  D.5526 = (long unsigned int) i;
  D.5527 = D.5526 * 8;
  D.5528 = D.5525 + D.5527;
  *D.5528 = next_dl;
  goto <D.5538>;
  <D.5537>:
  prev_dl->prolog.next = next_dl;
  <D.5538>:
  GC_clear_mark_bit (curr_dl);
  D.5539 = dl_hashtbl->entries;
  D.5540 = D.5539 + 18446744073709551615;
  dl_hashtbl->entries = D.5540;
  curr_dl = next_dl;
  goto <D.5541>;
  <D.5535>:
  prev_dl = curr_dl;
  curr_dl = curr_dl->prolog.next;
  <D.5541>:
  <D.5050>:
  if (curr_dl != 0B) goto <D.5049>; else goto <D.5051>;
  <D.5051>:
  i = i + 1;
  <D.5053>:
  if (i < dl_size) goto <D.5052>; else goto <D.5054>;
  <D.5054>:
}


GC_remove_dangling_disappearing_links (struct dl_hashtbl_s * dl_hashtbl)
{
  int iftmp.58;
  long int D.5543;
  int D.5546;
  struct disappearing_link * * D.5548;
  long unsigned int D.5549;
  long unsigned int D.5550;
  struct disappearing_link * * D.5551;
  long unsigned int D.5552;
  long unsigned int D.5553;
  void * D.5554;
  int D.5558;
  long unsigned int D.5563;
  long unsigned int D.5564;
  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.5543 = dl_hashtbl->log_size;
  if (D.5543 != -1) goto <D.5544>; else goto <D.5545>;
  <D.5544>:
  D.5543 = dl_hashtbl->log_size;
  D.5546 = (int) D.5543;
  iftmp.58 = 1 << D.5546;
  goto <D.5547>;
  <D.5545>:
  iftmp.58 = 0;
  <D.5547>:
  dl_size = iftmp.58;
  i = 0;
  goto <D.5069>;
  <D.5068>:
  D.5548 = dl_hashtbl->head;
  D.5549 = (long unsigned int) i;
  D.5550 = D.5549 * 8;
  D.5551 = D.5548 + D.5550;
  curr_dl = *D.5551;
  prev_dl = 0B;
  goto <D.5066>;
  <D.5065>:
  D.5552 = curr_dl->prolog.hidden_key;
  D.5553 = ~D.5552;
  D.5554 = (void *) D.5553;
  real_link = GC_base (D.5554);
  if (real_link != 0B) goto <D.5557>; else goto <D.5555>;
  <D.5557>:
  D.5558 = GC_is_marked (real_link);
  if (D.5558 == 0) goto <D.5559>; else goto <D.5555>;
  <D.5559>:
  next_dl = curr_dl->prolog.next;
  if (prev_dl == 0B) goto <D.5560>; else goto <D.5561>;
  <D.5560>:
  D.5548 = dl_hashtbl->head;
  D.5549 = (long unsigned int) i;
  D.5550 = D.5549 * 8;
  D.5551 = D.5548 + D.5550;
  *D.5551 = next_dl;
  goto <D.5562>;
  <D.5561>:
  prev_dl->prolog.next = next_dl;
  <D.5562>:
  GC_clear_mark_bit (curr_dl);
  D.5563 = dl_hashtbl->entries;
  D.5564 = D.5563 + 18446744073709551615;
  dl_hashtbl->entries = D.5564;
  curr_dl = next_dl;
  goto <D.5556>;
  <D.5555>:
  prev_dl = curr_dl;
  curr_dl = curr_dl->prolog.next;
  <D.5556>:
  <D.5066>:
  if (curr_dl != 0B) goto <D.5065>; else goto <D.5067>;
  <D.5067>:
  i = i + 1;
  <D.5069>:
  if (i < dl_size) goto <D.5068>; else goto <D.5070>;
  <D.5070>:
}


GC_enqueue_all_finalizers ()
{
  int iftmp.59;
  long int log_fo_table_size.60;
  int D.5569;
  struct finalizable_object * * fo_head.61;
  long unsigned int D.5572;
  long unsigned int D.5573;
  struct finalizable_object * * D.5574;
  long unsigned int D.5575;
  long unsigned int D.5576;
  struct mse * GC_mark_stack.62;
  long unsigned int GC_mark_stack_size.63;
  long unsigned int D.5579;
  struct mse * D.5580;
  struct mse * GC_mark_stack_top.64;
  struct mse * GC_mark_stack_top.65;
  int D.5583;
  int GC_mark_state.66;
  int D.5587;
  long unsigned int GC_fo_entries.67;
  long unsigned int GC_fo_entries.68;
  struct finalizable_object * GC_finalize_now.69;
  long unsigned int D.5594;
  long unsigned int D.5595;
  int GC_all_interior_pointers.70;
  int D.5597;
  long unsigned int D.5598;
  long unsigned int D.5599;
  long unsigned int D.5600;
  long unsigned int D.5601;
  long unsigned int D.5602;
  long unsigned int D.5603;
  long unsigned int D.5604;
  long unsigned int D.5605;
  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.60 = log_fo_table_size;
  if (log_fo_table_size.60 != -1) goto <D.5567>; else goto <D.5568>;
  <D.5567>:
  log_fo_table_size.60 = log_fo_table_size;
  D.5569 = (int) log_fo_table_size.60;
  iftmp.59 = 1 << D.5569;
  goto <D.5570>;
  <D.5568>:
  iftmp.59 = 0;
  <D.5570>:
  fo_size = iftmp.59;
  GC_arrays._words_finalized = 0;
  i = 0;
  goto <D.5124>;
  <D.5123>:
  fo_head.61 = fo_head;
  D.5572 = (long unsigned int) i;
  D.5573 = D.5572 * 8;
  D.5574 = fo_head.61 + D.5573;
  curr_fo = *D.5574;
  prev_fo = 0B;
  goto <D.5121>;
  <D.5120>:
  D.5575 = curr_fo->prolog.hidden_key;
  D.5576 = ~D.5575;
  real_ptr = (char *) D.5576;
  GC_normal_finalize_mark_proc (real_ptr);
  goto <D.5115>;
  <D.5114>:
  GC_mark_stack.62 = GC_mark_stack;
  GC_mark_stack_size.63 = GC_mark_stack_size;
  D.5579 = GC_mark_stack_size.63 * 16;
  D.5580 = GC_mark_stack.62 + D.5579;
  GC_mark_stack.62 = GC_mark_stack;
  GC_mark_stack_top.64 = GC_mark_stack_top;
  GC_mark_stack_top.65 = GC_mark_from (GC_mark_stack_top.64, GC_mark_stack.62, D.5580);
  GC_mark_stack_top = GC_mark_stack_top.65;
  <D.5115>:
  D.5583 = GC_mark_stack_empty ();
  if (D.5583 == 0) goto <D.5114>; else goto <D.5116>;
  <D.5116>:
  GC_mark_state.66 = GC_mark_state;
  if (GC_mark_state.66 != 0) goto <D.5585>; else goto <D.5586>;
  <D.5585>:
  GC_set_mark_bit (real_ptr);
  goto <D.5118>;
  <D.5117>:
  <D.5118>:
  D.5587 = GC_mark_some (0B);
  if (D.5587 == 0) goto <D.5117>; else goto <D.5119>;
  <D.5119>:
  <D.5586>:
  GC_set_mark_bit (real_ptr);
  next_fo = curr_fo->prolog.next;
  if (prev_fo == 0B) goto <D.5588>; else goto <D.5589>;
  <D.5588>:
  fo_head.61 = fo_head;
  D.5572 = (long unsigned int) i;
  D.5573 = D.5572 * 8;
  D.5574 = fo_head.61 + D.5573;
  *D.5574 = next_fo;
  goto <D.5590>;
  <D.5589>:
  prev_fo->prolog.next = next_fo;
  <D.5590>:
  GC_fo_entries.67 = GC_fo_entries;
  GC_fo_entries.68 = GC_fo_entries.67 + 18446744073709551615;
  GC_fo_entries = GC_fo_entries.68;
  GC_finalize_now.69 = GC_finalize_now;
  curr_fo->prolog.next = GC_finalize_now.69;
  GC_finalize_now = curr_fo;
  D.5575 = curr_fo->prolog.hidden_key;
  D.5576 = ~D.5575;
  curr_fo->prolog.hidden_key = D.5576;
  D.5594 = GC_arrays._words_finalized;
  D.5595 = curr_fo->fo_object_size;
  GC_all_interior_pointers.70 = GC_all_interior_pointers;
  D.5597 = GC_all_interior_pointers.70 + 7;
  D.5598 = (long unsigned int) D.5597;
  D.5599 = D.5595 + D.5598;
  D.5600 = D.5599 >> 3;
  GC_all_interior_pointers.70 = GC_all_interior_pointers;
  D.5597 = GC_all_interior_pointers.70 + 7;
  D.5601 = (long unsigned int) D.5597;
  D.5602 = D.5601 + 48;
  D.5603 = D.5602 >> 3;
  D.5604 = D.5600 + D.5603;
  D.5605 = D.5594 + D.5604;
  GC_arrays._words_finalized = D.5605;
  curr_fo = next_fo;
  <D.5121>:
  if (curr_fo != 0B) goto <D.5120>; else goto <D.5122>;
  <D.5122>:
  i = i + 1;
  <D.5124>:
  if (i < fo_size) goto <D.5123>; else goto <D.5125>;
  <D.5125>:
  return;
}


GC_finalize_all ()
{
  int D.5607;
  int D.5610;
  long unsigned int GC_fo_entries.71;

  D.5607 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5607 != 0) goto <D.5608>; else goto <D.5609>;
  <D.5608>:
  GC_lock ();
  <D.5609>:
  goto <D.5129>;
  <D.5128>:
  GC_enqueue_all_finalizers ();
  pthread_mutex_unlock (&GC_allocate_ml);
  GC_notify_or_invoke_finalizers ();
  D.5610 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5610 != 0) goto <D.5611>; else goto <D.5612>;
  <D.5611>:
  GC_lock ();
  <D.5612>:
  <D.5129>:
  GC_fo_entries.71 = GC_fo_entries;
  if (GC_fo_entries.71 != 0) goto <D.5128>; else goto <D.5130>;
  <D.5130>:
  pthread_mutex_unlock (&GC_allocate_ml);
}


GC_should_invoke_finalizers ()
{
  int D.5614;
  struct finalizable_object * GC_finalize_now.72;
  _Bool D.5616;

  GC_finalize_now.72 = GC_finalize_now;
  D.5616 = GC_finalize_now.72 != 0B;
  D.5614 = (int) D.5616;
  return D.5614;
}


GC_invoke_finalizers ()
{
  int D.5618;
  struct hash_chain_entry * GC_finalize_now.73;
  void (*<T3fb>) (void *, void *) D.5627;
  char * D.5628;
  long unsigned int D.5629;
  void * D.5630;
  struct finalizable_object * GC_finalize_now.74;
  long unsigned int D.5634;
  int D.5637;
  long unsigned int D.5640;
  long unsigned int D.5641;
  long unsigned int D.5642;
  int D.5643;
  struct finalizable_object * curr_fo;
  int count;
  word mem_freed_before;

  count = 0;
  goto <D.5141>;
  <D.5140>:
  D.5618 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5618 != 0) goto <D.5619>; else goto <D.5620>;
  <D.5619>:
  GC_lock ();
  <D.5620>:
  if (count == 0) goto <D.5621>; else goto <D.5622>;
  <D.5621>:
  mem_freed_before = GC_arrays._mem_freed;
  <D.5622>:
  curr_fo = GC_finalize_now;
  if (curr_fo != 0B) goto <D.5623>; else goto <D.5624>;
  <D.5623>:
  GC_finalize_now.73 = curr_fo->prolog.next;
  GC_finalize_now = GC_finalize_now.73;
  <D.5624>:
  pthread_mutex_unlock (&GC_allocate_ml);
  if (curr_fo == 0B) goto <D.5139>; else goto <D.5626>;
  <D.5626>:
  curr_fo->prolog.next = 0B;
  D.5627 = curr_fo->fo_fn;
  D.5628 = curr_fo->fo_client_data;
  D.5629 = curr_fo->prolog.hidden_key;
  D.5630 = (void *) D.5629;
  D.5627 (D.5630, D.5628);
  curr_fo->fo_client_data = 0B;
  count = count + 1;
  <D.5141>:
  GC_finalize_now.74 = GC_finalize_now;
  if (GC_finalize_now.74 != 0B) goto <D.5140>; else goto <D.5139>;
  <D.5139>:
  if (count != 0) goto <D.5632>; else goto <D.5633>;
  <D.5632>:
  D.5634 = GC_arrays._mem_freed;
  if (D.5634 != mem_freed_before) goto <D.5635>; else goto <D.5636>;
  <D.5635>:
  D.5637 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5637 != 0) goto <D.5638>; else goto <D.5639>;
  <D.5638>:
  GC_lock ();
  <D.5639>:
  D.5640 = GC_arrays._finalizer_mem_freed;
  D.5634 = GC_arrays._mem_freed;
  D.5641 = D.5634 - mem_freed_before;
  D.5642 = D.5640 + D.5641;
  GC_arrays._finalizer_mem_freed = D.5642;
  pthread_mutex_unlock (&GC_allocate_ml);
  <D.5636>:
  <D.5633>:
  D.5643 = count;
  return D.5643;
}


GC_notify_or_invoke_finalizers ()
{
  struct finalizable_object * GC_finalize_now.75;
  int GC_finalize_on_demand.76;
  void (*<T3a4>) (void) GC_finalizer_notifier.77;
  long unsigned int last_finalizer_notification.78;
  long unsigned int GC_gc_no.79;

  GC_finalize_now.75 = GC_finalize_now;
  if (GC_finalize_now.75 == 0B) goto <D.5646>; else goto <D.5647>;
  <D.5646>:
  return;
  <D.5647>:
  GC_finalize_on_demand.76 = GC_finalize_on_demand;
  if (GC_finalize_on_demand.76 == 0) goto <D.5649>; else goto <D.5650>;
  <D.5649>:
  GC_invoke_finalizers ();
  return;
  <D.5650>:
  GC_finalizer_notifier.77 = GC_finalizer_notifier;
  if (GC_finalizer_notifier.77 != 0B) goto <D.5652>; else goto <D.5653>;
  <D.5652>:
  last_finalizer_notification.78 = last_finalizer_notification;
  GC_gc_no.79 = GC_gc_no;
  if (last_finalizer_notification.78 != GC_gc_no.79) goto <D.5656>; else goto <D.5657>;
  <D.5656>:
  GC_gc_no.79 = GC_gc_no;
  last_finalizer_notification = GC_gc_no.79;
  GC_finalizer_notifier.77 = GC_finalizer_notifier;
  GC_finalizer_notifier.77 ();
  <D.5657>:
  <D.5653>:
}


GC_call_with_alloc_lock (void * (*GC_fn_type) (void *) fn, void * client_data)
{
  int D.5659;
  long unsigned int GC_lock_holder.80;
  void * D.5663;
  void * result;

  D.5659 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5659 != 0) goto <D.5660>; else goto <D.5661>;
  <D.5660>:
  GC_lock ();
  <D.5661>:
  GC_lock_holder.80 = pthread_self ();
  GC_lock_holder = GC_lock_holder.80;
  result = fn (client_data);
  GC_lock_holder = 18446744073709551615;
  pthread_mutex_unlock (&GC_allocate_ml);
  D.5663 = result;
  return D.5663;
}


GC_print_finalization_stats ()
{
  long unsigned int D.5665;
  long int D.5666;
  long unsigned int D.5667;
  long int D.5668;
  long unsigned int GC_fo_entries.81;
  long int GC_fo_entries.82;
  long int ready.83;
  struct finalizable_object * fo;
  size_t ready;

  fo = GC_finalize_now;
  ready = 0;
  D.5665 = GC_ll_hashtbl.entries;
  D.5666 = (long int) D.5665;
  D.5667 = GC_dl_hashtbl.entries;
  D.5668 = (long int) D.5667;
  GC_fo_entries.81 = GC_fo_entries;
  GC_fo_entries.82 = (long int) GC_fo_entries.81;
  GC_printf ("%lu finalization table entries; %lu/%lu short/long disappearing links alive\n", GC_fo_entries.82, D.5668, D.5666, 0, 0, 0);
  goto <D.5159>;
  <D.5158>:
  ready = ready + 1;
  fo = fo->prolog.next;
  <D.5159>:
  if (fo != 0B) goto <D.5158>; else goto <D.5160>;
  <D.5160>:
  ready.83 = (long int) ready;
  GC_printf ("%lu objects are eligible for immediate finalization\n", ready.83, 0, 0, 0, 0, 0);
}


