line_profier.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #include "pocketpy/interpreter/line_profiler.h"
  2. #include <assert.h>
  3. void LineProfiler__ctor(LineProfiler* self) {
  4. c11_smallmap_p2i__ctor(&self->records);
  5. self->prev_loc.src = NULL;
  6. self->prev_time = 0;
  7. self->enabled = false;
  8. }
  9. void LineProfiler__dtor(LineProfiler* self) {
  10. for(int i = 0; i < self->records.length; i++) {
  11. LineRecord* lines = c11__getitem(LineRecord*, &self->records, i);
  12. PK_FREE(lines);
  13. }
  14. c11_smallmap_p2i__dtor(&self->records);
  15. }
  16. LineRecord* LineProfiler__get_record(LineProfiler* self, SourceLocation loc) {
  17. LineRecord* lines = (LineRecord*)c11_smallmap_p2i__get(&self->records, loc.src, 0);
  18. if(lines == NULL) {
  19. int max_lineno = loc.src->line_starts.length;
  20. lines = PK_MALLOC(sizeof(LineRecord) * (max_lineno + 1));
  21. memset(lines, 0, sizeof(LineRecord) * (max_lineno + 1));
  22. c11_smallmap_p2i__set(&self->records, loc.src, (py_i64)lines);
  23. }
  24. return &lines[loc.lineno];
  25. }
  26. void LineProfiler__begin(LineProfiler* self) {
  27. assert(!self->enabled);
  28. self->prev_loc.src = NULL;
  29. self->prev_time = 0;
  30. self->enabled = true;
  31. }
  32. void LineProfiler__tracefunc_line(LineProfiler* self, py_Frame* frame) {
  33. assert(self->enabled);
  34. clock_t now = clock();
  35. if(self->prev_loc.src != NULL) {
  36. LineRecord* line = LineProfiler__get_record(self, self->prev_loc);
  37. line->hits++;
  38. line->time += now - self->prev_time;
  39. }
  40. self->prev_loc = Frame__source_location(frame);
  41. self->prev_time = now;
  42. }
  43. void LineProfiler__end(LineProfiler* self) {
  44. assert(self->enabled);
  45. if(self->prev_loc.src != NULL) {
  46. LineRecord* line = LineProfiler__get_record(self, self->prev_loc);
  47. line->hits++;
  48. line->time += clock() - self->prev_time;
  49. }
  50. self->enabled = false;
  51. }
  52. void LineProfiler__reset(LineProfiler* self) {
  53. LineProfiler__dtor(self);
  54. LineProfiler__ctor(self);
  55. }