summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/xray/tests/unit/function_call_trie_test.cc
diff options
context:
space:
mode:
authorDean Michael Berris <dberris@google.com>2018-07-10 08:25:44 +0000
committerDean Michael Berris <dberris@google.com>2018-07-10 08:25:44 +0000
commit0dd4f9f22fdba48cd30d4546f67c9ac8de3f1372 (patch)
tree4a2172684cda45414f3f90e510def847e7ad9412 /compiler-rt/lib/xray/tests/unit/function_call_trie_test.cc
parentd1bf9ef0c7926a64a202865a6b879190c9b4cf9c (diff)
downloadbcm5719-llvm-0dd4f9f22fdba48cd30d4546f67c9ac8de3f1372.tar.gz
bcm5719-llvm-0dd4f9f22fdba48cd30d4546f67c9ac8de3f1372.zip
[XRay][compiler-rt] xray::Array Freelist and Iterator Updates
Summary: We found a bug while working on a benchmark for the profiling mode which manifests as a segmentation fault in the profiling handler's implementation. This change adds unit tests which replicate the issues in isolation. We've tracked this down as a bug in the implementation of the Freelist in the `xray::Array` type. This happens when we trim the array by a number of elements, where we've been incorrectly assigning pointers for the links in the freelist of chunk nodes. We've taken the chance to add more debug-only assertions to the code path and allow us to verify these assumptions in debug builds. In the process, we also took the opportunity to use iterators to implement both `front()` and `back()` which exposes a bug in the iterator decrement operation. In particular, when we decrement past a chunk size boundary, we end up moving too far back and reaching the `SentinelChunk` prematurely. This change unblocks us to allow for contributing the non-crashing version of the benchmarks in the test-suite as well. Reviewers: kpw Subscribers: mgorny, llvm-commits Differential Revision: https://reviews.llvm.org/D48653 llvm-svn: 336644
Diffstat (limited to 'compiler-rt/lib/xray/tests/unit/function_call_trie_test.cc')
-rw-r--r--compiler-rt/lib/xray/tests/unit/function_call_trie_test.cc42
1 files changed, 36 insertions, 6 deletions
diff --git a/compiler-rt/lib/xray/tests/unit/function_call_trie_test.cc b/compiler-rt/lib/xray/tests/unit/function_call_trie_test.cc
index d4a79d9028c..6ad51aa148c 100644
--- a/compiler-rt/lib/xray/tests/unit/function_call_trie_test.cc
+++ b/compiler-rt/lib/xray/tests/unit/function_call_trie_test.cc
@@ -18,12 +18,6 @@ namespace __xray {
namespace {
-TEST(FunctionCallTrieTest, Construction) {
- // We want to make sure that we can create one of these without the set of
- // allocators we need. This will by default use the global allocators.
- FunctionCallTrie Trie;
-}
-
TEST(FunctionCallTrieTest, ConstructWithTLSAllocators) {
// FIXME: Support passing in configuration for allocators in the allocator
// constructors.
@@ -61,6 +55,17 @@ TEST(FunctionCallTrieTest, MissingFunctionEntry) {
ASSERT_TRUE(R.empty());
}
+TEST(FunctionCallTrieTest, NoMatchingEntersForExit) {
+ auto A = FunctionCallTrie::InitAllocators();
+ FunctionCallTrie Trie(A);
+ Trie.enterFunction(2, 1);
+ Trie.enterFunction(3, 3);
+ Trie.exitFunction(1, 5);
+ const auto &R = Trie.getRoots();
+
+ ASSERT_TRUE(R.empty());
+}
+
TEST(FunctionCallTrieTest, MissingFunctionExit) {
auto A = FunctionCallTrie::InitAllocators();
FunctionCallTrie Trie(A);
@@ -153,6 +158,31 @@ TEST(FunctionCallTrieTest, MissingIntermediaryExit) {
EXPECT_EQ(F1.CumulativeLocalTime, 100);
}
+TEST(FunctionCallTrieTest, DeepCallStack) {
+ // Simulate a relatively deep call stack (32 levels) and ensure that we can
+ // properly pop all the way up the stack.
+ profilingFlags()->setDefaults();
+ auto A = FunctionCallTrie::InitAllocators();
+ FunctionCallTrie Trie(A);
+ for (int i = 0; i < 32; ++i)
+ Trie.enterFunction(i + 1, i);
+ Trie.exitFunction(1, 33);
+
+ // Here, validate that we have a 32-level deep function call path from the
+ // root (1) down to the leaf (33).
+ const auto &R = Trie.getRoots();
+ ASSERT_EQ(R.size(), 1u);
+ auto F = R[0];
+ for (int i = 0; i < 32; ++i) {
+ EXPECT_EQ(F->FId, i + 1);
+ EXPECT_EQ(F->CallCount, 1);
+ if (F->Callees.empty() && i != 31)
+ FAIL() << "Empty callees for FId " << F->FId;
+ if (i != 31)
+ F = F->Callees[0].NodePtr;
+ }
+}
+
// TODO: Test that we can handle cross-CPU migrations, where TSCs are not
// guaranteed to be synchronised.
TEST(FunctionCallTrieTest, DeepCopy) {
OpenPOWER on IntegriCloud