blob: 5fd00345ae07d403aa1ca201733d7680df760275 [file] [log] [blame]
Andrew Topa953d4e2016-11-22 22:38:45 -08001/*
2 * Copyright 2016 Google Inc. All Rights Reserved.
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#ifndef NB_MEMORY_SCOPE_H_
18#define NB_MEMORY_SCOPE_H_
19
Andrew Topa953d4e2016-11-22 22:38:45 -080020///////////////////////////////////////////////////////////////////////////////
21// Macros to define the memory scope objects. These are objects that are used
22// to annotate sections of the code base as belonging to a particular memory
23// scope. Note that this is an annotation and does not memory allocation.
24///////////////////////////////////////////////////////////////////////////////
25
26// Macro to track the memory scope inside a function or block of code. The
27// memory scope is in effect until the end of the code block.
28// Example:
29// void Foo() {
30// TRACK_MEMORY_SCOPE("FooMemoryScope");
31// // pops the memory scope at the end.
32// }
33
34#if !defined(__cplusplus)
35// Disallow macro use for non-C++ builds.
36#define TRACK_MEMORY_SCOPE(STR) error_forbidden_in_non_c_plus_plus_code
37#define TRACK_MEMORY_SCOPE_DYNAMIC(STR) error_forbidden_in_non_c_plus_plus_code
38#elif defined(STARBOARD_ALLOWS_MEMORY_TRACKING)
39#define TRACK_MEMORY_SCOPE(STR) TRACK_MEMORY_STATIC_CACHED(STR)
40#define TRACK_MEMORY_SCOPE_DYNAMIC(STR) TRACK_MEMORY_STATIC_NOT_CACHED(STR)
41#else
42// No-op when starboard does not allow memory tracking.
43#define TRACK_MEMORY_SCOPE(STR)
44#define TRACK_MEMORY_SCOPE_DYNAMIC(STR)
45#endif
46
47// Preprocessor needs double expansion in order to __FILE__, __LINE__ and
48// __FUNCTION__ properly.
49#define TRACK_MEMORY_STATIC_CACHED(STR) \
50 TRACK_MEMORY_STATIC_CACHED_IMPL_2(STR, __FILE__, __LINE__, __FUNCTION__)
51
52#define TRACK_MEMORY_STATIC_NOT_CACHED(STR) \
53 TRACK_MEMORY_STATIC_NOT_CACHED_IMPL_2(STR, __FILE__, __LINE__, __FUNCTION__)
54
55// Only enable TRACK_MEMORY_STATIC_CACHED_IMPL_2 if starboard allows memory
56// tracking.
57#define TRACK_MEMORY_STATIC_CACHED_IMPL_2(Str, FileStr, LineNum, FuncStr) \
58 static NbMemoryScopeInfo memory_scope_handle_##LineNum = \
Andrew Topa8b99852016-11-29 21:41:27 -080059 { NULL, Str, FileStr, LineNum, FuncStr, true }; \
Andrew Topa953d4e2016-11-22 22:38:45 -080060 NbPushMemoryScope(&memory_scope_handle_##LineNum); \
David Ghandehari00be30f2017-04-27 21:30:48 -070061 NbPopMemoryScopeOnScopeEnd pop_on_scope_end_##LineNum; \
62 (void)pop_on_scope_end_##LineNum;
Andrew Topa953d4e2016-11-22 22:38:45 -080063
64#define TRACK_MEMORY_STATIC_NOT_CACHED_IMPL_2(Str, FileStr, LineNum, FuncStr) \
65 NbMemoryScopeInfo memory_scope_handle_##LineNum = { \
Andrew Topa8b99852016-11-29 21:41:27 -080066 NULL, Str, FileStr, LineNum, FuncStr, false}; \
Andrew Topa953d4e2016-11-22 22:38:45 -080067 NbPushMemoryScope(&memory_scope_handle_##LineNum); \
David Ghandehari00be30f2017-04-27 21:30:48 -070068 NbPopMemoryScopeOnScopeEnd pop_on_scope_end_##LineNum; \
69 (void)pop_on_scope_end_##LineNum;
Andrew Topa953d4e2016-11-22 22:38:45 -080070
71#ifdef __cplusplus
72extern "C" {
73#endif
74
75struct NbMemoryScopeReporter;
76struct NbMemoryScopeInfo;
77
78// Sets the memory reporter. Returns true on success, false something
79// goes wrong.
80bool NbSetMemoryScopeReporter(NbMemoryScopeReporter* reporter);
81
82// Note that we pass by pointer because the memory scope contains a
83// variable allowing the result to be cached.
84void NbPushMemoryScope(NbMemoryScopeInfo* memory_scope);
85void NbPopMemoryScope();
86
87///////////////////////////////////////////////////////////////////////////////
88// Implementation
89///////////////////////////////////////////////////////////////////////////////
90// Interface for handling memory scopes.
91typedef void (*NbReportPushMemoryScopeCallback)(void* context,
92 NbMemoryScopeInfo* info);
93typedef void (*NbReportPopMemoryScopeCallback)(void* context);
94
95struct NbMemoryScopeReporter {
96 // Callback to report pushing of memory scope.
97 NbReportPushMemoryScopeCallback push_memory_scope_cb;
98
99 // Callback to report poping of the memory scope.
100 NbReportPopMemoryScopeCallback pop_memory_scope_cb;
101
102 // Optional, is passed to the callbacks as first argument.
103 void* context;
104};
105
106// This MemoryScope must remain a POD data type so that it can be statically
107// initialized.
108struct NbMemoryScopeInfo {
109 // cached_handle_ allows a cached result of the the fields represented in
110 // this struct to be generated and the handle be placed into this field.
111 // See also allows_caching_.
Andrew Topa8b99852016-11-29 21:41:27 -0800112 void* cached_handle_;
Andrew Topa953d4e2016-11-22 22:38:45 -0800113
114 // Represents the name of the memory scope. I.E. "Javascript" or "Gfx".
115 const char* memory_scope_name_;
116
117 // Represents the file name that this memory scope was created at.
118 const char* file_name_;
119
120 // Represents the line number that this memory scope was created at.
121 int line_number_;
122
123 // Represents the function name that this memory scope was created at.
124 const char* function_name_;
125
126 // When true, if cached_handle_ is 0 then an object may be created that
127 // represents the fields of this object. The handle that represents this
128 // cached object is then placed in cached_hanlde_.
Andrew Top2ea22382016-12-08 09:47:36 -0800129 bool allows_caching_;
Andrew Topa953d4e2016-11-22 22:38:45 -0800130};
131
132// NbPopMemoryScopeOnScopeEnd is only allowed for C++ builds.
133#ifdef __cplusplus
134// A helper that pops the memory scope at the end of the current code block.
135struct NbPopMemoryScopeOnScopeEnd {
136 ~NbPopMemoryScopeOnScopeEnd() { NbPopMemoryScope(); }
137};
138#endif
139
140
141#ifdef __cplusplus
142} // extern "C"
143#endif
144
145#endif // NB_MEMORY_SCOPE_H_