tasks.ml 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. open Type
  2. open CompilationCache
  3. class gc_task (max_working_memory : float) (heap_size : float) = object(self)
  4. inherit server_task ["gc"] 100
  5. method private execute =
  6. let t0 = Timer.get_time() in
  7. let stats = Gc.stat() in
  8. let live_words = float_of_int stats.live_words in
  9. (* Maximum heap size needed for the last X compilations = sum of what's live + max working memory. *)
  10. let needed_max = live_words +. max_working_memory in
  11. (* Additional heap percentage needed = what's live / max of what was live. *)
  12. let percent_needed = (1. -. live_words /. needed_max) in
  13. (* Effective cache size percentage = what's live / heap size. *)
  14. let percent_used = live_words /. heap_size in
  15. (* Set allowed space_overhead to the maximum of what we needed during the last X compilations. *)
  16. let new_space_overhead = int_of_float ((percent_needed +. 0.05) *. 100.) in
  17. let old_gc = Gc.get() in
  18. Gc.set { old_gc with Gc.space_overhead = new_space_overhead; };
  19. (* Compact if less than 80% of our heap words consist of the cache and there's less than 50% overhead. *)
  20. let do_compact = percent_used < 0.8 && percent_needed < 0.5 in
  21. begin if do_compact then
  22. Gc.compact()
  23. else
  24. Gc.full_major();
  25. end;
  26. Gc.set old_gc;
  27. ServerMessage.gc_stats (Timer.get_time() -. t0) stats do_compact new_space_overhead
  28. end
  29. class class_maintenance_task (cs : CompilationCache.t) (c : tclass) = object(self)
  30. inherit server_task ["module maintenance"] 70
  31. method private execute =
  32. let rec field cf =
  33. (* Unset cf_expr. This holds the optimized version for generators, which we don't need to persist. If
  34. we compile again, the semi-optimized expression will be restored by calling cl_restore(). *)
  35. cf.cf_expr <- None;
  36. List.iter field cf.cf_overloads
  37. in
  38. (* What we're doing here at the moment is free, so we can just do it in one task. If this ever gets more expensive,
  39. we should spawn a task per-field. *)
  40. List.iter field c.cl_ordered_fields;
  41. List.iter field c.cl_ordered_statics;
  42. Option.may field c.cl_constructor;
  43. end
  44. class module_maintenance_task (cs : CompilationCache.t) (m : module_def) = object(self)
  45. inherit server_task ["module maintenance"] 80
  46. method private execute =
  47. List.iter (fun mt -> match mt with
  48. | TClassDecl c ->
  49. cs#add_task (new class_maintenance_task cs c)
  50. | _ ->
  51. ()
  52. ) m.m_types
  53. end
  54. class server_exploration_task (cs : CompilationCache.t) = object(self)
  55. inherit server_task ["server explore"] 90
  56. method private execute =
  57. cs#iter_modules (fun m -> cs#add_task (new module_maintenance_task cs m))
  58. end