Import Cobalt 6.14838
Change-Id: I49864fe26f7f6fca3777d185823aa31251e8ae57
diff --git a/src/nb/memory_scope.h b/src/nb/memory_scope.h
new file mode 100644
index 0000000..9c9446b
--- /dev/null
+++ b/src/nb/memory_scope.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NB_MEMORY_SCOPE_H_
+#define NB_MEMORY_SCOPE_H_
+
+#include "starboard/types.h"
+
+///////////////////////////////////////////////////////////////////////////////
+// Macros to define the memory scope objects. These are objects that are used
+// to annotate sections of the code base as belonging to a particular memory
+// scope. Note that this is an annotation and does not memory allocation.
+///////////////////////////////////////////////////////////////////////////////
+
+// Macro to track the memory scope inside a function or block of code. The
+// memory scope is in effect until the end of the code block.
+// Example:
+// void Foo() {
+// TRACK_MEMORY_SCOPE("FooMemoryScope");
+// // pops the memory scope at the end.
+// }
+
+#if !defined(__cplusplus)
+// Disallow macro use for non-C++ builds.
+#define TRACK_MEMORY_SCOPE(STR) error_forbidden_in_non_c_plus_plus_code
+#define TRACK_MEMORY_SCOPE_DYNAMIC(STR) error_forbidden_in_non_c_plus_plus_code
+#elif defined(STARBOARD_ALLOWS_MEMORY_TRACKING)
+#define TRACK_MEMORY_SCOPE(STR) TRACK_MEMORY_STATIC_CACHED(STR)
+#define TRACK_MEMORY_SCOPE_DYNAMIC(STR) TRACK_MEMORY_STATIC_NOT_CACHED(STR)
+#else
+// No-op when starboard does not allow memory tracking.
+#define TRACK_MEMORY_SCOPE(STR)
+#define TRACK_MEMORY_SCOPE_DYNAMIC(STR)
+#endif
+
+// Preprocessor needs double expansion in order to __FILE__, __LINE__ and
+// __FUNCTION__ properly.
+#define TRACK_MEMORY_STATIC_CACHED(STR) \
+ TRACK_MEMORY_STATIC_CACHED_IMPL_2(STR, __FILE__, __LINE__, __FUNCTION__)
+
+#define TRACK_MEMORY_STATIC_NOT_CACHED(STR) \
+ TRACK_MEMORY_STATIC_NOT_CACHED_IMPL_2(STR, __FILE__, __LINE__, __FUNCTION__)
+
+// Only enable TRACK_MEMORY_STATIC_CACHED_IMPL_2 if starboard allows memory
+// tracking.
+#define TRACK_MEMORY_STATIC_CACHED_IMPL_2(Str, FileStr, LineNum, FuncStr) \
+ static NbMemoryScopeInfo memory_scope_handle_##LineNum = \
+ { 0, Str, FileStr, LineNum, FuncStr, true }; \
+ NbPushMemoryScope(&memory_scope_handle_##LineNum); \
+ NbPopMemoryScopeOnScopeEnd pop_on_scope_end_##LineNum;
+
+#define TRACK_MEMORY_STATIC_NOT_CACHED_IMPL_2(Str, FileStr, LineNum, FuncStr) \
+ NbMemoryScopeInfo memory_scope_handle_##LineNum = { \
+ 0, Str, FileStr, LineNum, FuncStr, false}; \
+ NbPushMemoryScope(&memory_scope_handle_##LineNum); \
+ NbPopMemoryScopeOnScopeEnd pop_on_scope_end_##LineNum;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct NbMemoryScopeReporter;
+struct NbMemoryScopeInfo;
+
+// Sets the memory reporter. Returns true on success, false something
+// goes wrong.
+bool NbSetMemoryScopeReporter(NbMemoryScopeReporter* reporter);
+
+// Note that we pass by pointer because the memory scope contains a
+// variable allowing the result to be cached.
+void NbPushMemoryScope(NbMemoryScopeInfo* memory_scope);
+void NbPopMemoryScope();
+
+///////////////////////////////////////////////////////////////////////////////
+// Implementation
+///////////////////////////////////////////////////////////////////////////////
+// Interface for handling memory scopes.
+typedef void (*NbReportPushMemoryScopeCallback)(void* context,
+ NbMemoryScopeInfo* info);
+typedef void (*NbReportPopMemoryScopeCallback)(void* context);
+
+struct NbMemoryScopeReporter {
+ // Callback to report pushing of memory scope.
+ NbReportPushMemoryScopeCallback push_memory_scope_cb;
+
+ // Callback to report poping of the memory scope.
+ NbReportPopMemoryScopeCallback pop_memory_scope_cb;
+
+ // Optional, is passed to the callbacks as first argument.
+ void* context;
+};
+
+// This MemoryScope must remain a POD data type so that it can be statically
+// initialized.
+struct NbMemoryScopeInfo {
+ // cached_handle_ allows a cached result of the the fields represented in
+ // this struct to be generated and the handle be placed into this field.
+ // See also allows_caching_.
+ uintptr_t cached_handle_;
+
+ // Represents the name of the memory scope. I.E. "Javascript" or "Gfx".
+ const char* memory_scope_name_;
+
+ // Represents the file name that this memory scope was created at.
+ const char* file_name_;
+
+ // Represents the line number that this memory scope was created at.
+ int line_number_;
+
+ // Represents the function name that this memory scope was created at.
+ const char* function_name_;
+
+ // When true, if cached_handle_ is 0 then an object may be created that
+ // represents the fields of this object. The handle that represents this
+ // cached object is then placed in cached_hanlde_.
+ const bool allows_caching_;
+};
+
+// NbPopMemoryScopeOnScopeEnd is only allowed for C++ builds.
+#ifdef __cplusplus
+// A helper that pops the memory scope at the end of the current code block.
+struct NbPopMemoryScopeOnScopeEnd {
+ ~NbPopMemoryScopeOnScopeEnd() { NbPopMemoryScope(); }
+};
+#endif
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // NB_MEMORY_SCOPE_H_