Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | /* Copyright (C) 2012 Matthew Fluet. |
2 | * Copyright (C) 1999-2006 Henry Cejtin, Matthew Fluet, Suresh | |
3 | * Jagannathan, and Stephen Weeks. | |
4 | * Copyright (C) 1997-2000 NEC Research Institute. | |
5 | * | |
6 | * MLton is released under a BSD-style license. | |
7 | * See the file MLton-LICENSE for details. | |
8 | */ | |
9 | ||
10 | #if (defined (MLTON_GC_INTERNAL_TYPES)) | |
11 | ||
12 | typedef enum { | |
13 | PROFILE_ALLOC, | |
14 | PROFILE_COUNT, | |
15 | PROFILE_NONE, | |
16 | PROFILE_TIME_FIELD, | |
17 | PROFILE_TIME_LABEL | |
18 | } GC_profileKind; | |
19 | ||
20 | /* If profileStack, then there is one struct GC_profileStack for each | |
21 | * function. | |
22 | */ | |
23 | typedef struct GC_profileStack { | |
24 | /* ticks counts ticks while the function was on the stack. */ | |
25 | uintmax_t ticks; | |
26 | /* ticksGC counts ticks in GC while the function was on the stack. */ | |
27 | uintmax_t ticksGC; | |
28 | /* lastTotal is the value of total when the oldest occurrence of f | |
29 | * on the stack was pushed, i.e., the most recent time that | |
30 | * numTimesOnStack changed from 0 to 1. lastTotal is used to | |
31 | * compute the amount to attribute to f when the oldest occurrence | |
32 | * is finally popped. | |
33 | */ | |
34 | uintmax_t lastTotal; | |
35 | /* lastTotalGC is like lastTotal, but for GC ticks. */ | |
36 | uintmax_t lastTotalGC; | |
37 | /* numOccurrences is the number of times this function is on the | |
38 | * stack. | |
39 | */ | |
40 | uintmax_t numOccurrences; | |
41 | } *GC_profileStack; | |
42 | ||
43 | typedef uint32_t GC_profileMasterIndex; | |
44 | ||
45 | /* GC_profileData is used for both time and allocation profiling. | |
46 | * In the comments below, "ticks" mean clock ticks with time profiling and | |
47 | * bytes allocated with allocation profiling. | |
48 | * | |
49 | * All of the arrays in GC_profileData are of length sourcesLength + sourceNamesLength. | |
50 | * The first sourceLength entries are for handling the duplicate copies of | |
51 | * functions, and the next sourceNamesLength entries are for the master versions. | |
52 | */ | |
53 | typedef struct GC_profileData { | |
54 | /* countTop is an array that counts for each function the number of | |
55 | * ticks that occurred while the function was on top of the stack. | |
56 | */ | |
57 | uintmax_t *countTop; | |
58 | /* stack is an array that gives stack info for each function. | |
59 | * It is only used if profileStack. | |
60 | */ | |
61 | struct GC_profileStack *stack; | |
62 | /* The total number of mutator ticks. */ | |
63 | uintmax_t total; | |
64 | /* The total number of GC ticks. */ | |
65 | uintmax_t totalGC; | |
66 | } *GC_profileData; | |
67 | ||
68 | struct GC_profiling { | |
69 | GC_profileData data; | |
70 | bool isOn; | |
71 | GC_profileKind kind; | |
72 | bool stack; | |
73 | }; | |
74 | ||
75 | #else | |
76 | ||
77 | struct GC_profileData; | |
78 | typedef struct GC_profileData *GC_profileData; | |
79 | ||
80 | #endif /* (defined (MLTON_GC_INTERNAL_TYPES)) */ | |
81 | ||
82 | #if (defined (MLTON_GC_INTERNAL_FUNCS)) | |
83 | ||
84 | static inline GC_profileMasterIndex sourceIndexToProfileMasterIndex (GC_state s, GC_sourceIndex i); | |
85 | static inline GC_sourceNameIndex profileMasterIndexToSourceNameIndex (GC_state s, GC_profileMasterIndex i); | |
86 | static inline GC_profileStack getProfileStackInfo (GC_state s, GC_profileMasterIndex i); | |
87 | ||
88 | static inline void addToStackForProfiling (GC_state s, GC_profileMasterIndex i); | |
89 | static inline void enterSourceForProfiling (GC_state s, GC_profileMasterIndex i); | |
90 | static inline void enterForProfiling (GC_state s, GC_sourceSeqIndex sourceSeqIndex); | |
91 | static inline void enterFrameForProfiling (GC_state s, GC_frameIndex i); | |
92 | ||
93 | static inline void removeFromStackForProfiling (GC_state s, GC_profileMasterIndex i); | |
94 | static inline void leaveSourceForProfiling (GC_state s, GC_profileMasterIndex i); | |
95 | static inline void leaveForProfiling (GC_state s, GC_sourceSeqIndex sourceSeqIndex); | |
96 | ||
97 | static inline void incForProfiling (GC_state s, size_t amount, GC_sourceSeqIndex sourceSeqIndex); | |
98 | ||
99 | static inline char* profileIndexSourceName (GC_state s, GC_sourceIndex i); | |
100 | ||
101 | static void writeProfileCount (GC_state s, FILE *f, GC_profileData p, GC_profileMasterIndex i); | |
102 | ||
103 | PRIVATE GC_profileData profileMalloc (GC_state s); | |
104 | PRIVATE void profileWrite (GC_state s, GC_profileData p, const char* fileName); | |
105 | PRIVATE void profileFree (GC_state s, GC_profileData p); | |
106 | ||
107 | static void setProfTimer (suseconds_t usec); | |
108 | static void initProfilingTime (GC_state s); | |
109 | static void atexitForProfiling (void); | |
110 | static void initProfiling (GC_state s); | |
111 | ||
112 | #endif /* (defined (MLTON_GC_INTERNAL_FUNCS)) */ | |
113 | ||
114 | #if (defined (MLTON_GC_INTERNAL_BASIS)) | |
115 | ||
116 | PRIVATE void GC_profileEnter (GC_state s); | |
117 | PRIVATE void GC_profileLeave (GC_state s); | |
118 | PRIVATE void GC_profileInc (GC_state s, size_t amount); | |
119 | PRIVATE void GC_profileAllocInc (GC_state s, size_t amount); | |
120 | ||
121 | PRIVATE GC_profileData GC_getProfileCurrent (GC_state s); | |
122 | PRIVATE void GC_setProfileCurrent (GC_state s, GC_profileData p); | |
123 | ||
124 | PRIVATE GC_profileData GC_profileMalloc (GC_state s); | |
125 | PRIVATE void GC_profileWrite (GC_state s, GC_profileData p, NullString8_t fileName); | |
126 | PRIVATE void GC_profileFree (GC_state s, GC_profileData p); | |
127 | ||
128 | PRIVATE void GC_profileDone (GC_state s); | |
129 | ||
130 | #endif /* (defined (MLTON_GC_INTERNAL_BASIS)) */ | |
131 | ||
132 | PRIVATE void GC_handleSigProf (code_pointer pc); | |
133 |