1413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom/*
2413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom * Copyright (C) 2013 The Android Open Source Project
3413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom *
4413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License");
5413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom * you may not use this file except in compliance with the License.
6413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom * You may obtain a copy of the License at
7413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom *
8413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom *      http://www.apache.org/licenses/LICENSE-2.0
9413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom *
10413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom * Unless required by applicable law or agreed to in writing, software
11413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
12413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom * See the License for the specific language governing permissions and
14413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom * limitations under the License.
15413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom */
16413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom
17413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom#include "allocator.h"
18413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom
19413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom#include <inttypes.h>
20413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom#include <stdlib.h>
21413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom
22bad0267eaab9d6a522d05469ff90501deefdb88bMathieu Chartier#include "atomic.h"
23413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom#include "base/logging.h"
24bad0267eaab9d6a522d05469ff90501deefdb88bMathieu Chartier#include "thread-inl.h"
25413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom
26413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstromnamespace art {
27413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom
28e77493c7217efdd1a0ecef521a6845a13da0305bIan Rogersclass MallocAllocator FINAL : public Allocator {
29413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom public:
30413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom  explicit MallocAllocator() {}
31413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom  ~MallocAllocator() {}
32413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom
336a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  void* Alloc(size_t size) {
34413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom    return calloc(sizeof(uint8_t), size);
35413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom  }
36413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom
376a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  void Free(void* p) {
38413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom    free(p);
39413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom  }
40413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom
41413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom private:
42413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom  DISALLOW_COPY_AND_ASSIGN(MallocAllocator);
43413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom};
44413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom
45413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian CarlstromMallocAllocator g_malloc_allocator;
46413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom
47e77493c7217efdd1a0ecef521a6845a13da0305bIan Rogersclass NoopAllocator FINAL : public Allocator {
48413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom public:
49413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom  explicit NoopAllocator() {}
50413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom  ~NoopAllocator() {}
51413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom
524b8f1ecd3aa5a29ec1463ff88fee9db365f257dcRoland Levillain  void* Alloc(size_t size ATTRIBUTE_UNUSED) {
53413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom    LOG(FATAL) << "NoopAllocator::Alloc should not be called";
546a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers    UNREACHABLE();
55413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom  }
56413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom
574b8f1ecd3aa5a29ec1463ff88fee9db365f257dcRoland Levillain  void Free(void* p ATTRIBUTE_UNUSED) {
58413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom    // Noop.
59413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom  }
60413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom
61413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom private:
62413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom  DISALLOW_COPY_AND_ASSIGN(NoopAllocator);
63413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom};
64413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom
65413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian CarlstromNoopAllocator g_noop_allocator;
66413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom
67413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian CarlstromAllocator* Allocator::GetMallocAllocator() {
68413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom  return &g_malloc_allocator;
69413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom}
70413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom
71413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian CarlstromAllocator* Allocator::GetNoopAllocator() {
72413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom  return &g_noop_allocator;
73413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom}
74413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom
757e70b002c4552347ed1af8c002a0e13f08864f20Ian Rogersnamespace TrackedAllocators {
767e70b002c4552347ed1af8c002a0e13f08864f20Ian Rogers
776e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier// These globals are safe since they don't have any non-trivial destructors.
787e70b002c4552347ed1af8c002a0e13f08864f20Ian RogersAtomic<size_t> g_bytes_used[kAllocatorTagCount];
797e70b002c4552347ed1af8c002a0e13f08864f20Ian Rogersvolatile size_t g_max_bytes_used[kAllocatorTagCount];
807e70b002c4552347ed1af8c002a0e13f08864f20Ian RogersAtomic<uint64_t> g_total_bytes_used[kAllocatorTagCount];
817e70b002c4552347ed1af8c002a0e13f08864f20Ian Rogers
827e70b002c4552347ed1af8c002a0e13f08864f20Ian Rogersvoid Dump(std::ostream& os) {
83bad0267eaab9d6a522d05469ff90501deefdb88bMathieu Chartier  if (kEnableTrackingAllocator) {
84bad0267eaab9d6a522d05469ff90501deefdb88bMathieu Chartier    os << "Dumping native memory usage\n";
85bad0267eaab9d6a522d05469ff90501deefdb88bMathieu Chartier    for (size_t i = 0; i < kAllocatorTagCount; ++i) {
867e70b002c4552347ed1af8c002a0e13f08864f20Ian Rogers      uint64_t bytes_used = g_bytes_used[i].LoadRelaxed();
877e70b002c4552347ed1af8c002a0e13f08864f20Ian Rogers      uint64_t max_bytes_used = g_max_bytes_used[i];
887e70b002c4552347ed1af8c002a0e13f08864f20Ian Rogers      uint64_t total_bytes_used = g_total_bytes_used[i].LoadRelaxed();
89bad0267eaab9d6a522d05469ff90501deefdb88bMathieu Chartier      if (total_bytes_used != 0) {
90bad0267eaab9d6a522d05469ff90501deefdb88bMathieu Chartier        os << static_cast<AllocatorTag>(i) << " active=" << bytes_used << " max="
91bad0267eaab9d6a522d05469ff90501deefdb88bMathieu Chartier           << max_bytes_used << " total=" << total_bytes_used << "\n";
92bad0267eaab9d6a522d05469ff90501deefdb88bMathieu Chartier      }
93bad0267eaab9d6a522d05469ff90501deefdb88bMathieu Chartier    }
94bad0267eaab9d6a522d05469ff90501deefdb88bMathieu Chartier  }
95bad0267eaab9d6a522d05469ff90501deefdb88bMathieu Chartier}
96413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom
977e70b002c4552347ed1af8c002a0e13f08864f20Ian Rogers}  // namespace TrackedAllocators
987e70b002c4552347ed1af8c002a0e13f08864f20Ian Rogers
99413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian Carlstrom}  // namespace art
100