WIP [kernel][heap][stats] add more call sites to the stats

Change-Id: If5490114366f09e27dc885ac9db2b7744ebd0d76
diff --git a/kernel/lib/heap/heap_wrapper.cpp b/kernel/lib/heap/heap_wrapper.cpp
index 12def92..311ea0c 100644
--- a/kernel/lib/heap/heap_wrapper.cpp
+++ b/kernel/lib/heap/heap_wrapper.cpp
@@ -142,6 +142,24 @@
     return ptr;
 }
 
+void *malloc_debug_caller(size_t size, void *caller) {
+    DEBUG_ASSERT(!arch_in_int_handler());
+
+    LTRACEF("size %zu\n", size);
+
+    add_stat(caller, size);
+
+    void* ptr = cmpct_alloc(size);
+    if (unlikely(heap_trace))
+        printf("caller %p malloc %zu -> %p\n", __GET_CALLER(), size, ptr);
+
+    if (HEAP_PANIC_ON_ALLOC_FAIL && unlikely(!ptr)) {
+        panic("malloc of size %zu failed\n", size);
+    }
+
+    return ptr;
+}
+
 void* memalign(size_t boundary, size_t size) {
     DEBUG_ASSERT(!arch_in_int_handler());
 
diff --git a/kernel/lib/heap/include/lib/heap.h b/kernel/lib/heap/include/lib/heap.h
index 51f76f6..a7602b2 100644
--- a/kernel/lib/heap/include/lib/heap.h
+++ b/kernel/lib/heap/include/lib/heap.h
@@ -13,25 +13,27 @@
 
 __BEGIN_CDECLS
 
-/* standard heap definitions */
+// standard heap definitions
 void *malloc(size_t size) __MALLOC;
 void *memalign(size_t boundary, size_t size) __MALLOC;
 void *calloc(size_t count, size_t size) __MALLOC;
 void *realloc(void *ptr, size_t size);
 void free(void *ptr);
 
+// alternate versions where the caller is passed in
+void *malloc_debug_caller(size_t size, void *caller) __MALLOC;
+
 void heap_init(void);
 
-/* tell the heap to return any free pages it can find */
+// tell the heap to return any free pages it can find
 void heap_trim(void);
 
-/* internal apis used by the heap implementation to get/return pages to the VM */
+// internal apis used by the heap implementation to get/return pages to the VM
 void *heap_page_alloc(size_t pages);
 void heap_page_free(void *ptr, size_t pages);
 
-/* Gets stats about the heap.
- * |size_bytes| is the total size of the heap, |free_bytes| is the free portion.
- */
+// Gets stats about the heap.
+// |size_bytes| is the total size of the heap, |free_bytes| is the free portion.
 void heap_get_info(size_t *size_bytes, size_t *free_bytes);
 
 __END_CDECLS
diff --git a/system/ulib/zxcpp/new.cpp b/system/ulib/zxcpp/new.cpp
index 35ed885..7b77144 100644
--- a/system/ulib/zxcpp/new.cpp
+++ b/system/ulib/zxcpp/new.cpp
@@ -7,9 +7,9 @@
 #include <zircon/assert.h>
 #include <stdlib.h>
 
+#if !_KERNEL
 // The kernel does not want non-AllocCheckered non-placement new
 // overloads, but userspace can have them.
-#if !_KERNEL
 void* operator new(size_t s) {
     if (s == 0u) {
         s = 1u;
@@ -31,7 +31,6 @@
     }
     return mem;
 }
-#endif // !_KERNEL
 
 void* operator new(size_t s, const std::nothrow_t&) noexcept {
     if (s == 0u) {
@@ -47,14 +46,25 @@
     return ::malloc(s);
 }
 
-void* operator new(size_t , void *p) {
-    return p;
+#else // !_KERNEL
+
+// kernel versions may pass through the call site to the underlying allocator
+void* operator new(size_t s, const std::nothrow_t&) noexcept {
+    if (s == 0u) {
+        s = 1u;
+    }
+    return ::malloc_debug_caller(s, __GET_CALLER());
 }
 
-void* operator new[](size_t , void* p) {
-    return p;
+void* operator new[](size_t s, const std::nothrow_t&) noexcept {
+    if (s == 0u) {
+        s = 1u;
+    }
+    return ::malloc_debug_caller(s, __GET_CALLER());
 }
 
+#endif // _KERNEL
+
 void operator delete(void *p) {
     return ::free(p);
 }
@@ -70,3 +80,11 @@
 void operator delete[](void *p, size_t s) {
     return ::free(p);
 }
+void* operator new(size_t , void *p) {
+    return p;
+}
+
+void* operator new[](size_t , void* p) {
+    return p;
+}
+