1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <malloc.h>
18 #include <stdint.h>
19 #include <stdio.h>
20 #include <unistd.h>
21
22 #include <memory_trace/MemoryTrace.h>
23
24 #include "Alloc.h"
25 #include "Pointers.h"
26 #include "Utils.h"
27
AllocDoesFree(const memory_trace::Entry & entry)28 bool AllocDoesFree(const memory_trace::Entry& entry) {
29 switch (entry.type) {
30 case memory_trace::MALLOC:
31 case memory_trace::CALLOC:
32 case memory_trace::MEMALIGN:
33 case memory_trace::THREAD_DONE:
34 case memory_trace::UNKNOWN:
35 return false;
36
37 case memory_trace::FREE:
38 return entry.ptr != 0;
39
40 case memory_trace::REALLOC:
41 return entry.u.old_ptr != 0;
42 }
43 }
44
MallocExecute(const memory_trace::Entry & entry,Pointers * pointers)45 static uint64_t MallocExecute(const memory_trace::Entry& entry, Pointers* pointers) {
46 int pagesize = getpagesize();
47 uint64_t time_nsecs = Nanotime();
48 void* memory = malloc(entry.size);
49 MakeAllocationResident(memory, entry.size, entry.present_bytes, pagesize);
50 time_nsecs = Nanotime() - time_nsecs;
51
52 pointers->Add(entry.ptr, memory);
53
54 return time_nsecs;
55 }
56
CallocExecute(const memory_trace::Entry & entry,Pointers * pointers)57 static uint64_t CallocExecute(const memory_trace::Entry& entry, Pointers* pointers) {
58 int pagesize = getpagesize();
59 uint64_t time_nsecs = Nanotime();
60 void* memory = calloc(entry.u.n_elements, entry.size);
61 MakeAllocationResident(memory, entry.u.n_elements * entry.size, entry.present_bytes, pagesize);
62 time_nsecs = Nanotime() - time_nsecs;
63
64 pointers->Add(entry.ptr, memory);
65
66 return time_nsecs;
67 }
68
ReallocExecute(const memory_trace::Entry & entry,Pointers * pointers)69 static uint64_t ReallocExecute(const memory_trace::Entry& entry, Pointers* pointers) {
70 void* old_memory = nullptr;
71 if (entry.u.old_ptr != 0) {
72 old_memory = pointers->Remove(entry.u.old_ptr);
73 }
74
75 int pagesize = getpagesize();
76 uint64_t time_nsecs = Nanotime();
77 void* memory = realloc(old_memory, entry.size);
78 MakeAllocationResident(memory, entry.size, entry.present_bytes, pagesize);
79 time_nsecs = Nanotime() - time_nsecs;
80
81 pointers->Add(entry.ptr, memory);
82
83 return time_nsecs;
84 }
85
MemalignExecute(const memory_trace::Entry & entry,Pointers * pointers)86 static uint64_t MemalignExecute(const memory_trace::Entry& entry, Pointers* pointers) {
87 int pagesize = getpagesize();
88 uint64_t time_nsecs = Nanotime();
89 void* memory = memalign(entry.u.align, entry.size);
90 MakeAllocationResident(memory, entry.size, entry.present_bytes, pagesize);
91 time_nsecs = Nanotime() - time_nsecs;
92
93 pointers->Add(entry.ptr, memory);
94
95 return time_nsecs;
96 }
97
FreeExecute(const memory_trace::Entry & entry,Pointers * pointers)98 static uint64_t FreeExecute(const memory_trace::Entry& entry, Pointers* pointers) {
99 if (entry.ptr == 0) {
100 return 0;
101 }
102
103 void* memory = pointers->Remove(entry.ptr);
104 uint64_t time_nsecs = Nanotime();
105 free(memory);
106 return Nanotime() - time_nsecs;
107 }
108
AllocExecute(const memory_trace::Entry & entry,Pointers * pointers)109 uint64_t AllocExecute(const memory_trace::Entry& entry, Pointers* pointers) {
110 switch (entry.type) {
111 case memory_trace::MALLOC:
112 return MallocExecute(entry, pointers);
113 case memory_trace::CALLOC:
114 return CallocExecute(entry, pointers);
115 case memory_trace::REALLOC:
116 return ReallocExecute(entry, pointers);
117 case memory_trace::MEMALIGN:
118 return MemalignExecute(entry, pointers);
119 case memory_trace::FREE:
120 return FreeExecute(entry, pointers);
121 default:
122 return 0;
123 }
124 }
125