Fix emulator build error
[platform/framework/web/chromium-efl.git] / base / profiler / stack_buffer.cc
1 // Copyright 2019 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/profiler/stack_buffer.h"
6
7 #include "base/bits.h"
8 #if BUILDFLAG(IS_CHROMEOS)
9 #include <sys/mman.h>
10
11 #include <ostream>
12
13 #include "base/check.h"
14 #include "base/check_op.h"
15 #include "base/memory/page_size.h"
16 #endif  // #if BUILDFLAG(IS_CHROMEOS)
17
18 namespace base {
19
20 constexpr size_t StackBuffer::kPlatformStackAlignment;
21
22 #if BUILDFLAG(IS_CHROMEOS)
23
24 void StackBuffer::MarkUpperBufferContentsAsUnneeded(size_t retained_bytes) {
25   // Round up to the next multiple of the page size. madvise needs the
26   // starting address to be page aligned. Since buffer_.get() is
27   // already page aligned, we just need to round up the retained bytes.
28   size_t actual_retained_bytes = bits::AlignUp(retained_bytes, GetPageSize());
29
30   // Avoid passing a negative discard_size to madvise(). Doing so would randomly
31   // discard large amounts of memory causing weird crashes.
32   CHECK_LE(actual_retained_bytes, size_);
33
34   uint8_t* start_of_discard =
35       reinterpret_cast<uint8_t*>(buffer_.get()) + actual_retained_bytes;
36   size_t discard_size = size_ - actual_retained_bytes;
37   int result = madvise(start_of_discard, discard_size, MADV_DONTNEED);
38
39   DPCHECK(result == 0) << "madvise failed: ";
40 }
41
42 #endif  // #if BUILDFLAG(IS_CHROMEOS)
43
44 StackBuffer::StackBuffer(size_t buffer_size)
45 #if BUILDFLAG(IS_CHROMEOS)
46     // On ChromeOS, we have 8MB of stack space per thread; however, we normally
47     // only use a small fraction of that. To avoid blowing our memory budget,
48     // we use madvise(MADV_DONTNEED) to let the kernel discard the memory in the
49     // 8MB buffer except when we are actively using it. For madvise() to work,
50     // we need |buffer_| to be aligned to a page boundary.
51     //
52     // We also need the |size_| to be a multiple of the page size so that we
53     // don't pass partial pages to madvise(). This isn't documented but the
54     // program will consistently crash otherwise.
55     : size_(bits::AlignUp(buffer_size, GetPageSize())),
56       buffer_(static_cast<uintptr_t*>(AlignedAlloc(size_, GetPageSize()))) {
57   // Our (very large) buffer may already have data written to it & thus have
58   // backing pages. Tell the kernel we don't need the current contents.
59   MarkUpperBufferContentsAsUnneeded(0);
60 }
61 #else   // #if BUILDFLAG(IS_CHROMEOS)
62     : size_(buffer_size),
63       buffer_(static_cast<uintptr_t*>(
64           AlignedAlloc(size_, kPlatformStackAlignment))) {
65   static_assert(bits::IsPowerOfTwo(kPlatformStackAlignment));
66 }
67 #endif  // !#if BUILDFLAG(IS_CHROMEOS)
68
69 StackBuffer::~StackBuffer() = default;
70
71 }  // namespace base