1245614Sandrew//===-- sanitizer_stackdepot.h ----------------------------------*- C++ -*-===//
2245614Sandrew//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6245614Sandrew//
7245614Sandrew//===----------------------------------------------------------------------===//
8245614Sandrew//
9245614Sandrew// This file is shared between AddressSanitizer and ThreadSanitizer
10245614Sandrew// run-time libraries.
11245614Sandrew//===----------------------------------------------------------------------===//
12296417Sdim
13245614Sandrew#ifndef SANITIZER_STACKDEPOT_H
14245614Sandrew#define SANITIZER_STACKDEPOT_H
15245614Sandrew
16274201Sdim#include "sanitizer_common.h"
17251034Sed#include "sanitizer_internal_defs.h"
18276789Sdim#include "sanitizer_stacktrace.h"
19245614Sandrew
20245614Sandrewnamespace __sanitizer {
21245614Sandrew
22245614Sandrew// StackDepot efficiently stores huge amounts of stack traces.
23276789Sdimstruct StackDepotNode;
24276789Sdimstruct StackDepotHandle {
25276789Sdim  StackDepotNode *node_;
26296417Sdim  StackDepotHandle() : node_(nullptr) {}
27276789Sdim  explicit StackDepotHandle(StackDepotNode *node) : node_(node) {}
28276789Sdim  bool valid() { return node_; }
29276789Sdim  u32 id();
30276789Sdim  int use_count();
31276789Sdim  void inc_use_count_unsafe();
32276789Sdim};
33245614Sandrew
34344779Sdimconst int kStackDepotMaxUseCount = 1U << (SANITIZER_ANDROID ? 16 : 20);
35245614Sandrew
36245614SandrewStackDepotStats *StackDepotGetStats();
37276789Sdimu32 StackDepotPut(StackTrace stack);
38276789SdimStackDepotHandle StackDepotPut_WithHandle(StackTrace stack);
39276789Sdim// Retrieves a stored stack trace by the id.
40276789SdimStackTrace StackDepotGet(u32 id);
41245614Sandrew
42276789Sdimvoid StackDepotLockAll();
43276789Sdimvoid StackDepotUnlockAll();
44274201Sdim
45274201Sdim// Instantiating this class creates a snapshot of StackDepot which can be
46274201Sdim// efficiently queried with StackDepotGet(). You can use it concurrently with
47274201Sdim// StackDepot, but the snapshot is only guaranteed to contain those stack traces
48274201Sdim// which were stored before it was instantiated.
49274201Sdimclass StackDepotReverseMap {
50274201Sdim public:
51274201Sdim  StackDepotReverseMap();
52276789Sdim  StackTrace Get(u32 id);
53274201Sdim
54274201Sdim private:
55274201Sdim  struct IdDescPair {
56274201Sdim    u32 id;
57276789Sdim    StackDepotNode *desc;
58274201Sdim
59274201Sdim    static bool IdComparator(const IdDescPair &a, const IdDescPair &b);
60274201Sdim  };
61274201Sdim
62274201Sdim  InternalMmapVector<IdDescPair> map_;
63274201Sdim
64274201Sdim  // Disallow evil constructors.
65274201Sdim  StackDepotReverseMap(const StackDepotReverseMap&);
66274201Sdim  void operator=(const StackDepotReverseMap&);
67274201Sdim};
68276789Sdim
69296417Sdim} // namespace __sanitizer
70245614Sandrew
71296417Sdim#endif // SANITIZER_STACKDEPOT_H
72