* @class memStack * @brief Thread-local logical call stack used to synthesize frame identifiers. * * The stack is explicitly manipulated via fastgrind RAII objects (FAST_GRIND macro) * rather than relying on platform unwinding. Each push/pop updates a rolling id * so that the same textual sequence of function names maps to a deterministic * frameId across time slices. */
| 1143 | * frameId across time slices. |
| 1144 | */ |
| 1145 | class memStack |
| 1146 | { |
| 1147 | public: |
| 1148 | MEM_NO_INSTRUMENT memStack() |
| 1149 | { |
| 1150 | _offset = 0; |
| 1151 | _stackId = 0; |
| 1152 | } |
| 1153 | |
| 1154 | MEM_NO_INSTRUMENT ~memStack() |
| 1155 | { |
| 1156 | } |
| 1157 | |
| 1158 | /** @brief Push function name onto stack and update frame id hash. */ |
| 1159 | MEM_NO_INSTRUMENT void push(const char *v) |
| 1160 | { |
| 1161 | if (_offset >= __MEM_MAX_STACK_DEPTH) { |
| 1162 | static bool warned_stack = false; |
| 1163 | if (!warned_stack) { |
| 1164 | fprintf(stderr, "[FASTGRIND] WARNING: Call stack depth exceeded %d\n", __MEM_MAX_STACK_DEPTH); |
| 1165 | warned_stack = true; |
| 1166 | } |
| 1167 | |
| 1168 | return; |
| 1169 | } |
| 1170 | |
| 1171 | assert(_offset < __MEM_MAX_STACK_DEPTH); |
| 1172 | |
| 1173 | _stack[_offset++] = v; |
| 1174 | _stackId += size_t(v); |
| 1175 | } |
| 1176 | |
| 1177 | /** @brief Pop top of stack (must not be empty). */ |
| 1178 | MEM_NO_INSTRUMENT const char *pop() |
| 1179 | { |
| 1180 | if (_offset == 0) |
| 1181 | return nullptr; |
| 1182 | |
| 1183 | auto v = _stack[--_offset]; |
| 1184 | _stackId -= size_t(v); |
| 1185 | return v; |
| 1186 | } |
| 1187 | |
| 1188 | /** @return Current stack depth. */ |
| 1189 | MEM_NO_INSTRUMENT unsigned depth() const |
| 1190 | { |
| 1191 | return _offset; |
| 1192 | } |
| 1193 | |
| 1194 | /** @return Top function name (undefined if empty). */ |
| 1195 | MEM_NO_INSTRUMENT const char *top() const |
| 1196 | { |
| 1197 | return _stack[_offset - 1]; |
| 1198 | } |
| 1199 | |
| 1200 | /** @return Synthetic frame id composed from top symbol pointer plus cumulative hash. */ |
| 1201 | MEM_NO_INSTRUMENT size_t frameId() const |
| 1202 | { |
nothing calls this directly
no outgoing calls
no test coverage detected