├── Zones └── jemalloc │ ├── src │ ├── spin.c │ ├── hash.c │ ├── prng.c │ ├── ticker.c │ ├── hooks.c │ ├── mutex_pool.c │ ├── extent_mmap.c │ ├── sz.c │ └── witness.c │ └── include │ ├── jemalloc │ ├── internal │ │ ├── private_namespace.sh │ │ ├── public_unnamespace.sh │ │ ├── public_namespace.sh │ │ ├── base_types.h │ │ ├── base_inlines.h │ │ ├── extent_types.h │ │ ├── tsd_types.h │ │ ├── stats_tsd.h │ │ ├── arena_structs_a.h │ │ ├── extent_mmap.h │ │ ├── public_unnamespace.h │ │ ├── public_symbols.txt │ │ ├── spin.h │ │ ├── extent_dss.h │ │ ├── hooks.h │ │ ├── base_externs.h │ │ ├── public_namespace.h │ │ ├── jemalloc_internal_macros.h │ │ ├── large_externs.h │ │ ├── tsd_tls.h │ │ ├── private_symbols.sh │ │ ├── ticker.h │ │ ├── tsd_malloc_thread_cleanup.h │ │ ├── background_thread_externs.h │ │ ├── nstime.h │ │ ├── assert.h │ │ ├── private_symbols.awk │ │ ├── private_symbols_jet.awk │ │ ├── base_structs.h │ │ ├── arena_inlines_a.h │ │ ├── arena_types.h │ │ ├── util.h │ │ ├── background_thread_structs.h │ │ ├── jemalloc_internal_externs.h │ │ ├── prof_types.h │ │ ├── rtree_tsd.h │ │ ├── malloc_io.h │ │ ├── background_thread_inlines.h │ │ ├── jemalloc_internal_decls.h │ │ ├── tcache_types.h │ │ ├── tcache_externs.h │ │ ├── prof_inlines_a.h │ │ ├── tcache_structs.h │ │ ├── qr.h │ │ ├── jemalloc_internal_inlines_b.h │ │ ├── pages.h │ │ ├── atomic.h │ │ ├── ql.h │ │ ├── mutex_prof.h │ │ └── mutex_pool.h │ ├── jemalloc_rename.sh │ ├── jemalloc.sh │ ├── jemalloc_rename.h │ ├── jemalloc_defs.h.in │ ├── jemalloc_mangle.sh │ ├── jemalloc_defs.h │ ├── jemalloc_mangle.h │ ├── jemalloc_mangle_jet.h │ ├── jemalloc_typedefs.h │ └── jemalloc_typedefs.h.in │ └── msvc_compat │ ├── windows_extra.h │ ├── C99 │ └── stdbool.h │ └── strings.h ├── DDMallocDetector ├── DDMallocDetector.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── MallocDetector.xcscheme ├── MallocDetector │ ├── Classes │ │ ├── views │ │ │ ├── control │ │ │ │ ├── MDInspectorIcon.h │ │ │ │ ├── MDInspectorWindow.h │ │ │ │ ├── MDInspectorWindow.mm │ │ │ │ └── MDInspectorIcon.m │ │ │ ├── Controller │ │ │ │ ├── MDControlViewController.h │ │ │ │ ├── ByTime │ │ │ │ │ ├── MDByTimeGroupTableViewController.h │ │ │ │ │ ├── MDByTimeGenerateTableViewController.h │ │ │ │ │ ├── MDByTimeGraphViewController.h │ │ │ │ │ └── MDByTimeGraphViewController.mm │ │ │ │ ├── BySize │ │ │ │ │ ├── MDBySizeGenerateTableViewController.h │ │ │ │ │ ├── MDBySizeGroupTableViewController.h │ │ │ │ │ ├── MDBySizeGraphViewController.h │ │ │ │ │ └── MDBySizeGraphViewController.mm │ │ │ │ ├── ByThread │ │ │ │ │ ├── MDByThreadGroupTableViewController.h │ │ │ │ │ ├── MDByThreadGraphViewController.h │ │ │ │ │ └── MDByThreadGraphViewController.mm │ │ │ │ ├── MDAnalysisGroupTableViewController.h │ │ │ │ └── MDControlViewController.mm │ │ │ ├── MDViewMacros.h │ │ │ └── graph │ │ │ │ ├── MDPerThreadView.h │ │ │ │ ├── MDByTimeView.h │ │ │ │ ├── MDStatisticsView.h │ │ │ │ ├── MDBySizeView.h │ │ │ │ ├── MDDrawableView.h │ │ │ │ ├── MDStatisticsView.mm │ │ │ │ ├── MDDrawableView.mm │ │ │ │ └── MDPerThreadView.mm │ │ ├── drawable │ │ │ ├── AxisLayer.mm │ │ │ ├── Drawable.hpp │ │ │ ├── CanvasLayer.mm │ │ │ ├── FillLayer.cpp │ │ │ ├── FillLayer.hpp │ │ │ ├── Color.h │ │ │ ├── CanvasLayer.h │ │ │ ├── Layer.hpp │ │ │ ├── Layer.cpp │ │ │ └── StrokeLayerHelper.hpp │ │ ├── base │ │ │ ├── Macros.h │ │ │ ├── Allocator.hpp │ │ │ └── ThreadLocal.hpp │ │ ├── MallocDetector.h │ │ ├── detector │ │ │ ├── MallocWrapZone.cpp │ │ │ ├── MallocCollector.hpp │ │ │ ├── MemoryDetector.cpp │ │ │ ├── MallocMemory.hpp │ │ │ ├── MallocCollectorHelper.hpp │ │ │ ├── MallocWrapZone.hpp │ │ │ ├── MallocPool.hpp │ │ │ └── MallocCollector.cpp │ │ ├── analysis │ │ │ ├── AnalysisTask.hpp │ │ │ ├── AnalysisTask.cpp │ │ │ ├── AnalysisHelper.h │ │ │ ├── AnalysisPerThread.cpp │ │ │ ├── AnalysisPerThread.hpp │ │ │ └── AnalysisBySize.hpp │ │ └── MallocDetector.mm │ ├── MallocDetector.h │ └── Info.plist └── DDMallocDetector │ ├── ViewController.h │ ├── AppDelegate.h │ ├── main.mm │ ├── ViewController.mm │ ├── Info.plist │ ├── Base.lproj │ ├── Main.storyboard │ └── LaunchScreen.storyboard │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ └── AppDelegate.m ├── JemallocDemo ├── JemallocDemo │ ├── ViewController.h │ ├── AppDelegate.h │ ├── main.m │ ├── ViewController.m │ ├── Info.plist │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ └── AppDelegate.m ├── jemalloc │ ├── jemalloc.h │ └── Info.plist └── JemallocDemo.xcodeproj │ └── xcshareddata │ └── xcschemes │ └── jemalloc.xcscheme ├── LICENSE └── .gitignore /Zones/jemalloc/src/spin.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_SPIN_C_ 2 | #include "jemalloc/internal/jemalloc_preamble.h" 3 | 4 | #include "jemalloc/internal/spin.h" 5 | -------------------------------------------------------------------------------- /Zones/jemalloc/src/hash.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_HASH_C_ 2 | #include "jemalloc/internal/jemalloc_preamble.h" 3 | #include "jemalloc/internal/jemalloc_internal_includes.h" 4 | -------------------------------------------------------------------------------- /Zones/jemalloc/src/prng.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_PRNG_C_ 2 | #include "jemalloc/internal/jemalloc_preamble.h" 3 | #include "jemalloc/internal/jemalloc_internal_includes.h" 4 | -------------------------------------------------------------------------------- /Zones/jemalloc/src/ticker.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_TICKER_C_ 2 | #include "jemalloc/internal/jemalloc_preamble.h" 3 | #include "jemalloc/internal/jemalloc_internal_includes.h" 4 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/private_namespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for symbol in `cat "$@"` ; do 4 | echo "#define ${symbol} JEMALLOC_N(${symbol})" 5 | done 6 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/public_unnamespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for nm in `cat $1` ; do 4 | n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'` 5 | echo "#undef je_${n}" 6 | done 7 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/msvc_compat/windows_extra.h: -------------------------------------------------------------------------------- 1 | #ifndef MSVC_COMPAT_WINDOWS_EXTRA_H 2 | #define MSVC_COMPAT_WINDOWS_EXTRA_H 3 | 4 | #include 5 | 6 | #endif /* MSVC_COMPAT_WINDOWS_EXTRA_H */ 7 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/public_namespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for nm in `cat $1` ; do 4 | n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'` 5 | echo "#define je_${n} JEMALLOC_N(${n})" 6 | done 7 | -------------------------------------------------------------------------------- /DDMallocDetector/DDMallocDetector.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/base_types.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_BASE_TYPES_H 2 | #define JEMALLOC_INTERNAL_BASE_TYPES_H 3 | 4 | typedef struct base_block_s base_block_t; 5 | typedef struct base_s base_t; 6 | 7 | #endif /* JEMALLOC_INTERNAL_BASE_TYPES_H */ 8 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/base_inlines.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_BASE_INLINES_H 2 | #define JEMALLOC_INTERNAL_BASE_INLINES_H 3 | 4 | static inline unsigned 5 | base_ind_get(const base_t *base) { 6 | return base->ind; 7 | } 8 | 9 | #endif /* JEMALLOC_INTERNAL_BASE_INLINES_H */ 10 | -------------------------------------------------------------------------------- /JemallocDemo/JemallocDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // JemallocDemo 4 | // 5 | // Created by daniel on 2018/4/6. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/extent_types.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_EXTENT_TYPES_H 2 | #define JEMALLOC_INTERNAL_EXTENT_TYPES_H 3 | 4 | typedef struct extent_s extent_t; 5 | typedef struct extents_s extents_t; 6 | 7 | #define EXTENT_HOOKS_INITIALIZER NULL 8 | 9 | #endif /* JEMALLOC_INTERNAL_EXTENT_TYPES_H */ 10 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/control/MDInspectorIcon.h: -------------------------------------------------------------------------------- 1 | // 2 | // MDInspectorIcon.h 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/3/31. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MDInspectorIcon : UIButton 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /DDMallocDetector/DDMallocDetector/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // DDMallocDetector 4 | // 5 | // Created by hzduanjiashun on 2018/3/30. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/tsd_types.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_TSD_TYPES_H 2 | #define JEMALLOC_INTERNAL_TSD_TYPES_H 3 | 4 | #define MALLOC_TSD_CLEANUPS_MAX 2 5 | 6 | typedef struct tsd_s tsd_t; 7 | typedef struct tsdn_s tsdn_t; 8 | typedef bool (*malloc_tsd_cleanup_t)(void); 9 | 10 | #endif /* JEMALLOC_INTERNAL_TSD_TYPES_H */ 11 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/Controller/MDControlViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MDControlTableViewController.h 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/3/31. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MDControlViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/drawable/AxisLayer.mm: -------------------------------------------------------------------------------- 1 | // 2 | // AxisLayer.cpp 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/30. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #include "AxisLayer.hpp" 10 | #include "CanvasLayer.h" 11 | #include 12 | 13 | namespace MD { 14 | 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /JemallocDemo/JemallocDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // JemallocDemo 4 | // 5 | // Created by daniel on 2018/4/6. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/stats_tsd.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_STATS_TSD_H 2 | #define JEMALLOC_INTERNAL_STATS_TSD_H 3 | 4 | typedef struct tcache_bin_stats_s { 5 | /* 6 | * Number of allocation requests that corresponded to the size of this 7 | * bin. 8 | */ 9 | uint64_t nrequests; 10 | } tcache_bin_stats_t; 11 | 12 | #endif /* JEMALLOC_INTERNAL_STATS_TSD_H */ 13 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/arena_structs_a.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_ARENA_STRUCTS_A_H 2 | #define JEMALLOC_INTERNAL_ARENA_STRUCTS_A_H 3 | 4 | #include "jemalloc/internal/bitmap.h" 5 | 6 | struct arena_slab_data_s { 7 | /* Per region allocated/deallocated bitmap. */ 8 | bitmap_t bitmap[BITMAP_GROUPS_MAX]; 9 | }; 10 | 11 | #endif /* JEMALLOC_INTERNAL_ARENA_STRUCTS_A_H */ 12 | -------------------------------------------------------------------------------- /DDMallocDetector/DDMallocDetector/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // DDMallocDetector 4 | // 5 | // Created by hzduanjiashun on 2018/3/30. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/Controller/ByTime/MDByTimeGroupTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MDByTimeGroupTableViewController.h 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/4/2. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MDByTimeGroupTableViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/Controller/BySize/MDBySizeGenerateTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MDBySizeGenerateTableViewController.h 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/4/2. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MDBySizeGenerateTableViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/Controller/BySize/MDBySizeGroupTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MDBySizeGroupTableViewController.h 3 | // DDMallocDetector 4 | // 5 | // Created by hzduanjiashun on 2018/4/2. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MDBySizeGroupTableViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/Controller/ByThread/MDByThreadGroupTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MDByThreadGroupTableViewController.h 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/4/3. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MDByThreadGroupTableViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/Controller/ByTime/MDByTimeGenerateTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MDByTimeGenerateTableViewController.h 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/4/2. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MDByTimeGenerateTableViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/Controller/MDAnalysisGroupTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MDAnalysisGroupTableViewController.h 3 | // DDMallocDetector 4 | // 5 | // Created by hzduanjiashun on 2018/4/2. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MDAnalysisGroupTableViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/extent_mmap.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_EXTENT_MMAP_EXTERNS_H 2 | #define JEMALLOC_INTERNAL_EXTENT_MMAP_EXTERNS_H 3 | 4 | extern bool opt_retain; 5 | 6 | void *extent_alloc_mmap(void *new_addr, size_t size, size_t alignment, 7 | bool *zero, bool *commit); 8 | bool extent_dalloc_mmap(void *addr, size_t size); 9 | 10 | #endif /* JEMALLOC_INTERNAL_EXTENT_MMAP_EXTERNS_H */ 11 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/MDViewMacros.h: -------------------------------------------------------------------------------- 1 | // 2 | // MDViewMacros.h 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/3/31. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #ifndef MDViewMacros_h 10 | #define MDViewMacros_h 11 | 12 | #define MDViewAssertMainThread() NSAssert([NSThread isMainThread], @"Must call at main thread!") 13 | 14 | #endif /* MDViewMacros_h */ 15 | -------------------------------------------------------------------------------- /JemallocDemo/JemallocDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // JemallocDemo 4 | // 5 | // Created by daniel on 2018/4/6. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/drawable/Drawable.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Drawable.hpp 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/28. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #ifndef Drawable_hpp 10 | #define Drawable_hpp 11 | 12 | #include 13 | 14 | namespace MD { 15 | class Drawable { 16 | public: 17 | virtual void Draw() = 0; 18 | }; 19 | } 20 | 21 | #endif /* Drawable_hpp */ 22 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/control/MDInspectorWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // MDInspectorWindow.h 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/3/31. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MDInspectorWindow : UIWindow 12 | 13 | + (instancetype)sharedWindow; 14 | 15 | + (BOOL)isEnabled; 16 | + (void)enable; 17 | + (void)disable; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/graph/MDPerThreadView.h: -------------------------------------------------------------------------------- 1 | // 2 | // MDPerThreadView.h 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/4/1. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import "MDDrawableView.h" 10 | #include "AnalysisPerThread.hpp" 11 | 12 | @interface MDPerThreadView : MDDrawableView 13 | 14 | - (void)setPerThreadData:(MD::PerThreadData::memory_list_type_ptr)data; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/Controller/ByTime/MDByTimeGraphViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MDByTimeGraphViewController.h 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/4/2. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MDByTimeView.h" 11 | 12 | @interface MDByTimeGraphViewController : UIViewController 13 | 14 | - (void)setData:(MDByTimeDataPtrType)data; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Zones/jemalloc/src/hooks.c: -------------------------------------------------------------------------------- 1 | #include "jemalloc/internal/jemalloc_preamble.h" 2 | 3 | /* 4 | * The hooks are a little bit screwy -- they're not genuinely exported in the 5 | * sense that we want them available to end-users, but we do want them visible 6 | * from outside the generated library, so that we can use them in test code. 7 | */ 8 | JEMALLOC_EXPORT 9 | void (*hooks_arena_new_hook)() = NULL; 10 | 11 | JEMALLOC_EXPORT 12 | void (*hooks_libc_hook)() = NULL; 13 | -------------------------------------------------------------------------------- /DDMallocDetector/DDMallocDetector/main.mm: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // DDMallocDetector 4 | // 5 | // Created by hzduanjiashun on 2018/3/30. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | #import "MallocDetector.h" 12 | 13 | int main(int argc, char * argv[]) { 14 | 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/Controller/ByThread/MDByThreadGraphViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MDGraphViewController.h 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/3/31. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MDPerThreadView.h" 11 | 12 | @interface MDByThreadGraphViewController : UIViewController 13 | 14 | @property (nonatomic, strong) MDPerThreadView *statView; 15 | 16 | - (void)setData:(MD::PerThreadData::memory_list_type_ptr)data; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/drawable/CanvasLayer.mm: -------------------------------------------------------------------------------- 1 | // 2 | // CanvasLayer.cpp 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/29. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #include 10 | #include "CanvasLayer.h" 11 | 12 | namespace MD { 13 | void CanvasLayer::Draw() { 14 | ctx_ = UIGraphicsGetCurrentContext(); 15 | super::Draw(); 16 | } 17 | 18 | void CanvasLayer::Draw(CGContextRef ctx) { 19 | ctx_ = ctx; 20 | super::Draw(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/msvc_compat/C99/stdbool.h: -------------------------------------------------------------------------------- 1 | #ifndef stdbool_h 2 | #define stdbool_h 3 | 4 | #include 5 | 6 | /* MSVC doesn't define _Bool or bool in C, but does have BOOL */ 7 | /* Note this doesn't pass autoconf's test because (bool) 0.5 != true */ 8 | /* Clang-cl uses MSVC headers, so needs msvc_compat, but has _Bool as 9 | * a built-in type. */ 10 | #ifndef __clang__ 11 | typedef BOOL _Bool; 12 | #endif 13 | 14 | #define bool _Bool 15 | #define true 1 16 | #define false 0 17 | 18 | #define __bool_true_false_are_defined 1 19 | 20 | #endif /* stdbool_h */ 21 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/public_unnamespace.h: -------------------------------------------------------------------------------- 1 | #undef je_aligned_alloc 2 | #undef je_calloc 3 | #undef je_dallocx 4 | #undef je_free 5 | #undef je_mallctl 6 | #undef je_mallctlbymib 7 | #undef je_mallctlnametomib 8 | #undef je_malloc 9 | #undef je_malloc_conf 10 | #undef je_malloc_message 11 | #undef je_malloc_stats_print 12 | #undef je_malloc_usable_size 13 | #undef je_mallocx 14 | #undef je_nallocx 15 | #undef je_posix_memalign 16 | #undef je_rallocx 17 | #undef je_realloc 18 | #undef je_sallocx 19 | #undef je_sdallocx 20 | #undef je_xallocx 21 | #undef je_valloc 22 | -------------------------------------------------------------------------------- /Zones/jemalloc/src/mutex_pool.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_MUTEX_POOL_C_ 2 | 3 | #include "jemalloc/internal/jemalloc_preamble.h" 4 | #include "jemalloc/internal/jemalloc_internal_includes.h" 5 | 6 | #include "jemalloc/internal/mutex.h" 7 | #include "jemalloc/internal/mutex_pool.h" 8 | 9 | bool 10 | mutex_pool_init(mutex_pool_t *pool, const char *name, witness_rank_t rank) { 11 | for (int i = 0; i < MUTEX_POOL_SIZE; ++i) { 12 | if (malloc_mutex_init(&pool->mutexes[i], name, rank, 13 | malloc_mutex_address_ordered)) { 14 | return true; 15 | } 16 | } 17 | return false; 18 | } 19 | -------------------------------------------------------------------------------- /JemallocDemo/jemalloc/jemalloc.h: -------------------------------------------------------------------------------- 1 | // 2 | // jemalloc.h 3 | // jemalloc 4 | // 5 | // Created by daniel on 2018/4/6. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for jemalloc. 12 | FOUNDATION_EXPORT double jemallocVersionNumber; 13 | 14 | //! Project version string for jemalloc. 15 | FOUNDATION_EXPORT const unsigned char jemallocVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/jemalloc_rename.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | public_symbols_txt=$1 4 | 5 | cat < 10 | #include "../../../analysis/AnalysisBySize.hpp" 11 | 12 | typedef std::shared_ptr>> MDBySizeGraphViewControllerData; 13 | 14 | @interface MDBySizeGraphViewController : UIViewController 15 | 16 | - (void)setData:(MDBySizeGraphViewControllerData)data; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/jemalloc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | objroot=$1 4 | 5 | cat < 11 | #include 12 | 13 | typedef std::pair MDByTimeItemType; 14 | typedef std::vector MDByTimeDataType; 15 | typedef std::shared_ptr MDByTimeDataPtrType; 16 | 17 | @interface MDByTimeView : MDDrawableView 18 | 19 | - (void)setData:(MDByTimeDataPtrType)data; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/base/Macros.h: -------------------------------------------------------------------------------- 1 | // 2 | // Macros.h 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/30. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #ifndef Macros_h 10 | #define Macros_h 11 | 12 | #define MD_NO_COPY(TypeName) \ 13 | TypeName(const TypeName&) = delete 14 | 15 | #define MD_NO_ASSIGN(TypeName) \ 16 | TypeName& operator= (const TypeName&) = delete 17 | 18 | #define MD_NO_COPY_ASSIGN(TypeName) \ 19 | MD_NO_COPY(TypeName); \ 20 | MD_NO_ASSIGN(TypeName) 21 | 22 | #endif /* Macros_h */ 23 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/drawable/FillLayer.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // FillLayer.cpp 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/30. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #include "FillLayer.hpp" 10 | #include "CanvasLayer.h" 11 | 12 | namespace MD { 13 | void FillLayer::Draw() { 14 | auto ctx = canvas()->context(); 15 | CGContextSaveGState(ctx); 16 | Rect r = absoluteFrame(); 17 | CGContextSetFillColor(ctx, backgroundColor()); 18 | CGContextFillRect(ctx, r); 19 | CGContextRestoreGState(ctx); 20 | super::Draw(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/public_symbols.txt: -------------------------------------------------------------------------------- 1 | aligned_alloc:je_aligned_alloc 2 | calloc:je_calloc 3 | dallocx:je_dallocx 4 | free:je_free 5 | mallctl:je_mallctl 6 | mallctlbymib:je_mallctlbymib 7 | mallctlnametomib:je_mallctlnametomib 8 | malloc:je_malloc 9 | malloc_conf:je_malloc_conf 10 | malloc_message:je_malloc_message 11 | malloc_stats_print:je_malloc_stats_print 12 | malloc_usable_size:je_malloc_usable_size 13 | mallocx:je_mallocx 14 | nallocx:je_nallocx 15 | posix_memalign:je_posix_memalign 16 | rallocx:je_rallocx 17 | realloc:je_realloc 18 | sallocx:je_sallocx 19 | sdallocx:je_sdallocx 20 | xallocx:je_xallocx 21 | valloc:je_valloc 22 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/graph/MDStatisticsView.h: -------------------------------------------------------------------------------- 1 | // 2 | // MDStatisticsView.h 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/29. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MDDrawableView.h" 11 | #include 12 | #include 13 | 14 | namespace MD { 15 | namespace View { 16 | typedef std::vector Line; 17 | typedef std::vector> Lines; 18 | } 19 | } 20 | 21 | @interface MDStatisticsView : MDDrawableView 22 | 23 | - (void)setLines:(std::shared_ptr)lines; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /JemallocDemo/JemallocDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // JemallocDemo 4 | // 5 | // Created by daniel on 2018/4/6. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view, typically from a nib. 20 | } 21 | 22 | 23 | - (void)didReceiveMemoryWarning { 24 | [super didReceiveMemoryWarning]; 25 | // Dispose of any resources that can be recreated. 26 | } 27 | 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/MallocDetector.h: -------------------------------------------------------------------------------- 1 | // 2 | // MallocDetector.h 3 | // MallocDetector 4 | // 5 | // Created by daniel on 2018/4/6. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "./Classes/MallocDetector.h" 12 | 13 | //! Project version number for MallocDetector. 14 | FOUNDATION_EXPORT double MallocDetectorVersionNumber; 15 | 16 | //! Project version string for MallocDetector. 17 | FOUNDATION_EXPORT const unsigned char MallocDetectorVersionString[]; 18 | 19 | // In this header, you should import all the public headers of your framework using statements like #import 20 | 21 | 22 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/graph/MDBySizeView.h: -------------------------------------------------------------------------------- 1 | // 2 | // MDBySizeView.h 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/4/2. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import "MDDrawableView.h" 10 | #include 11 | #include 12 | #include 13 | 14 | typedef std::pair MDBySizeItemType; 15 | typedef std::shared_ptr> MDBySizeListType; 16 | 17 | @interface MDBySizeView : MDDrawableView 18 | 19 | //- (void)setXMin:(std::size_t)min max:(std::size_t)max; 20 | - (void)setList:(MDBySizeListType)list minCount:(std::size_t)min maxCount:(std::size_t)max; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/MallocDetector.h: -------------------------------------------------------------------------------- 1 | // 2 | // DDMallocDetector.hpp 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/3/31. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #ifndef DDMallocDetector_hpp 10 | #define DDMallocDetector_hpp 11 | 12 | #include 13 | #include 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | void malloc_detector_attach_zone(bool default_zone); 20 | void malloc_detector_start(); 21 | void malloc_detector_stop(); 22 | bool malloc_detector_is_running(); 23 | void malloc_detector_show_inspector(); 24 | 25 | #ifdef __cplusplus 26 | } // extern "C" 27 | #endif 28 | 29 | #endif /* DDMallocDetector_hpp */ 30 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/spin.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_SPIN_H 2 | #define JEMALLOC_INTERNAL_SPIN_H 3 | 4 | #ifdef JEMALLOC_SPIN_C_ 5 | # define SPIN_INLINE extern inline 6 | #else 7 | # define SPIN_INLINE inline 8 | #endif 9 | 10 | #define SPIN_INITIALIZER {0U} 11 | 12 | typedef struct { 13 | unsigned iteration; 14 | } spin_t; 15 | 16 | SPIN_INLINE void 17 | spin_adaptive(spin_t *spin) { 18 | volatile uint32_t i; 19 | 20 | if (spin->iteration < 5) { 21 | for (i = 0; i < (1U << spin->iteration); i++) { 22 | CPU_SPINWAIT; 23 | } 24 | spin->iteration++; 25 | } else { 26 | #ifdef _WIN32 27 | SwitchToThread(); 28 | #else 29 | sched_yield(); 30 | #endif 31 | } 32 | } 33 | 34 | #undef SPIN_INLINE 35 | 36 | #endif /* JEMALLOC_INTERNAL_SPIN_H */ 37 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/detector/MallocWrapZone.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // MallocWrapZone.cpp 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/27. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #include "MallocWrapZone.hpp" 10 | #include 11 | #include 12 | #include "MallocCollector.hpp" 13 | 14 | namespace MD { 15 | 16 | void MallocWrapZones::MallocWrapZone::Wrap() { 17 | mprotect(orig_zone_ptr_, sizeof(malloc_zone_t), PROT_READ|PROT_WRITE); 18 | orig_zone_ptr_->malloc = Wrap::malloc; 19 | mprotect(orig_zone_ptr_, sizeof(malloc_zone_t), PROT_READ); 20 | } 21 | 22 | void MallocWrapZones::MallocWrapZone::UnWrap() { 23 | orig_zone_ptr_->malloc = orig_zone_.malloc; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/drawable/FillLayer.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // FillLayer.hpp 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/30. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #ifndef FillLayer_hpp 10 | #define FillLayer_hpp 11 | 12 | #include 13 | #include "Layer.hpp" 14 | 15 | namespace MD { 16 | class FillLayer : public Layer { 17 | public: 18 | typedef Layer super; 19 | 20 | void setBackgroundColor(Color color) { 21 | background_color_ = color; 22 | } 23 | Color& backgroundColor() { return background_color_; } 24 | 25 | void Draw() override; 26 | 27 | private: 28 | Color background_color_; 29 | }; 30 | } 31 | 32 | #endif /* FillLayer_hpp */ 33 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/graph/MDDrawableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // MDDrawableView.h 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/29. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | #include "CanvasLayer.h" 11 | #include "StrokeLayer.hpp" 12 | #include "AxisLayer.hpp" 13 | 14 | @interface MDDrawableView : UIView { 15 | @protected 16 | std::shared_ptr _xAxis; 17 | std::shared_ptr _yAxis; 18 | std::shared_ptr _contentLayer; 19 | } 20 | 21 | 22 | - (const std::shared_ptr&)canvas; 23 | - (void)setNeedsRebuildCanvas; 24 | - (void)rebuildCanvasIfNeeded; 25 | - (void)rebuildCanvas NS_REQUIRES_SUPER; 26 | 27 | - (std::shared_ptr)makeXAxis; 28 | - (std::shared_ptr)makeYAxis; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/extent_dss.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_EXTENT_DSS_H 2 | #define JEMALLOC_INTERNAL_EXTENT_DSS_H 3 | 4 | typedef enum { 5 | dss_prec_disabled = 0, 6 | dss_prec_primary = 1, 7 | dss_prec_secondary = 2, 8 | 9 | dss_prec_limit = 3 10 | } dss_prec_t; 11 | #define DSS_PREC_DEFAULT dss_prec_secondary 12 | #define DSS_DEFAULT "secondary" 13 | 14 | extern const char *dss_prec_names[]; 15 | 16 | extern const char *opt_dss; 17 | 18 | dss_prec_t extent_dss_prec_get(void); 19 | bool extent_dss_prec_set(dss_prec_t dss_prec); 20 | void *extent_alloc_dss(tsdn_t *tsdn, arena_t *arena, void *new_addr, 21 | size_t size, size_t alignment, bool *zero, bool *commit); 22 | bool extent_in_dss(void *addr); 23 | bool extent_dss_mergeable(void *addr_a, void *addr_b); 24 | void extent_dss_boot(void); 25 | 26 | #endif /* JEMALLOC_INTERNAL_EXTENT_DSS_H */ 27 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/analysis/AnalysisTask.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // AnalysisTask.hpp 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/3/31. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #ifndef AnalysisTask_hpp 10 | #define AnalysisTask_hpp 11 | 12 | #include 13 | #include 14 | #include "MallocPool.hpp" 15 | 16 | namespace MD { 17 | class AnalysisTask { 18 | public: 19 | AnalysisTask() : canceled_(false), running_(false) {} 20 | void Start(); 21 | void Cancel(); 22 | bool canceled(); 23 | bool running() { return running_.load(); } 24 | protected: 25 | MallocPool& pool() const; 26 | virtual void Run() = 0; 27 | private: 28 | std::atomic canceled_; 29 | std::atomic running_; 30 | }; 31 | } 32 | 33 | #endif /* AnalysisTask_hpp */ 34 | -------------------------------------------------------------------------------- /JemallocDemo/jemalloc/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/hooks.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_HOOKS_H 2 | #define JEMALLOC_INTERNAL_HOOKS_H 3 | 4 | extern JEMALLOC_EXPORT void (*hooks_arena_new_hook)(); 5 | extern JEMALLOC_EXPORT void (*hooks_libc_hook)(); 6 | 7 | #define JEMALLOC_HOOK(fn, hook) ((void)(hook != NULL && (hook(), 0)), fn) 8 | 9 | #define open JEMALLOC_HOOK(open, hooks_libc_hook) 10 | #define read JEMALLOC_HOOK(read, hooks_libc_hook) 11 | #define write JEMALLOC_HOOK(write, hooks_libc_hook) 12 | #define readlink JEMALLOC_HOOK(readlink, hooks_libc_hook) 13 | #define close JEMALLOC_HOOK(close, hooks_libc_hook) 14 | #define creat JEMALLOC_HOOK(creat, hooks_libc_hook) 15 | #define secure_getenv JEMALLOC_HOOK(secure_getenv, hooks_libc_hook) 16 | /* Note that this is undef'd and re-define'd in src/prof.c. */ 17 | #define _Unwind_Backtrace JEMALLOC_HOOK(_Unwind_Backtrace, hooks_libc_hook) 18 | 19 | #endif /* JEMALLOC_INTERNAL_HOOKS_H */ 20 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/base_externs.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_BASE_EXTERNS_H 2 | #define JEMALLOC_INTERNAL_BASE_EXTERNS_H 3 | 4 | base_t *b0get(void); 5 | base_t *base_new(tsdn_t *tsdn, unsigned ind, extent_hooks_t *extent_hooks); 6 | void base_delete(tsdn_t *tsdn, base_t *base); 7 | extent_hooks_t *base_extent_hooks_get(base_t *base); 8 | extent_hooks_t *base_extent_hooks_set(base_t *base, 9 | extent_hooks_t *extent_hooks); 10 | void *base_alloc(tsdn_t *tsdn, base_t *base, size_t size, size_t alignment); 11 | extent_t *base_alloc_extent(tsdn_t *tsdn, base_t *base); 12 | void base_stats_get(tsdn_t *tsdn, base_t *base, size_t *allocated, 13 | size_t *resident, size_t *mapped); 14 | void base_prefork(tsdn_t *tsdn, base_t *base); 15 | void base_postfork_parent(tsdn_t *tsdn, base_t *base); 16 | void base_postfork_child(tsdn_t *tsdn, base_t *base); 17 | bool base_boot(tsdn_t *tsdn); 18 | 19 | #endif /* JEMALLOC_INTERNAL_BASE_EXTERNS_H */ 20 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/detector/MallocCollector.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // MallocCollector.hpp 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/27. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #ifndef MallocCollector_hpp 10 | #define MallocCollector_hpp 11 | 12 | #include 13 | #include "MallocStorage.hpp" 14 | #include "MallocCollector.hpp" 15 | 16 | namespace MD { 17 | 18 | typedef Storage MemoryStorage; 19 | 20 | struct CollectorChecker { 21 | static int64_t max(); 22 | static void overflow(MemoryStorage* storage); 23 | }; 24 | 25 | typedef Collector MemoryCollector; 26 | 27 | namespace Wrap { 28 | 29 | 30 | extern void *malloc(malloc_zone_t *zone, size_t size); 31 | // void free(malloc_zone_t *zone, void *ptr) { 32 | // 33 | // } 34 | } 35 | } 36 | 37 | #endif /* MallocCollector_hpp */ 38 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/analysis/AnalysisTask.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // AnalysisTask.cpp 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/3/31. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #include "AnalysisTask.hpp" 10 | #include "MemoryDetector.hpp" 11 | 12 | namespace MD { 13 | MallocPool& AnalysisTask::pool() const { 14 | return MemoryDetector::GetInstance()->pool(); 15 | } 16 | 17 | void AnalysisTask::Start() { 18 | if (MemoryDetector::GetInstance()->Running()) { 19 | throw MemoryDetector::ProtectException(); 20 | } 21 | else { 22 | if (!canceled()) { 23 | running_.store(true); 24 | Run(); 25 | running_.store(false); 26 | } 27 | } 28 | } 29 | 30 | void AnalysisTask::Cancel() { 31 | canceled_.store(true); 32 | } 33 | 34 | bool AnalysisTask::canceled() { 35 | return canceled_.load(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/MallocDetector.mm: -------------------------------------------------------------------------------- 1 | // 2 | // DDMallocDetector.cpp 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/3/31. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #include "MallocDetector.h" 10 | #include "MemoryDetector.hpp" 11 | #import "MDInspectorWindow.h" 12 | 13 | void malloc_detector_attach_zone(bool default_zone) { 14 | auto d = MD::MemoryDetector::GetInstance(); 15 | if (default_zone) { 16 | d->DetectorDefaultZone(); 17 | } 18 | else { 19 | d->DetectorAllZones(); 20 | } 21 | } 22 | 23 | void malloc_detector_start() { 24 | auto d = MD::MemoryDetector::GetInstance(); 25 | d->ClearPool(); 26 | d->Start(); 27 | } 28 | 29 | void malloc_detector_stop() { 30 | MD::MemoryDetector::GetInstance()->Stop(); 31 | } 32 | 33 | bool malloc_detector_is_running() { 34 | return MD::MemoryDetector::GetInstance()->Running(); 35 | } 36 | 37 | 38 | void malloc_detector_show_inspector() { 39 | [MDInspectorWindow enable]; 40 | } 41 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/Controller/ByTime/MDByTimeGraphViewController.mm: -------------------------------------------------------------------------------- 1 | // 2 | // MDByTimeGraphViewController.m 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/4/2. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import "MDByTimeGraphViewController.h" 10 | 11 | @interface MDByTimeGraphViewController () { 12 | MDByTimeDataPtrType _data; 13 | } 14 | 15 | @property (nonatomic, strong) MDByTimeView *graphView; 16 | 17 | @end 18 | 19 | @implementation MDByTimeGraphViewController 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | 24 | self.graphView = [[MDByTimeView alloc] initWithFrame:self.view.bounds]; 25 | [self.view addSubview:self.graphView]; 26 | 27 | [self.graphView setData:_data]; 28 | [self.graphView rebuildCanvasIfNeeded]; 29 | } 30 | 31 | - (void)setData:(MDByTimeDataPtrType)data { 32 | _data = data; 33 | 34 | [self.graphView setData:_data]; 35 | [self.graphView rebuildCanvasIfNeeded]; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/public_namespace.h: -------------------------------------------------------------------------------- 1 | #define je_aligned_alloc JEMALLOC_N(aligned_alloc) 2 | #define je_calloc JEMALLOC_N(calloc) 3 | #define je_dallocx JEMALLOC_N(dallocx) 4 | #define je_free JEMALLOC_N(free) 5 | #define je_mallctl JEMALLOC_N(mallctl) 6 | #define je_mallctlbymib JEMALLOC_N(mallctlbymib) 7 | #define je_mallctlnametomib JEMALLOC_N(mallctlnametomib) 8 | #define je_malloc JEMALLOC_N(malloc) 9 | #define je_malloc_conf JEMALLOC_N(malloc_conf) 10 | #define je_malloc_message JEMALLOC_N(malloc_message) 11 | #define je_malloc_stats_print JEMALLOC_N(malloc_stats_print) 12 | #define je_malloc_usable_size JEMALLOC_N(malloc_usable_size) 13 | #define je_mallocx JEMALLOC_N(mallocx) 14 | #define je_nallocx JEMALLOC_N(nallocx) 15 | #define je_posix_memalign JEMALLOC_N(posix_memalign) 16 | #define je_rallocx JEMALLOC_N(rallocx) 17 | #define je_realloc JEMALLOC_N(realloc) 18 | #define je_sallocx JEMALLOC_N(sallocx) 19 | #define je_sdallocx JEMALLOC_N(sdallocx) 20 | #define je_xallocx JEMALLOC_N(xallocx) 21 | #define je_valloc JEMALLOC_N(valloc) 22 | -------------------------------------------------------------------------------- /Zones/jemalloc/src/extent_mmap.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_EXTENT_MMAP_C_ 2 | #include "jemalloc/internal/jemalloc_preamble.h" 3 | #include "jemalloc/internal/jemalloc_internal_includes.h" 4 | 5 | #include "jemalloc/internal/assert.h" 6 | #include "jemalloc/internal/extent_mmap.h" 7 | 8 | /******************************************************************************/ 9 | /* Data. */ 10 | 11 | bool opt_retain = 12 | #ifdef JEMALLOC_RETAIN 13 | true 14 | #else 15 | false 16 | #endif 17 | ; 18 | 19 | /******************************************************************************/ 20 | 21 | void * 22 | extent_alloc_mmap(void *new_addr, size_t size, size_t alignment, bool *zero, 23 | bool *commit) { 24 | void *ret = pages_map(new_addr, size, ALIGNMENT_CEILING(alignment, 25 | PAGE), commit); 26 | if (ret == NULL) { 27 | return NULL; 28 | } 29 | assert(ret != NULL); 30 | if (*commit) { 31 | *zero = true; 32 | } 33 | return ret; 34 | } 35 | 36 | bool 37 | extent_dalloc_mmap(void *addr, size_t size) { 38 | if (!opt_retain) { 39 | pages_unmap(addr, size); 40 | } 41 | return opt_retain; 42 | } 43 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/jemalloc_internal_macros.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_MACROS_H 2 | #define JEMALLOC_INTERNAL_MACROS_H 3 | 4 | #ifdef JEMALLOC_DEBUG 5 | # define JEMALLOC_ALWAYS_INLINE static inline 6 | #else 7 | # define JEMALLOC_ALWAYS_INLINE JEMALLOC_ATTR(always_inline) static inline 8 | #endif 9 | #ifdef _MSC_VER 10 | # define inline _inline 11 | #endif 12 | 13 | #define UNUSED JEMALLOC_ATTR(unused) 14 | 15 | #define ZU(z) ((size_t)z) 16 | #define ZD(z) ((ssize_t)z) 17 | #define QU(q) ((uint64_t)q) 18 | #define QD(q) ((int64_t)q) 19 | 20 | #define KZU(z) ZU(z##ULL) 21 | #define KZD(z) ZD(z##LL) 22 | #define KQU(q) QU(q##ULL) 23 | #define KQD(q) QI(q##LL) 24 | 25 | #ifndef __DECONST 26 | # define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var)) 27 | #endif 28 | 29 | #if !defined(JEMALLOC_HAS_RESTRICT) || defined(__cplusplus) 30 | # define restrict 31 | #endif 32 | 33 | /* Various function pointers are statick and immutable except during testing. */ 34 | #ifdef JEMALLOC_JET 35 | # define JET_MUTABLE 36 | #else 37 | # define JET_MUTABLE const 38 | #endif 39 | 40 | #endif /* JEMALLOC_INTERNAL_MACROS_H */ 41 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/jemalloc_rename.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Name mangling for public symbols is controlled by --with-mangling and 3 | * --with-jemalloc-prefix. With default settings the je_ prefix is stripped by 4 | * these macro definitions. 5 | */ 6 | #ifndef JEMALLOC_NO_RENAME 7 | # define je_aligned_alloc je_aligned_alloc 8 | # define je_calloc je_calloc 9 | # define je_dallocx je_dallocx 10 | # define je_free je_free 11 | # define je_mallctl je_mallctl 12 | # define je_mallctlbymib je_mallctlbymib 13 | # define je_mallctlnametomib je_mallctlnametomib 14 | # define je_malloc je_malloc 15 | # define je_malloc_conf je_malloc_conf 16 | # define je_malloc_message je_malloc_message 17 | # define je_malloc_stats_print je_malloc_stats_print 18 | # define je_malloc_usable_size je_malloc_usable_size 19 | # define je_mallocx je_mallocx 20 | # define je_nallocx je_nallocx 21 | # define je_posix_memalign je_posix_memalign 22 | # define je_rallocx je_rallocx 23 | # define je_realloc je_realloc 24 | # define je_sallocx je_sallocx 25 | # define je_sdallocx je_sdallocx 26 | # define je_xallocx je_xallocx 27 | # define je_valloc je_valloc 28 | #endif 29 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/msvc_compat/strings.h: -------------------------------------------------------------------------------- 1 | #ifndef strings_h 2 | #define strings_h 3 | 4 | /* MSVC doesn't define ffs/ffsl. This dummy strings.h header is provided 5 | * for both */ 6 | #ifdef _MSC_VER 7 | # include 8 | # pragma intrinsic(_BitScanForward) 9 | static __forceinline int ffsl(long x) { 10 | unsigned long i; 11 | 12 | if (_BitScanForward(&i, x)) { 13 | return i + 1; 14 | } 15 | return 0; 16 | } 17 | 18 | static __forceinline int ffs(int x) { 19 | return ffsl(x); 20 | } 21 | 22 | # ifdef _M_X64 23 | # pragma intrinsic(_BitScanForward64) 24 | # endif 25 | 26 | static __forceinline int ffsll(unsigned __int64 x) { 27 | unsigned long i; 28 | #ifdef _M_X64 29 | if (_BitScanForward64(&i, x)) { 30 | return i + 1; 31 | } 32 | return 0; 33 | #else 34 | // Fallback for 32-bit build where 64-bit version not available 35 | // assuming little endian 36 | union { 37 | unsigned __int64 ll; 38 | unsigned long l[2]; 39 | } s; 40 | 41 | s.ll = x; 42 | 43 | if (_BitScanForward(&i, s.l[0])) { 44 | return i + 1; 45 | } else if(_BitScanForward(&i, s.l[1])) { 46 | return i + 33; 47 | } 48 | return 0; 49 | #endif 50 | } 51 | 52 | #else 53 | # define ffsll(x) __builtin_ffsll(x) 54 | # define ffsl(x) __builtin_ffsl(x) 55 | # define ffs(x) __builtin_ffs(x) 56 | #endif 57 | 58 | #endif /* strings_h */ 59 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/jemalloc_defs.h.in: -------------------------------------------------------------------------------- 1 | /* Defined if __attribute__((...)) syntax is supported. */ 2 | #undef JEMALLOC_HAVE_ATTR 3 | 4 | /* Defined if alloc_size attribute is supported. */ 5 | #undef JEMALLOC_HAVE_ATTR_ALLOC_SIZE 6 | 7 | /* Defined if format(gnu_printf, ...) attribute is supported. */ 8 | #undef JEMALLOC_HAVE_ATTR_FORMAT_GNU_PRINTF 9 | 10 | /* Defined if format(printf, ...) attribute is supported. */ 11 | #undef JEMALLOC_HAVE_ATTR_FORMAT_PRINTF 12 | 13 | /* 14 | * Define overrides for non-standard allocator-related functions if they are 15 | * present on the system. 16 | */ 17 | #undef JEMALLOC_OVERRIDE_MEMALIGN 18 | #undef JEMALLOC_OVERRIDE_VALLOC 19 | 20 | /* 21 | * At least Linux omits the "const" in: 22 | * 23 | * size_t malloc_usable_size(const void *ptr); 24 | * 25 | * Match the operating system's prototype. 26 | */ 27 | #undef JEMALLOC_USABLE_SIZE_CONST 28 | 29 | /* 30 | * If defined, specify throw() for the public function prototypes when compiling 31 | * with C++. The only justification for this is to match the prototypes that 32 | * glibc defines. 33 | */ 34 | #undef JEMALLOC_USE_CXX_THROW 35 | 36 | #ifdef _MSC_VER 37 | # ifdef _WIN64 38 | # define LG_SIZEOF_PTR_WIN 3 39 | # else 40 | # define LG_SIZEOF_PTR_WIN 2 41 | # endif 42 | #endif 43 | 44 | /* sizeof(void *) == 2^LG_SIZEOF_PTR. */ 45 | #undef LG_SIZEOF_PTR 46 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/large_externs.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_LARGE_EXTERNS_H 2 | #define JEMALLOC_INTERNAL_LARGE_EXTERNS_H 3 | 4 | void *large_malloc(tsdn_t *tsdn, arena_t *arena, size_t usize, bool zero); 5 | void *large_palloc(tsdn_t *tsdn, arena_t *arena, size_t usize, size_t alignment, 6 | bool zero); 7 | bool large_ralloc_no_move(tsdn_t *tsdn, extent_t *extent, size_t usize_min, 8 | size_t usize_max, bool zero); 9 | void *large_ralloc(tsdn_t *tsdn, arena_t *arena, extent_t *extent, size_t usize, 10 | size_t alignment, bool zero, tcache_t *tcache); 11 | 12 | typedef void (large_dalloc_junk_t)(void *, size_t); 13 | extern large_dalloc_junk_t *JET_MUTABLE large_dalloc_junk; 14 | 15 | typedef void (large_dalloc_maybe_junk_t)(void *, size_t); 16 | extern large_dalloc_maybe_junk_t *JET_MUTABLE large_dalloc_maybe_junk; 17 | 18 | void large_dalloc_prep_junked_locked(tsdn_t *tsdn, extent_t *extent); 19 | void large_dalloc_finish(tsdn_t *tsdn, extent_t *extent); 20 | void large_dalloc(tsdn_t *tsdn, extent_t *extent); 21 | size_t large_salloc(tsdn_t *tsdn, const extent_t *extent); 22 | prof_tctx_t *large_prof_tctx_get(tsdn_t *tsdn, const extent_t *extent); 23 | void large_prof_tctx_set(tsdn_t *tsdn, extent_t *extent, prof_tctx_t *tctx); 24 | void large_prof_tctx_reset(tsdn_t *tsdn, extent_t *extent); 25 | 26 | #endif /* JEMALLOC_INTERNAL_LARGE_EXTERNS_H */ 27 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/tsd_tls.h: -------------------------------------------------------------------------------- 1 | #ifdef JEMALLOC_INTERNAL_TSD_TLS_H 2 | #error This file should be included only once, by tsd.h. 3 | #endif 4 | #define JEMALLOC_INTERNAL_TSD_TLS_H 5 | 6 | extern __thread tsd_t tsd_tls; 7 | extern pthread_key_t tsd_tsd; 8 | extern bool tsd_booted; 9 | 10 | /* Initialization/cleanup. */ 11 | JEMALLOC_ALWAYS_INLINE bool 12 | tsd_boot0(void) { 13 | if (pthread_key_create(&tsd_tsd, &tsd_cleanup) != 0) { 14 | return true; 15 | } 16 | tsd_booted = true; 17 | return false; 18 | } 19 | 20 | JEMALLOC_ALWAYS_INLINE void 21 | tsd_boot1(void) { 22 | /* Do nothing. */ 23 | } 24 | 25 | JEMALLOC_ALWAYS_INLINE bool 26 | tsd_boot(void) { 27 | return tsd_boot0(); 28 | } 29 | 30 | JEMALLOC_ALWAYS_INLINE bool 31 | tsd_booted_get(void) { 32 | return tsd_booted; 33 | } 34 | 35 | JEMALLOC_ALWAYS_INLINE bool 36 | tsd_get_allocates(void) { 37 | return false; 38 | } 39 | 40 | /* Get/set. */ 41 | JEMALLOC_ALWAYS_INLINE tsd_t * 42 | tsd_get(bool init) { 43 | assert(tsd_booted); 44 | return &tsd_tls; 45 | } 46 | 47 | JEMALLOC_ALWAYS_INLINE void 48 | tsd_set(tsd_t *val) { 49 | assert(tsd_booted); 50 | if (likely(&tsd_tls != val)) { 51 | tsd_tls = (*val); 52 | } 53 | if (pthread_setspecific(tsd_tsd, (void *)(&tsd_tls)) != 0) { 54 | malloc_write(": Error setting tsd.\n"); 55 | if (opt_abort) { 56 | abort(); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2018, Daniel 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /DDMallocDetector/DDMallocDetector/ViewController.mm: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // DDMallocDetector 4 | // 5 | // Created by hzduanjiashun on 2018/3/30. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "MDStatisticsView.h" 11 | #import "MDInspectorWindow.h" 12 | 13 | @interface ViewController () 14 | 15 | @property (nonatomic, strong) MDStatisticsView *statView; 16 | 17 | @end 18 | 19 | @implementation ViewController 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | // [MDInspectorWindow enable]; 24 | // 25 | // self.statView = [[MDStatisticsView alloc] initWithFrame:self.view.bounds]; 26 | // [self.view addSubview:self.statView]; 27 | // 28 | // auto line = std::make_shared(); 29 | // line->push_back(2); 30 | // line->push_back(3); 31 | // line->push_back(6); 32 | // line->push_back(4); 33 | // line->push_back(9); 34 | // line->push_back(6); 35 | // line->push_back(1); 36 | // line->push_back(3); 37 | // 38 | // auto lines = std::make_shared(); 39 | // lines->emplace_back(line); 40 | // 41 | // [self.statView setLines:lines]; 42 | // [self.statView rebuildCanvasIfNeeded]; 43 | } 44 | 45 | 46 | - (void)didReceiveMemoryWarning { 47 | [super didReceiveMemoryWarning]; 48 | // Dispose of any resources that can be recreated. 49 | } 50 | 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/private_symbols.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Generate private_symbols[_jet].awk. 4 | # 5 | # Usage: private_symbols.sh * 6 | # 7 | # is typically "" or "_". 8 | 9 | sym_prefix=$1 10 | shift 11 | 12 | cat <' output. 35 | # 36 | # Handle lines like: 37 | # 0000000000000008 D opt_junk 38 | # 0000000000007574 T malloc_initialized 39 | (NF == 3 && $2 ~ /^[ABCDGRSTVW]$/ && !($3 in exported_symbols) && $3 ~ /^[A-Za-z0-9_]+$/) { 40 | print substr($3, 1+length(sym_prefix), length($3)-length(sym_prefix)) 41 | } 42 | 43 | # Process 'dumpbin /SYMBOLS ' output. 44 | # 45 | # Handle lines like: 46 | # 353 00008098 SECT4 notype External | opt_junk 47 | # 3F1 00000000 SECT7 notype () External | malloc_initialized 48 | ($3 ~ /^SECT[0-9]+/ && $(NF-2) == "External" && !($NF in exported_symbols)) { 49 | print $NF 50 | } 51 | EOF 52 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/ticker.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_TICKER_H 2 | #define JEMALLOC_INTERNAL_TICKER_H 3 | 4 | #include "jemalloc/internal/util.h" 5 | 6 | /** 7 | * A ticker makes it easy to count-down events until some limit. You 8 | * ticker_init the ticker to trigger every nticks events. You then notify it 9 | * that an event has occurred with calls to ticker_tick (or that nticks events 10 | * have occurred with a call to ticker_ticks), which will return true (and reset 11 | * the counter) if the countdown hit zero. 12 | */ 13 | 14 | typedef struct { 15 | int32_t tick; 16 | int32_t nticks; 17 | } ticker_t; 18 | 19 | static inline void 20 | ticker_init(ticker_t *ticker, int32_t nticks) { 21 | ticker->tick = nticks; 22 | ticker->nticks = nticks; 23 | } 24 | 25 | static inline void 26 | ticker_copy(ticker_t *ticker, const ticker_t *other) { 27 | *ticker = *other; 28 | } 29 | 30 | static inline int32_t 31 | ticker_read(const ticker_t *ticker) { 32 | return ticker->tick; 33 | } 34 | 35 | static inline bool 36 | ticker_ticks(ticker_t *ticker, int32_t nticks) { 37 | if (unlikely(ticker->tick < nticks)) { 38 | ticker->tick = ticker->nticks; 39 | return true; 40 | } 41 | ticker->tick -= nticks; 42 | return(false); 43 | } 44 | 45 | static inline bool 46 | ticker_tick(ticker_t *ticker) { 47 | return ticker_ticks(ticker, 1); 48 | } 49 | 50 | #endif /* JEMALLOC_INTERNAL_TICKER_H */ 51 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/tsd_malloc_thread_cleanup.h: -------------------------------------------------------------------------------- 1 | #ifdef JEMALLOC_INTERNAL_TSD_MALLOC_THREAD_CLEANUP_H 2 | #error This file should be included only once, by tsd.h. 3 | #endif 4 | #define JEMALLOC_INTERNAL_TSD_MALLOC_THREAD_CLEANUP_H 5 | 6 | extern __thread tsd_t tsd_tls; 7 | extern __thread bool tsd_initialized; 8 | extern bool tsd_booted; 9 | 10 | /* Initialization/cleanup. */ 11 | JEMALLOC_ALWAYS_INLINE bool 12 | tsd_cleanup_wrapper(void) { 13 | if (tsd_initialized) { 14 | tsd_initialized = false; 15 | tsd_cleanup(&tsd_tls); 16 | } 17 | return tsd_initialized; 18 | } 19 | 20 | JEMALLOC_ALWAYS_INLINE bool 21 | tsd_boot0(void) { 22 | malloc_tsd_cleanup_register(&tsd_cleanup_wrapper); 23 | tsd_booted = true; 24 | return false; 25 | } 26 | 27 | JEMALLOC_ALWAYS_INLINE void 28 | tsd_boot1(void) { 29 | /* Do nothing. */ 30 | } 31 | 32 | JEMALLOC_ALWAYS_INLINE bool 33 | tsd_boot(void) { 34 | return tsd_boot0(); 35 | } 36 | 37 | JEMALLOC_ALWAYS_INLINE bool 38 | tsd_booted_get(void) { 39 | return tsd_booted; 40 | } 41 | 42 | JEMALLOC_ALWAYS_INLINE bool 43 | tsd_get_allocates(void) { 44 | return false; 45 | } 46 | 47 | /* Get/set. */ 48 | JEMALLOC_ALWAYS_INLINE tsd_t * 49 | tsd_get(bool init) { 50 | assert(tsd_booted); 51 | return &tsd_tls; 52 | } 53 | JEMALLOC_ALWAYS_INLINE void 54 | tsd_set(tsd_t *val) { 55 | assert(tsd_booted); 56 | if (likely(&tsd_tls != val)) { 57 | tsd_tls = (*val); 58 | } 59 | tsd_initialized = true; 60 | } 61 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/background_thread_externs.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_BACKGROUND_THREAD_EXTERNS_H 2 | #define JEMALLOC_INTERNAL_BACKGROUND_THREAD_EXTERNS_H 3 | 4 | extern bool opt_background_thread; 5 | extern malloc_mutex_t background_thread_lock; 6 | extern atomic_b_t background_thread_enabled_state; 7 | extern size_t n_background_threads; 8 | extern background_thread_info_t *background_thread_info; 9 | extern bool can_enable_background_thread; 10 | 11 | bool background_thread_create(tsd_t *tsd, unsigned arena_ind); 12 | bool background_threads_enable(tsd_t *tsd); 13 | bool background_threads_disable(tsd_t *tsd); 14 | void background_thread_interval_check(tsdn_t *tsdn, arena_t *arena, 15 | arena_decay_t *decay, size_t npages_new); 16 | void background_thread_prefork0(tsdn_t *tsdn); 17 | void background_thread_prefork1(tsdn_t *tsdn); 18 | void background_thread_postfork_parent(tsdn_t *tsdn); 19 | void background_thread_postfork_child(tsdn_t *tsdn); 20 | bool background_thread_stats_read(tsdn_t *tsdn, 21 | background_thread_stats_t *stats); 22 | void background_thread_ctl_init(tsdn_t *tsdn); 23 | 24 | #ifdef JEMALLOC_PTHREAD_CREATE_WRAPPER 25 | extern int pthread_create_wrapper(pthread_t *__restrict, const pthread_attr_t *, 26 | void *(*)(void *), void *__restrict); 27 | #endif 28 | bool background_thread_boot0(void); 29 | bool background_thread_boot1(tsdn_t *tsdn); 30 | 31 | #endif /* JEMALLOC_INTERNAL_BACKGROUND_THREAD_EXTERNS_H */ 32 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/nstime.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_NSTIME_H 2 | #define JEMALLOC_INTERNAL_NSTIME_H 3 | 4 | /* Maximum supported number of seconds (~584 years). */ 5 | #define NSTIME_SEC_MAX KQU(18446744072) 6 | #define NSTIME_ZERO_INITIALIZER {0} 7 | 8 | typedef struct { 9 | uint64_t ns; 10 | } nstime_t; 11 | 12 | void nstime_init(nstime_t *time, uint64_t ns); 13 | void nstime_init2(nstime_t *time, uint64_t sec, uint64_t nsec); 14 | uint64_t nstime_ns(const nstime_t *time); 15 | uint64_t nstime_sec(const nstime_t *time); 16 | uint64_t nstime_msec(const nstime_t *time); 17 | uint64_t nstime_nsec(const nstime_t *time); 18 | void nstime_copy(nstime_t *time, const nstime_t *source); 19 | int nstime_compare(const nstime_t *a, const nstime_t *b); 20 | void nstime_add(nstime_t *time, const nstime_t *addend); 21 | void nstime_iadd(nstime_t *time, uint64_t addend); 22 | void nstime_subtract(nstime_t *time, const nstime_t *subtrahend); 23 | void nstime_isubtract(nstime_t *time, uint64_t subtrahend); 24 | void nstime_imultiply(nstime_t *time, uint64_t multiplier); 25 | void nstime_idivide(nstime_t *time, uint64_t divisor); 26 | uint64_t nstime_divide(const nstime_t *time, const nstime_t *divisor); 27 | 28 | typedef bool (nstime_monotonic_t)(void); 29 | extern nstime_monotonic_t *JET_MUTABLE nstime_monotonic; 30 | 31 | typedef bool (nstime_update_t)(nstime_t *); 32 | extern nstime_update_t *JET_MUTABLE nstime_update; 33 | 34 | #endif /* JEMALLOC_INTERNAL_NSTIME_H */ 35 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/jemalloc_mangle.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | public_symbols_txt=$1 4 | symbol_prefix=$2 5 | 6 | cat < 13 | #include 14 | 15 | namespace MD { 16 | class Color { 17 | public: 18 | typedef CGFloat color_type[4]; 19 | 20 | Color() : color_{0, 0, 0, 1} { }; 21 | Color(Float r, Float g, Float b, Float a = 1) : color_{r, g, b, a} { } 22 | Color(const Color& c) { *this = c; } 23 | Color(const Color&& c) { *this = c; } 24 | 25 | Float red() const { return color_[0]; } 26 | Float green() const { return color_[1]; } 27 | Float blue() const { return color_[2]; } 28 | Float alpha() const { return color_[3]; } 29 | void setComponents(Float r, Float g, Float b, Float a = 1) { 30 | color_[0] = r; 31 | color_[1] = g; 32 | color_[2] = b; 33 | color_[3] = a; 34 | } 35 | 36 | Color& operator= (const Color& c) { 37 | color_[0] = c.color_[0]; color_[1] = c.color_[1]; color_[2] = c.color_[2]; color_[3] = c.color_[3]; 38 | return *this; 39 | } 40 | 41 | operator const CGFloat* () { 42 | return color_; 43 | } 44 | 45 | private: 46 | color_type color_; 47 | }; 48 | } 49 | 50 | 51 | #endif /* Color_h */ 52 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/Controller/MDControlViewController.mm: -------------------------------------------------------------------------------- 1 | // 2 | // MDControlViewController.m 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/3/31. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import "MDControlViewController.h" 10 | #import "MDInspectorIcon.h" 11 | #import "MemoryDetector.hpp" 12 | #import "MDAnalysisGroupTableViewController.h" 13 | 14 | @interface MDControlViewController () 15 | @property (nonatomic, strong) MDInspectorIcon *icon; 16 | @end 17 | 18 | @implementation MDControlViewController 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | 23 | self.icon = [[MDInspectorIcon alloc] initWithFrame:CGRectMake(0, 100, 40, 40)]; 24 | [self.icon addTarget:self action:@selector(onIcon:) forControlEvents:UIControlEventTouchUpInside]; 25 | [self.view addSubview:self.icon]; 26 | } 27 | 28 | - (void)viewWillAppear:(BOOL)animated { 29 | [super viewWillAppear:animated]; 30 | self.navigationController.navigationBarHidden = YES; 31 | } 32 | 33 | - (void)viewDidDisappear:(BOOL)animated { 34 | [super viewDidDisappear:animated]; 35 | self.navigationController.navigationBarHidden = NO; 36 | } 37 | 38 | - (void)onIcon:(id)sender { 39 | if (MD::MemoryDetector::GetInstance()->Running()) { 40 | MD::MemoryDetector::GetInstance()->Stop(); 41 | } 42 | 43 | MDAnalysisGroupTableViewController *vc = [MDAnalysisGroupTableViewController new]; 44 | [self.navigationController pushViewController:vc animated:YES]; 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/assert.h: -------------------------------------------------------------------------------- 1 | #include "jemalloc/internal/malloc_io.h" 2 | #include "jemalloc/internal/util.h" 3 | 4 | /* 5 | * Define a custom assert() in order to reduce the chances of deadlock during 6 | * assertion failure. 7 | */ 8 | #ifndef assert 9 | #define assert(e) do { \ 10 | if (unlikely(config_debug && !(e))) { \ 11 | malloc_printf( \ 12 | ": %s:%d: Failed assertion: \"%s\"\n", \ 13 | __FILE__, __LINE__, #e); \ 14 | abort(); \ 15 | } \ 16 | } while (0) 17 | #endif 18 | 19 | #ifndef not_reached 20 | #define not_reached() do { \ 21 | if (config_debug) { \ 22 | malloc_printf( \ 23 | ": %s:%d: Unreachable code reached\n", \ 24 | __FILE__, __LINE__); \ 25 | abort(); \ 26 | } \ 27 | unreachable(); \ 28 | } while (0) 29 | #endif 30 | 31 | #ifndef not_implemented 32 | #define not_implemented() do { \ 33 | if (config_debug) { \ 34 | malloc_printf(": %s:%d: Not implemented\n", \ 35 | __FILE__, __LINE__); \ 36 | abort(); \ 37 | } \ 38 | } while (0) 39 | #endif 40 | 41 | #ifndef assert_not_implemented 42 | #define assert_not_implemented(e) do { \ 43 | if (unlikely(config_debug && !(e))) { \ 44 | not_implemented(); \ 45 | } \ 46 | } while (0) 47 | #endif 48 | 49 | /* Use to assert a particular configuration, e.g., cassert(config_debug). */ 50 | #ifndef cassert 51 | #define cassert(c) do { \ 52 | if (unlikely(!(c))) { \ 53 | not_reached(); \ 54 | } \ 55 | } while (0) 56 | #endif 57 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/base/Allocator.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Allocator.hpp 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/28. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #ifndef Allocator_hpp 10 | #define Allocator_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace MD { 19 | 20 | template 21 | class VMAllocator : public std::allocator<_Tp> { 22 | public: 23 | typedef typename std::allocator<_Tp>::pointer pointer; 24 | typedef typename std::allocator<_Tp>::size_type size_type; 25 | 26 | pointer allocate(size_type __n, std::allocator::const_pointer = 0) 27 | { 28 | size_type n = round_page(__n * sizeof(_Tp)); 29 | vm_address_t addr; 30 | kern_return_t rt = vm_allocate(mach_task_self(), &addr, n, VM_FLAGS_ANYWHERE); 31 | if (rt != KERN_SUCCESS) { 32 | throw std::bad_alloc(); 33 | } 34 | vm_protect(mach_task_self(), addr, n, true, VM_PROT_READ|VM_PROT_WRITE); 35 | return reinterpret_cast(addr); 36 | } 37 | void deallocate(pointer __p, size_type __n) noexcept 38 | { 39 | size_type n = round_page(__n); 40 | kern_return_t rt = vm_deallocate(mach_task_self(), reinterpret_cast(__p), n); 41 | if (rt != KERN_SUCCESS) { 42 | 43 | } 44 | } 45 | }; 46 | } 47 | 48 | #endif /* Allocator_hpp */ 49 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/private_symbols.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env awk -f 2 | 3 | BEGIN { 4 | sym_prefix = "_" 5 | split("\ 6 | _je_aligned_alloc \ 7 | _je_calloc \ 8 | _je_dallocx \ 9 | _je_free \ 10 | _je_mallctl \ 11 | _je_mallctlbymib \ 12 | _je_mallctlnametomib \ 13 | _je_malloc \ 14 | _je_malloc_conf \ 15 | _je_malloc_message \ 16 | _je_malloc_stats_print \ 17 | _je_malloc_usable_size \ 18 | _je_mallocx \ 19 | _je_nallocx \ 20 | _je_posix_memalign \ 21 | _je_rallocx \ 22 | _je_realloc \ 23 | _je_sallocx \ 24 | _je_sdallocx \ 25 | _je_xallocx \ 26 | _je_valloc \ 27 | _pthread_create \ 28 | ", exported_symbol_names) 29 | # Store exported symbol names as keys in exported_symbols. 30 | for (i in exported_symbol_names) { 31 | exported_symbols[exported_symbol_names[i]] = 1 32 | } 33 | } 34 | 35 | # Process 'nm -a ' output. 36 | # 37 | # Handle lines like: 38 | # 0000000000000008 D opt_junk 39 | # 0000000000007574 T malloc_initialized 40 | (NF == 3 && $2 ~ /^[ABCDGRSTVW]$/ && !($3 in exported_symbols) && $3 ~ /^[A-Za-z0-9_]+$/) { 41 | print substr($3, 1+length(sym_prefix), length($3)-length(sym_prefix)) 42 | } 43 | 44 | # Process 'dumpbin /SYMBOLS ' output. 45 | # 46 | # Handle lines like: 47 | # 353 00008098 SECT4 notype External | opt_junk 48 | # 3F1 00000000 SECT7 notype () External | malloc_initialized 49 | ($3 ~ /^SECT[0-9]+/ && $(NF-2) == "External" && !($NF in exported_symbols)) { 50 | print $NF 51 | } 52 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/base/ThreadLocal.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ThreadLocal.hpp 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/27. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #ifndef ThreadLocal_hpp 10 | #define ThreadLocal_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | namespace MD { 17 | // template 18 | // static void Deallocator(void *p) { 19 | // delete p; 20 | // } 21 | 22 | template 23 | struct Constructor { 24 | T *operator()() { 25 | return new T(); 26 | } 27 | }; 28 | 29 | template> 30 | class ThreadLocal { 31 | public: 32 | typedef _Tp value_type; 33 | ThreadLocal(pthread_key_t key) : key_(key) {} 34 | 35 | value_type* value() { 36 | pthread_key_t key = key_; 37 | value_type* value = reinterpret_cast(pthread_getspecific(key)); 38 | if (value == nullptr) { 39 | value = _Constructor()();// new value_type(); 40 | pthread_setspecific(key, reinterpret_cast(value)); 41 | } 42 | return value; 43 | } 44 | 45 | value_type* operator->() { return value(); } 46 | 47 | private: 48 | 49 | static void deallocate(void *p) { 50 | value_type *v = reinterpret_cast(p); 51 | delete v; 52 | } 53 | 54 | pthread_key_t key_; 55 | }; 56 | } 57 | 58 | #endif /* ThreadLocal_hpp */ 59 | -------------------------------------------------------------------------------- /JemallocDemo/JemallocDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /DDMallocDetector/DDMallocDetector/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | .vscode/ 25 | 26 | ## Obj-C/Swift specific 27 | *.hmap 28 | *.ipa 29 | *.dSYM.zip 30 | *.dSYM 31 | 32 | # CocoaPods 33 | # 34 | # We recommend against adding the Pods directory to your .gitignore. However 35 | # you should judge for yourself, the pros and cons are mentioned at: 36 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 37 | # 38 | # Pods/ 39 | 40 | # Carthage 41 | # 42 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 43 | # Carthage/Checkouts 44 | 45 | Carthage/Build 46 | 47 | # fastlane 48 | # 49 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 50 | # screenshots whenever they are needed. 51 | # For more information about the recommended setup visit: 52 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 53 | 54 | fastlane/report.xml 55 | fastlane/Preview.html 56 | fastlane/screenshots 57 | fastlane/test_output 58 | 59 | # Code Injection 60 | # 61 | # After new code Injection tools there's a generated folder /iOSInjectionProject 62 | # https://github.com/johnno1962/injectionforxcode 63 | 64 | iOSInjectionProject/ 65 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/private_symbols_jet.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env awk -f 2 | 3 | BEGIN { 4 | sym_prefix = "_" 5 | split("\ 6 | _jet_aligned_alloc \ 7 | _jet_calloc \ 8 | _jet_dallocx \ 9 | _jet_free \ 10 | _jet_mallctl \ 11 | _jet_mallctlbymib \ 12 | _jet_mallctlnametomib \ 13 | _jet_malloc \ 14 | _jet_malloc_conf \ 15 | _jet_malloc_message \ 16 | _jet_malloc_stats_print \ 17 | _jet_malloc_usable_size \ 18 | _jet_mallocx \ 19 | _jet_nallocx \ 20 | _jet_posix_memalign \ 21 | _jet_rallocx \ 22 | _jet_realloc \ 23 | _jet_sallocx \ 24 | _jet_sdallocx \ 25 | _jet_xallocx \ 26 | _jet_valloc \ 27 | _pthread_create \ 28 | ", exported_symbol_names) 29 | # Store exported symbol names as keys in exported_symbols. 30 | for (i in exported_symbol_names) { 31 | exported_symbols[exported_symbol_names[i]] = 1 32 | } 33 | } 34 | 35 | # Process 'nm -a ' output. 36 | # 37 | # Handle lines like: 38 | # 0000000000000008 D opt_junk 39 | # 0000000000007574 T malloc_initialized 40 | (NF == 3 && $2 ~ /^[ABCDGRSTVW]$/ && !($3 in exported_symbols) && $3 ~ /^[A-Za-z0-9_]+$/) { 41 | print substr($3, 1+length(sym_prefix), length($3)-length(sym_prefix)) 42 | } 43 | 44 | # Process 'dumpbin /SYMBOLS ' output. 45 | # 46 | # Handle lines like: 47 | # 353 00008098 SECT4 notype External | opt_junk 48 | # 3F1 00000000 SECT7 notype () External | malloc_initialized 49 | ($3 ~ /^SECT[0-9]+/ && $(NF-2) == "External" && !($NF in exported_symbols)) { 50 | print $NF 51 | } 52 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/base_structs.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_BASE_STRUCTS_H 2 | #define JEMALLOC_INTERNAL_BASE_STRUCTS_H 3 | 4 | #include "jemalloc/internal/jemalloc_internal_types.h" 5 | #include "jemalloc/internal/mutex.h" 6 | #include "jemalloc/internal/size_classes.h" 7 | 8 | /* Embedded at the beginning of every block of base-managed virtual memory. */ 9 | struct base_block_s { 10 | /* Total size of block's virtual memory mapping. */ 11 | size_t size; 12 | 13 | /* Next block in list of base's blocks. */ 14 | base_block_t *next; 15 | 16 | /* Tracks unused trailing space. */ 17 | extent_t extent; 18 | }; 19 | 20 | struct base_s { 21 | /* Associated arena's index within the arenas array. */ 22 | unsigned ind; 23 | 24 | /* 25 | * User-configurable extent hook functions. Points to an 26 | * extent_hooks_t. 27 | */ 28 | atomic_p_t extent_hooks; 29 | 30 | /* Protects base_alloc() and base_stats_get() operations. */ 31 | malloc_mutex_t mtx; 32 | 33 | /* 34 | * Most recent size class in the series of increasingly large base 35 | * extents. Logarithmic spacing between subsequent allocations ensures 36 | * that the total number of distinct mappings remains small. 37 | */ 38 | pszind_t pind_last; 39 | 40 | /* Serial number generation state. */ 41 | size_t extent_sn_next; 42 | 43 | /* Chain of all blocks associated with base. */ 44 | base_block_t *blocks; 45 | 46 | /* Heap of extents that track unused trailing space within blocks. */ 47 | extent_heap_t avail[NSIZES]; 48 | 49 | /* Stats, only maintained if config_stats. */ 50 | size_t allocated; 51 | size_t resident; 52 | size_t mapped; 53 | }; 54 | 55 | #endif /* JEMALLOC_INTERNAL_BASE_STRUCTS_H */ 56 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/graph/MDStatisticsView.mm: -------------------------------------------------------------------------------- 1 | // 2 | // MDStatisticsView.m 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/29. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import "MDStatisticsView.h" 10 | #include "StrokeLayer.hpp" 11 | #include "AxisLayer.hpp" 12 | 13 | @interface MDStatisticsView () { 14 | std::shared_ptr _lines; 15 | 16 | } 17 | 18 | @end 19 | 20 | @implementation MDStatisticsView 21 | 22 | - (instancetype)initWithFrame:(CGRect)frame 23 | { 24 | self = [super initWithFrame:frame]; 25 | if (self) { 26 | _xAxis->setEdges(MD::Edges(20, 100, 20, 100)); 27 | _xAxis->setTriangleHeight(10); 28 | 29 | _yAxis->setEdges(MD::Edges(20, 100, 20, 100)); 30 | } 31 | return self; 32 | } 33 | 34 | - (void)rebuildCanvas { 35 | [super rebuildCanvas]; 36 | auto& canvas = self.canvas; 37 | _contentLayer->setEdges(MD::Edges(20, 100, 20, 100)); 38 | _contentLayer->setBackgroundColor({0.2, 0.2, 0.2}); 39 | if (_lines) { 40 | std::for_each(_lines->begin(), _lines->end(), [&](std::shared_ptr& line) { 41 | auto layer = std::make_shared(); 42 | layer->setEdges(MD::Edges(20, 100, 20, 100)); 43 | layer->setColor(1, 0, 0); 44 | layer->setXRange({0, CGFloat(line->size())}); 45 | layer->setYRange({0, 10}); 46 | layer->setLine(line); 47 | canvas->AddLayer(layer); 48 | }); 49 | } 50 | } 51 | 52 | - (void)setLines:(std::shared_ptr)lines { 53 | _lines = lines; 54 | 55 | [self setNeedsRebuildCanvas]; 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /JemallocDemo/JemallocDemo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/arena_inlines_a.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_ARENA_INLINES_A_H 2 | #define JEMALLOC_INTERNAL_ARENA_INLINES_A_H 3 | 4 | static inline unsigned 5 | arena_ind_get(const arena_t *arena) { 6 | return base_ind_get(arena->base); 7 | } 8 | 9 | static inline void 10 | arena_internal_add(arena_t *arena, size_t size) { 11 | atomic_fetch_add_zu(&arena->stats.internal, size, ATOMIC_RELAXED); 12 | } 13 | 14 | static inline void 15 | arena_internal_sub(arena_t *arena, size_t size) { 16 | atomic_fetch_sub_zu(&arena->stats.internal, size, ATOMIC_RELAXED); 17 | } 18 | 19 | static inline size_t 20 | arena_internal_get(arena_t *arena) { 21 | return atomic_load_zu(&arena->stats.internal, ATOMIC_RELAXED); 22 | } 23 | 24 | static inline bool 25 | arena_prof_accum(tsdn_t *tsdn, arena_t *arena, uint64_t accumbytes) { 26 | cassert(config_prof); 27 | 28 | if (likely(prof_interval == 0)) { 29 | return false; 30 | } 31 | 32 | return prof_accum_add(tsdn, &arena->prof_accum, accumbytes); 33 | } 34 | 35 | static inline void 36 | percpu_arena_update(tsd_t *tsd, unsigned cpu) { 37 | assert(have_percpu_arena); 38 | arena_t *oldarena = tsd_arena_get(tsd); 39 | assert(oldarena != NULL); 40 | unsigned oldind = arena_ind_get(oldarena); 41 | 42 | if (oldind != cpu) { 43 | unsigned newind = cpu; 44 | arena_t *newarena = arena_get(tsd_tsdn(tsd), newind, true); 45 | assert(newarena != NULL); 46 | 47 | /* Set new arena/tcache associations. */ 48 | arena_migrate(tsd, oldind, newind); 49 | tcache_t *tcache = tcache_get(tsd); 50 | if (tcache != NULL) { 51 | tcache_arena_reassociate(tsd_tsdn(tsd), tcache, 52 | newarena); 53 | } 54 | } 55 | } 56 | 57 | #endif /* JEMALLOC_INTERNAL_ARENA_INLINES_A_H */ 58 | -------------------------------------------------------------------------------- /DDMallocDetector/DDMallocDetector/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/detector/MemoryDetector.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // MemoryDetector.cpp 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/27. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include "MemoryDetector.hpp" 12 | 13 | 14 | extern "C" malloc_zone_t **malloc_zones; 15 | extern "C" int32_t malloc_num_zones; 16 | 17 | typedef void (malloc_logger_t)(uint32_t type, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t result, uint32_t num_hot_frames_to_skip); 18 | 19 | extern "C" malloc_logger_t *__syscall_logger; 20 | 21 | namespace MD { 22 | static void malloc_logger_func(uint32_t type, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t result, uint32_t num_hot_frames_to_skip) { 23 | MemoryDetector::GetInstance()->AddSyscallCount(); 24 | } 25 | 26 | // Should init at start, do not need lock. 27 | MemoryDetector *MemoryDetector::GetInstance() { 28 | static MemoryDetector *detector = nullptr; 29 | if (detector == nullptr) { 30 | detector = new MemoryDetector; 31 | } 32 | return detector; 33 | } 34 | 35 | MemoryDetector::MemoryDetector() : max_data_count_(MAX_DATA_COUNT) { 36 | __syscall_logger = malloc_logger_func; 37 | } 38 | 39 | void MemoryDetector::DetectorAllZones() noexcept { 40 | for (int i = 0; i < malloc_num_zones; i++) { 41 | malloc_zone_t *z = malloc_zones[i]; 42 | wrap_zones().WrapZone(z); 43 | } 44 | } 45 | 46 | void MemoryDetector::DetectorDefaultZone() noexcept { 47 | malloc_zone_t *z = malloc_zones[0]; 48 | wrap_zones().WrapZone(z); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/control/MDInspectorWindow.mm: -------------------------------------------------------------------------------- 1 | // 2 | // MDInspectorWindow.m 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/3/31. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import "MDInspectorWindow.h" 10 | #import "MDViewMacros.h" 11 | #import "MDControlViewController.h" 12 | 13 | @implementation MDInspectorWindow 14 | 15 | static MDInspectorWindow *g_window; 16 | static __weak UIView *g_untouchableView; 17 | 18 | + (instancetype)sharedWindow { 19 | MDViewAssertMainThread(); 20 | return g_window; 21 | } 22 | 23 | + (BOOL)isEnabled { 24 | MDViewAssertMainThread(); 25 | return g_window != nil; 26 | } 27 | 28 | + (void)enable { 29 | MDViewAssertMainThread(); 30 | g_window = [[self alloc] initWithFrame:UIScreen.mainScreen.bounds]; 31 | MDControlViewController *vc = [MDControlViewController new]; 32 | UINavigationController *navi = [[UINavigationController alloc] initWithRootViewController:vc]; 33 | navi.navigationBarHidden = YES; 34 | g_window.rootViewController = navi; 35 | g_window.windowLevel = UIWindowLevelStatusBar - 1; 36 | g_window.hidden = NO; 37 | 38 | g_untouchableView = vc.view; 39 | } 40 | 41 | + (void)disable { 42 | g_window.hidden = YES; 43 | g_window = nil; 44 | } 45 | 46 | - (instancetype)initWithFrame:(CGRect)frame 47 | { 48 | self = [super initWithFrame:frame]; 49 | if (self) { 50 | } 51 | return self; 52 | } 53 | 54 | - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { 55 | UIView *view = [super hitTest:point withEvent:event]; 56 | if (view != self && view != g_untouchableView) { 57 | return view; 58 | } 59 | return nil; 60 | } 61 | 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/analysis/AnalysisHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // AnalysisHelper.h 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/4/3. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #ifndef AnalysisHelper_h 10 | #define AnalysisHelper_h 11 | 12 | #include 13 | #include 14 | 15 | namespace MD { 16 | 17 | template 18 | struct StepByLog { 19 | static_assert(_Step > 1, ""); 20 | static_assert(_Start >= 1, ""); 21 | 22 | std::vector operator()(std::size_t min, std::size_t max) { 23 | assert(max > min); 24 | std::vector steps; 25 | std::size_t value = _Start; 26 | while(value < min) value *= _Step; 27 | steps.push_back(value); 28 | while (true) { 29 | value *= _Step; 30 | if (value > max) break; 31 | steps.push_back(value); 32 | }; 33 | return steps; 34 | } 35 | }; 36 | 37 | template 38 | struct StepByLinear { 39 | static_assert(_Step > 0, ""); 40 | 41 | std::vector operator()(std::size_t min, std::size_t max) { 42 | assert(max > min); 43 | std::vector steps; 44 | std::size_t value = min; 45 | steps.push_back(value); 46 | while (true) { 47 | value += _Step; 48 | if (value > max) break; 49 | steps.push_back(value); 50 | } 51 | return steps; 52 | } 53 | }; 54 | } 55 | 56 | #endif /* AnalysisHelper_h */ 57 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/drawable/CanvasLayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CanvasLayer.hpp 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/29. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #ifndef CanvasLayer_hpp 10 | #define CanvasLayer_hpp 11 | 12 | #include 13 | #include 14 | #include "FillLayer.hpp" 15 | 16 | namespace MD { 17 | class CanvasLayer : public FillLayer { 18 | public: 19 | typedef FillLayer super; 20 | 21 | void Draw() override; 22 | 23 | void Draw(CGContextRef ctx); 24 | 25 | 26 | Rect frame() const { 27 | return rect_; 28 | } 29 | 30 | void setFrame(Rect rect) { 31 | rect_ = rect; 32 | } 33 | 34 | Size size() const { 35 | return rect_.size; 36 | } 37 | 38 | void setSize(Size size) { 39 | rect_.size = size; 40 | } 41 | 42 | Float width() const { 43 | return rect_.size.width; 44 | } 45 | 46 | Float height() const { 47 | return rect_.size.height; 48 | } 49 | 50 | Point origin() const { 51 | return rect_.origin; 52 | } 53 | 54 | void setOrigin(Point point) { 55 | rect_.origin = point; 56 | } 57 | 58 | CGContextRef context() { 59 | return ctx_; 60 | } 61 | protected: 62 | bool isCanvas() const override { 63 | return true; 64 | } 65 | 66 | private: 67 | Rect rect_; 68 | CGContextRef ctx_; 69 | }; 70 | } 71 | 72 | #endif /* CanvasLayer_hpp */ 73 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/drawable/Layer.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Layer.hpp 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/28. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #ifndef Layer_hpp 10 | #define Layer_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include "Geometry.hpp" 16 | #include "Drawable.hpp" 17 | #include "Color.h" 18 | #include "../base/Macros.h" 19 | 20 | namespace MD { 21 | class CanvasLayer; 22 | 23 | class Layer : public Drawable { 24 | public: 25 | Layer() {} 26 | 27 | Edges edges() const { return edges_; } 28 | void setEdges(const Edges& e) { 29 | edges_ = e; 30 | } 31 | void setEdges(const Edges&& e) { 32 | edges_ = e; 33 | } 34 | 35 | Layer* superLayer() const { 36 | return super_layer_; 37 | } 38 | 39 | void AddLayer(std::shared_ptr layer) noexcept; 40 | void RemoveLayer(Layer* layer) noexcept; 41 | void RemoveLayer(std::shared_ptr& layer) noexcept; 42 | void RemoveLayers() noexcept; 43 | 44 | void Draw() override; 45 | 46 | virtual ~Layer() { 47 | RemoveLayers(); 48 | } 49 | 50 | protected: 51 | virtual bool isCanvas() const { 52 | return false; 53 | } 54 | 55 | CanvasLayer* canvas() const; 56 | Rect absoluteFrame() const; 57 | 58 | private: 59 | MD_NO_COPY(Layer); 60 | 61 | Edges edges_; 62 | Layer *super_layer_ = nullptr; 63 | std::vector > sub_layers_; 64 | }; 65 | } 66 | 67 | #endif /* Layer_hpp */ 68 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/arena_types.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_ARENA_TYPES_H 2 | #define JEMALLOC_INTERNAL_ARENA_TYPES_H 3 | 4 | /* Maximum number of regions in one slab. */ 5 | #define LG_SLAB_MAXREGS (LG_PAGE - LG_TINY_MIN) 6 | #define SLAB_MAXREGS (1U << LG_SLAB_MAXREGS) 7 | 8 | /* Default decay times in milliseconds. */ 9 | #define DIRTY_DECAY_MS_DEFAULT ZD(10 * 1000) 10 | #define MUZZY_DECAY_MS_DEFAULT ZD(10 * 1000) 11 | /* Number of event ticks between time checks. */ 12 | #define DECAY_NTICKS_PER_UPDATE 1000 13 | 14 | typedef struct arena_slab_data_s arena_slab_data_t; 15 | typedef struct arena_bin_info_s arena_bin_info_t; 16 | typedef struct arena_decay_s arena_decay_t; 17 | typedef struct arena_bin_s arena_bin_t; 18 | typedef struct arena_s arena_t; 19 | typedef struct arena_tdata_s arena_tdata_t; 20 | typedef struct alloc_ctx_s alloc_ctx_t; 21 | 22 | typedef enum { 23 | percpu_arena_mode_names_base = 0, /* Used for options processing. */ 24 | 25 | /* 26 | * *_uninit are used only during bootstrapping, and must correspond 27 | * to initialized variant plus percpu_arena_mode_enabled_base. 28 | */ 29 | percpu_arena_uninit = 0, 30 | per_phycpu_arena_uninit = 1, 31 | 32 | /* All non-disabled modes must come after percpu_arena_disabled. */ 33 | percpu_arena_disabled = 2, 34 | 35 | percpu_arena_mode_names_limit = 3, /* Used for options processing. */ 36 | percpu_arena_mode_enabled_base = 3, 37 | 38 | percpu_arena = 3, 39 | per_phycpu_arena = 4 /* Hyper threads share arena. */ 40 | } percpu_arena_mode_t; 41 | 42 | #define PERCPU_ARENA_ENABLED(m) ((m) >= percpu_arena_mode_enabled_base) 43 | #define PERCPU_ARENA_DEFAULT percpu_arena_disabled 44 | 45 | #endif /* JEMALLOC_INTERNAL_ARENA_TYPES_H */ 46 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/util.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_UTIL_H 2 | #define JEMALLOC_INTERNAL_UTIL_H 3 | 4 | #define UTIL_INLINE static inline 5 | 6 | /* Junk fill patterns. */ 7 | #ifndef JEMALLOC_ALLOC_JUNK 8 | # define JEMALLOC_ALLOC_JUNK ((uint8_t)0xa5) 9 | #endif 10 | #ifndef JEMALLOC_FREE_JUNK 11 | # define JEMALLOC_FREE_JUNK ((uint8_t)0x5a) 12 | #endif 13 | 14 | /* 15 | * Wrap a cpp argument that contains commas such that it isn't broken up into 16 | * multiple arguments. 17 | */ 18 | #define JEMALLOC_ARG_CONCAT(...) __VA_ARGS__ 19 | 20 | /* cpp macro definition stringification. */ 21 | #define STRINGIFY_HELPER(x) #x 22 | #define STRINGIFY(x) STRINGIFY_HELPER(x) 23 | 24 | /* 25 | * Silence compiler warnings due to uninitialized values. This is used 26 | * wherever the compiler fails to recognize that the variable is never used 27 | * uninitialized. 28 | */ 29 | #define JEMALLOC_CC_SILENCE_INIT(v) = v 30 | 31 | #ifdef __GNUC__ 32 | # define likely(x) __builtin_expect(!!(x), 1) 33 | # define unlikely(x) __builtin_expect(!!(x), 0) 34 | #else 35 | # define likely(x) !!(x) 36 | # define unlikely(x) !!(x) 37 | #endif 38 | 39 | #if !defined(JEMALLOC_INTERNAL_UNREACHABLE) 40 | # error JEMALLOC_INTERNAL_UNREACHABLE should have been defined by configure 41 | #endif 42 | 43 | #define unreachable() JEMALLOC_INTERNAL_UNREACHABLE() 44 | 45 | /* Set error code. */ 46 | UTIL_INLINE void 47 | set_errno(int errnum) { 48 | #ifdef _WIN32 49 | SetLastError(errnum); 50 | #else 51 | errno = errnum; 52 | #endif 53 | } 54 | 55 | /* Get last error code. */ 56 | UTIL_INLINE int 57 | get_errno(void) { 58 | #ifdef _WIN32 59 | return GetLastError(); 60 | #else 61 | return errno; 62 | #endif 63 | } 64 | 65 | #undef UTIL_INLINE 66 | 67 | #endif /* JEMALLOC_INTERNAL_UTIL_H */ 68 | -------------------------------------------------------------------------------- /JemallocDemo/JemallocDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/Controller/ByThread/MDByThreadGraphViewController.mm: -------------------------------------------------------------------------------- 1 | // 2 | // MDGraphViewController.m 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/3/31. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import "MDByThreadGraphViewController.h" 10 | #import "../../../base/Normalize.hpp" 11 | 12 | using namespace MD::Normalize; 13 | 14 | @interface MDByThreadGraphViewController () { 15 | MD::PerThreadData::memory_list_type_ptr _data; 16 | } 17 | 18 | @end 19 | 20 | @implementation MDByThreadGraphViewController 21 | 22 | - (void)viewDidLoad { 23 | [super viewDidLoad]; 24 | // Do any additional setup after loading the view. 25 | 26 | self.statView = [[MDPerThreadView alloc] initWithFrame:self.view.bounds]; 27 | [self.view addSubview:self.statView]; 28 | 29 | if (_data) { 30 | [self.statView setPerThreadData:_data]; 31 | [self.statView rebuildCanvasIfNeeded]; 32 | } 33 | } 34 | 35 | 36 | - (void)setData:(MD::PerThreadData::memory_list_type_ptr)data { 37 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 38 | typedef MD::PerThreadData::memory_info_type T; 39 | CompositeNormalize parser(data); 40 | parser.then(Compress(256*4)).then(Scale().scale([](auto& v){ 41 | if (v.second > 0) { 42 | v.second = log2(v.second/8); 43 | } 44 | else { 45 | v.second = 0; 46 | } 47 | })); 48 | auto list = parser.list(); 49 | 50 | dispatch_async(dispatch_get_main_queue(), ^{ 51 | _data = list; 52 | [self.statView setPerThreadData:_data]; 53 | [self.statView rebuildCanvasIfNeeded]; 54 | }); 55 | }); 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /DDMallocDetector/DDMallocDetector/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/analysis/AnalysisPerThread.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // AnalysisPerThread.cpp 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/3/31. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #include "AnalysisPerThread.hpp" 10 | #include 11 | 12 | namespace MD { 13 | void AnalysisPerThread::Run() { 14 | PerThreadData::thread_memory_type thread_memory; 15 | 16 | auto func = [&](MemoryStorage* storage){ 17 | auto mlist = std::make_shared(); 18 | std::string name = storage->name(); 19 | auto begin = storage->data().begin(); 20 | auto& beginItem = *begin; 21 | PerThreadData::memory_info_type 22 | max(beginItem.start_time, beginItem.size), 23 | min(beginItem.start_time, beginItem.size); 24 | std::for_each(begin, storage->data().end(), [&](const Memory& mem){ 25 | mlist->push_back({mem.start_time, mem.size}); 26 | if (max.second < mem.size) { 27 | max.first = mem.start_time; 28 | max.second = mem.size; 29 | } 30 | if (min.second > mem.size) { 31 | min.first = mem.start_time; 32 | min.second = mem.size; 33 | } 34 | }); 35 | auto threadData = PerThreadData::ThreadInfo(std::move(name), std::move(mlist), min, max); 36 | threadData.start_time = beginItem.start_time; 37 | thread_memory.emplace_back(std::move(threadData)); 38 | }; 39 | 40 | pool().EnumerateRunningPool(func); 41 | pool().EnumerateDeadPool(func); 42 | 43 | data_->thread_memory_ = std::move(thread_memory); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/background_thread_structs.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_BACKGROUND_THREAD_STRUCTS_H 2 | #define JEMALLOC_INTERNAL_BACKGROUND_THREAD_STRUCTS_H 3 | 4 | /* This file really combines "structs" and "types", but only transitionally. */ 5 | 6 | #if defined(JEMALLOC_BACKGROUND_THREAD) || defined(JEMALLOC_LAZY_LOCK) 7 | # define JEMALLOC_PTHREAD_CREATE_WRAPPER 8 | #endif 9 | 10 | #define BACKGROUND_THREAD_INDEFINITE_SLEEP UINT64_MAX 11 | 12 | typedef enum { 13 | background_thread_stopped, 14 | background_thread_started, 15 | /* Thread waits on the global lock when paused (for arena_reset). */ 16 | background_thread_paused, 17 | } background_thread_state_t; 18 | 19 | struct background_thread_info_s { 20 | #ifdef JEMALLOC_BACKGROUND_THREAD 21 | /* Background thread is pthread specific. */ 22 | pthread_t thread; 23 | pthread_cond_t cond; 24 | #endif 25 | malloc_mutex_t mtx; 26 | background_thread_state_t state; 27 | /* When true, it means no wakeup scheduled. */ 28 | atomic_b_t indefinite_sleep; 29 | /* Next scheduled wakeup time (absolute time in ns). */ 30 | nstime_t next_wakeup; 31 | /* 32 | * Since the last background thread run, newly added number of pages 33 | * that need to be purged by the next wakeup. This is adjusted on 34 | * epoch advance, and is used to determine whether we should signal the 35 | * background thread to wake up earlier. 36 | */ 37 | size_t npages_to_purge_new; 38 | /* Stats: total number of runs since started. */ 39 | uint64_t tot_n_runs; 40 | /* Stats: total sleep time since started. */ 41 | nstime_t tot_sleep_time; 42 | }; 43 | typedef struct background_thread_info_s background_thread_info_t; 44 | 45 | struct background_thread_stats_s { 46 | size_t num_threads; 47 | uint64_t num_runs; 48 | nstime_t run_interval; 49 | }; 50 | typedef struct background_thread_stats_s background_thread_stats_t; 51 | 52 | #endif /* JEMALLOC_INTERNAL_BACKGROUND_THREAD_STRUCTS_H */ 53 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/jemalloc_internal_externs.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_EXTERNS_H 2 | #define JEMALLOC_INTERNAL_EXTERNS_H 3 | 4 | #include "jemalloc/internal/atomic.h" 5 | #include "jemalloc/internal/size_classes.h" 6 | #include "jemalloc/internal/tsd_types.h" 7 | 8 | /* TSD checks this to set thread local slow state accordingly. */ 9 | extern bool malloc_slow; 10 | 11 | /* Run-time options. */ 12 | extern bool opt_abort; 13 | extern bool opt_abort_conf; 14 | extern const char *opt_junk; 15 | extern bool opt_junk_alloc; 16 | extern bool opt_junk_free; 17 | extern bool opt_utrace; 18 | extern bool opt_xmalloc; 19 | extern bool opt_zero; 20 | extern unsigned opt_narenas; 21 | 22 | /* Number of CPUs. */ 23 | extern unsigned ncpus; 24 | 25 | /* Number of arenas used for automatic multiplexing of threads and arenas. */ 26 | extern unsigned narenas_auto; 27 | 28 | /* 29 | * Arenas that are used to service external requests. Not all elements of the 30 | * arenas array are necessarily used; arenas are created lazily as needed. 31 | */ 32 | extern atomic_p_t arenas[]; 33 | 34 | void *a0malloc(size_t size); 35 | void a0dalloc(void *ptr); 36 | void *bootstrap_malloc(size_t size); 37 | void *bootstrap_calloc(size_t num, size_t size); 38 | void bootstrap_free(void *ptr); 39 | void arena_set(unsigned ind, arena_t *arena); 40 | unsigned narenas_total_get(void); 41 | arena_t *arena_init(tsdn_t *tsdn, unsigned ind, extent_hooks_t *extent_hooks); 42 | arena_tdata_t *arena_tdata_get_hard(tsd_t *tsd, unsigned ind); 43 | arena_t *arena_choose_hard(tsd_t *tsd, bool internal); 44 | void arena_migrate(tsd_t *tsd, unsigned oldind, unsigned newind); 45 | void iarena_cleanup(tsd_t *tsd); 46 | void arena_cleanup(tsd_t *tsd); 47 | void arenas_tdata_cleanup(tsd_t *tsd); 48 | void jemalloc_prefork(void); 49 | void jemalloc_postfork_parent(void); 50 | void jemalloc_postfork_child(void); 51 | bool malloc_initialized(void); 52 | 53 | #endif /* JEMALLOC_INTERNAL_EXTERNS_H */ 54 | -------------------------------------------------------------------------------- /DDMallocDetector/DDMallocDetector/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/analysis/AnalysisPerThread.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // AnalysisPerThread.hpp 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/3/31. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #ifndef AnalysisPerThread_hpp 10 | #define AnalysisPerThread_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "AnalysisTask.hpp" 17 | 18 | namespace MD { 19 | class PerThreadData { 20 | public: 21 | typedef std::pair memory_info_type; 22 | typedef std::vector memory_list_type; 23 | typedef std::shared_ptr memory_list_type_ptr; 24 | struct ThreadInfo { 25 | std::string name; 26 | memory_list_type_ptr memory; 27 | time_t start_time; 28 | memory_info_type max, min; 29 | ThreadInfo() : max(0, 0), min(0, 0) {}; 30 | ThreadInfo(std::string&& name, memory_list_type_ptr&& mem, memory_info_type min, memory_info_type max) 31 | : name(std::move(name)), memory(std::move(mem)), max(max), min(min) {} 32 | }; 33 | typedef std::vector thread_memory_type; 34 | 35 | PerThreadData() : thread_memory_() {} 36 | 37 | thread_memory_type& thread_memory() { 38 | return thread_memory_; 39 | } 40 | private: 41 | friend class AnalysisPerThread; 42 | thread_memory_type thread_memory_; 43 | }; 44 | 45 | 46 | class AnalysisPerThread : public AnalysisTask { 47 | public: 48 | AnalysisPerThread() : data_(std::make_shared()) {} 49 | std::shared_ptr data() { 50 | return data_; 51 | } 52 | 53 | protected: 54 | void Run() override; 55 | 56 | private: 57 | std::shared_ptr data_; 58 | }; 59 | } 60 | 61 | #endif /* AnalysisPerThread_hpp */ 62 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/prof_types.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_PROF_TYPES_H 2 | #define JEMALLOC_INTERNAL_PROF_TYPES_H 3 | 4 | typedef struct prof_bt_s prof_bt_t; 5 | typedef struct prof_accum_s prof_accum_t; 6 | typedef struct prof_cnt_s prof_cnt_t; 7 | typedef struct prof_tctx_s prof_tctx_t; 8 | typedef struct prof_gctx_s prof_gctx_t; 9 | typedef struct prof_tdata_s prof_tdata_t; 10 | 11 | /* Option defaults. */ 12 | #ifdef JEMALLOC_PROF 13 | # define PROF_PREFIX_DEFAULT "jeprof" 14 | #else 15 | # define PROF_PREFIX_DEFAULT "" 16 | #endif 17 | #define LG_PROF_SAMPLE_DEFAULT 19 18 | #define LG_PROF_INTERVAL_DEFAULT -1 19 | 20 | /* 21 | * Hard limit on stack backtrace depth. The version of prof_backtrace() that 22 | * is based on __builtin_return_address() necessarily has a hard-coded number 23 | * of backtrace frame handlers, and should be kept in sync with this setting. 24 | */ 25 | #define PROF_BT_MAX 128 26 | 27 | /* Initial hash table size. */ 28 | #define PROF_CKH_MINITEMS 64 29 | 30 | /* Size of memory buffer to use when writing dump files. */ 31 | #define PROF_DUMP_BUFSIZE 65536 32 | 33 | /* Size of stack-allocated buffer used by prof_printf(). */ 34 | #define PROF_PRINTF_BUFSIZE 128 35 | 36 | /* 37 | * Number of mutexes shared among all gctx's. No space is allocated for these 38 | * unless profiling is enabled, so it's okay to over-provision. 39 | */ 40 | #define PROF_NCTX_LOCKS 1024 41 | 42 | /* 43 | * Number of mutexes shared among all tdata's. No space is allocated for these 44 | * unless profiling is enabled, so it's okay to over-provision. 45 | */ 46 | #define PROF_NTDATA_LOCKS 256 47 | 48 | /* 49 | * prof_tdata pointers close to NULL are used to encode state information that 50 | * is used for cleaning up during thread shutdown. 51 | */ 52 | #define PROF_TDATA_STATE_REINCARNATED ((prof_tdata_t *)(uintptr_t)1) 53 | #define PROF_TDATA_STATE_PURGATORY ((prof_tdata_t *)(uintptr_t)2) 54 | #define PROF_TDATA_STATE_MAX PROF_TDATA_STATE_PURGATORY 55 | 56 | #endif /* JEMALLOC_INTERNAL_PROF_TYPES_H */ 57 | -------------------------------------------------------------------------------- /JemallocDemo/JemallocDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/rtree_tsd.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_RTREE_CTX_H 2 | #define JEMALLOC_INTERNAL_RTREE_CTX_H 3 | 4 | /* 5 | * Number of leafkey/leaf pairs to cache in L1 and L2 level respectively. Each 6 | * entry supports an entire leaf, so the cache hit rate is typically high even 7 | * with a small number of entries. In rare cases extent activity will straddle 8 | * the boundary between two leaf nodes. Furthermore, an arena may use a 9 | * combination of dss and mmap. Note that as memory usage grows past the amount 10 | * that this cache can directly cover, the cache will become less effective if 11 | * locality of reference is low, but the consequence is merely cache misses 12 | * while traversing the tree nodes. 13 | * 14 | * The L1 direct mapped cache offers consistent and low cost on cache hit. 15 | * However collision could affect hit rate negatively. This is resolved by 16 | * combining with a L2 LRU cache, which requires linear search and re-ordering 17 | * on access but suffers no collision. Note that, the cache will itself suffer 18 | * cache misses if made overly large, plus the cost of linear search in the LRU 19 | * cache. 20 | */ 21 | #define RTREE_CTX_LG_NCACHE 4 22 | #define RTREE_CTX_NCACHE (1 << RTREE_CTX_LG_NCACHE) 23 | #define RTREE_CTX_NCACHE_L2 8 24 | 25 | /* 26 | * Zero initializer required for tsd initialization only. Proper initialization 27 | * done via rtree_ctx_data_init(). 28 | */ 29 | #define RTREE_CTX_ZERO_INITIALIZER {{{0}}} 30 | 31 | 32 | typedef struct rtree_leaf_elm_s rtree_leaf_elm_t; 33 | 34 | typedef struct rtree_ctx_cache_elm_s rtree_ctx_cache_elm_t; 35 | struct rtree_ctx_cache_elm_s { 36 | uintptr_t leafkey; 37 | rtree_leaf_elm_t *leaf; 38 | }; 39 | 40 | typedef struct rtree_ctx_s rtree_ctx_t; 41 | struct rtree_ctx_s { 42 | /* Direct mapped cache. */ 43 | rtree_ctx_cache_elm_t cache[RTREE_CTX_NCACHE]; 44 | /* L2 LRU cache. */ 45 | rtree_ctx_cache_elm_t l2_cache[RTREE_CTX_NCACHE_L2]; 46 | }; 47 | 48 | void rtree_ctx_data_init(rtree_ctx_t *ctx); 49 | 50 | #endif /* JEMALLOC_INTERNAL_RTREE_CTX_H */ 51 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/detector/MallocMemory.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // MallocMemory.hpp 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/28. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #ifndef MallocMemory_hpp 10 | #define MallocMemory_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace MD { 18 | enum class Action { 19 | Unknow, 20 | Malloc, 21 | Free, 22 | }; 23 | 24 | class Memory { 25 | public: 26 | 27 | Action action = Action::Unknow; 28 | malloc_zone_t *zone = nullptr; 29 | std::int64_t size = 0; 30 | clock_t start_time; 31 | clock_t end_time; 32 | 33 | void start() { 34 | start_time = clock(); 35 | } 36 | void stop() { 37 | end_time = clock(); 38 | } 39 | 40 | clock_t duration() { 41 | return end_time - start_time; 42 | } 43 | 44 | double duration_interval() { 45 | return duration() / CLOCKS_PER_SEC; 46 | } 47 | 48 | Memory& set(malloc_zone_t *z, Action act, std::int64_t size) { 49 | zone = z; 50 | action = act; 51 | size = size; 52 | return *this; 53 | } 54 | 55 | Memory() {}; 56 | Memory(const Memory& mem) 57 | : action(mem.action), zone(mem.zone), size(mem.size), 58 | start_time(mem.start_time), end_time(mem.end_time) { } 59 | 60 | Memory(const Memory&& mem) 61 | : action(mem.action), zone(mem.zone), size(mem.size), 62 | start_time(mem.start_time), end_time(mem.end_time) { } 63 | 64 | Memory& operator = (Memory& mem) { 65 | action = mem.action; 66 | zone = mem.zone; 67 | size = mem.size; 68 | start_time = mem.start_time; 69 | end_time = mem.end_time; 70 | return *this; 71 | } 72 | ~Memory() {} 73 | private: 74 | }; 75 | } 76 | 77 | #endif /* MallocMemory_hpp */ 78 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/malloc_io.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_MALLOC_IO_H 2 | #define JEMALLOC_INTERNAL_MALLOC_IO_H 3 | 4 | #ifdef _WIN32 5 | # ifdef _WIN64 6 | # define FMT64_PREFIX "ll" 7 | # define FMTPTR_PREFIX "ll" 8 | # else 9 | # define FMT64_PREFIX "ll" 10 | # define FMTPTR_PREFIX "" 11 | # endif 12 | # define FMTd32 "d" 13 | # define FMTu32 "u" 14 | # define FMTx32 "x" 15 | # define FMTd64 FMT64_PREFIX "d" 16 | # define FMTu64 FMT64_PREFIX "u" 17 | # define FMTx64 FMT64_PREFIX "x" 18 | # define FMTdPTR FMTPTR_PREFIX "d" 19 | # define FMTuPTR FMTPTR_PREFIX "u" 20 | # define FMTxPTR FMTPTR_PREFIX "x" 21 | #else 22 | # include 23 | # define FMTd32 PRId32 24 | # define FMTu32 PRIu32 25 | # define FMTx32 PRIx32 26 | # define FMTd64 PRId64 27 | # define FMTu64 PRIu64 28 | # define FMTx64 PRIx64 29 | # define FMTdPTR PRIdPTR 30 | # define FMTuPTR PRIuPTR 31 | # define FMTxPTR PRIxPTR 32 | #endif 33 | 34 | /* Size of stack-allocated buffer passed to buferror(). */ 35 | #define BUFERROR_BUF 64 36 | 37 | /* 38 | * Size of stack-allocated buffer used by malloc_{,v,vc}printf(). This must be 39 | * large enough for all possible uses within jemalloc. 40 | */ 41 | #define MALLOC_PRINTF_BUFSIZE 4096 42 | 43 | int buferror(int err, char *buf, size_t buflen); 44 | uintmax_t malloc_strtoumax(const char *restrict nptr, char **restrict endptr, 45 | int base); 46 | void malloc_write(const char *s); 47 | 48 | /* 49 | * malloc_vsnprintf() supports a subset of snprintf(3) that avoids floating 50 | * point math. 51 | */ 52 | size_t malloc_vsnprintf(char *str, size_t size, const char *format, 53 | va_list ap); 54 | size_t malloc_snprintf(char *str, size_t size, const char *format, ...) 55 | JEMALLOC_FORMAT_PRINTF(3, 4); 56 | void malloc_vcprintf(void (*write_cb)(void *, const char *), void *cbopaque, 57 | const char *format, va_list ap); 58 | void malloc_cprintf(void (*write_cb)(void *, const char *), void *cbopaque, 59 | const char *format, ...) JEMALLOC_FORMAT_PRINTF(3, 4); 60 | void malloc_printf(const char *format, ...) JEMALLOC_FORMAT_PRINTF(1, 2); 61 | 62 | #endif /* JEMALLOC_INTERNAL_MALLOC_IO_H */ 63 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/Controller/BySize/MDBySizeGraphViewController.mm: -------------------------------------------------------------------------------- 1 | // 2 | // MDBySizeGraphViewController.m 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/4/2. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import "MDBySizeGraphViewController.h" 10 | #import "AnalysisBySize.hpp" 11 | #import "MDBySizeView.h" 12 | 13 | @interface MDBySizeGraphViewController () { 14 | MDBySizeGraphViewControllerData _data; 15 | std::size_t _maxY; 16 | } 17 | 18 | @property (nonatomic, strong) MDBySizeView *graphView; 19 | 20 | @end 21 | 22 | @implementation MDBySizeGraphViewController 23 | 24 | - (void)viewDidLoad { 25 | [super viewDidLoad]; 26 | self.graphView = [[MDBySizeView alloc] initWithFrame:self.view.bounds]; 27 | [self.view addSubview:self.graphView]; 28 | 29 | [self.graphView setList:_data minCount:0 maxCount:_maxY]; 30 | [self.graphView rebuildCanvasIfNeeded]; 31 | } 32 | 33 | - (void)didReceiveMemoryWarning { 34 | [super didReceiveMemoryWarning]; 35 | // Dispose of any resources that can be recreated. 36 | } 37 | 38 | - (void)setData:(MDBySizeGraphViewControllerData)data { 39 | _data = data; 40 | 41 | std::size_t max = 0; 42 | std::for_each(_data->begin(), _data->end(), [&](auto& p) { 43 | max = std::max(max, p.second); 44 | }); 45 | _maxY = ceil(double(max) / 1000) * 1000; 46 | 47 | // [self printData]; 48 | if (self.graphView) { 49 | [self.graphView setList:_data minCount:0 maxCount:_maxY]; 50 | [self.graphView rebuildCanvasIfNeeded]; 51 | } 52 | } 53 | 54 | - (void)printData { 55 | std::for_each(_data->begin(), _data->end(), [](auto& p) { 56 | printf("(%ld, %ld)\n", p.first, p.second); 57 | }); 58 | } 59 | 60 | /* 61 | #pragma mark - Navigation 62 | 63 | // In a storyboard-based application, you will often want to do a little preparation before navigation 64 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 65 | // Get the new view controller using [segue destinationViewController]. 66 | // Pass the selected object to the new view controller. 67 | } 68 | */ 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/detector/MallocCollectorHelper.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // MallocCollectorHelper.hpp 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/28. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #ifndef MallocCollectorHelper_hpp 10 | #define MallocCollectorHelper_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include "MallocMemory.hpp" 16 | 17 | namespace MD { 18 | 19 | namespace CollectorDefault { 20 | template 21 | struct CollectorChecker { 22 | static int64_t max() { 23 | return 1024*1024; 24 | } 25 | static void overflow(_S* storage) { 26 | 27 | } 28 | }; 29 | } 30 | 31 | template > 32 | class Collector { 33 | public: 34 | typedef _S storage_type; 35 | typedef _I item_type; 36 | typedef _C checker_type; 37 | 38 | Collector(storage_type* s) : s_(s) { 39 | i_.start(); 40 | } 41 | 42 | Collector& setZone(malloc_zone_t *z) { 43 | i_.zone = z; 44 | return *this; 45 | } 46 | 47 | Collector& setAction(Action act) { 48 | i_.action = act; 49 | return *this; 50 | } 51 | 52 | Collector& setSize(std::int64_t size) { 53 | i_.size = size; 54 | return *this; 55 | } 56 | 57 | Collector& set(malloc_zone_t *z, Action act, std::int64_t size) { 58 | i_.zone = z; 59 | i_.action = act; 60 | i_.size = size; 61 | return *this; 62 | } 63 | 64 | ~Collector() { 65 | i_.stop(); 66 | 67 | int64_t cnt = s_->collect(std::move(i_)); 68 | if (cnt > checker_type::max()) { 69 | checker_type::overflow(s_); 70 | } 71 | } 72 | 73 | private: 74 | storage_type* s_; 75 | item_type i_; 76 | }; 77 | } 78 | 79 | #endif /* MallocCollectorHelper_hpp */ 80 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/background_thread_inlines.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_BACKGROUND_THREAD_INLINES_H 2 | #define JEMALLOC_INTERNAL_BACKGROUND_THREAD_INLINES_H 3 | 4 | JEMALLOC_ALWAYS_INLINE bool 5 | background_thread_enabled(void) { 6 | return atomic_load_b(&background_thread_enabled_state, ATOMIC_RELAXED); 7 | } 8 | 9 | JEMALLOC_ALWAYS_INLINE void 10 | background_thread_enabled_set(tsdn_t *tsdn, bool state) { 11 | malloc_mutex_assert_owner(tsdn, &background_thread_lock); 12 | atomic_store_b(&background_thread_enabled_state, state, ATOMIC_RELAXED); 13 | } 14 | 15 | JEMALLOC_ALWAYS_INLINE background_thread_info_t * 16 | arena_background_thread_info_get(arena_t *arena) { 17 | unsigned arena_ind = arena_ind_get(arena); 18 | return &background_thread_info[arena_ind % ncpus]; 19 | } 20 | 21 | JEMALLOC_ALWAYS_INLINE uint64_t 22 | background_thread_wakeup_time_get(background_thread_info_t *info) { 23 | uint64_t next_wakeup = nstime_ns(&info->next_wakeup); 24 | assert(atomic_load_b(&info->indefinite_sleep, ATOMIC_ACQUIRE) == 25 | (next_wakeup == BACKGROUND_THREAD_INDEFINITE_SLEEP)); 26 | return next_wakeup; 27 | } 28 | 29 | JEMALLOC_ALWAYS_INLINE void 30 | background_thread_wakeup_time_set(tsdn_t *tsdn, background_thread_info_t *info, 31 | uint64_t wakeup_time) { 32 | malloc_mutex_assert_owner(tsdn, &info->mtx); 33 | atomic_store_b(&info->indefinite_sleep, 34 | wakeup_time == BACKGROUND_THREAD_INDEFINITE_SLEEP, ATOMIC_RELEASE); 35 | nstime_init(&info->next_wakeup, wakeup_time); 36 | } 37 | 38 | JEMALLOC_ALWAYS_INLINE bool 39 | background_thread_indefinite_sleep(background_thread_info_t *info) { 40 | return atomic_load_b(&info->indefinite_sleep, ATOMIC_ACQUIRE); 41 | } 42 | 43 | JEMALLOC_ALWAYS_INLINE void 44 | arena_background_thread_inactivity_check(tsdn_t *tsdn, arena_t *arena, 45 | bool is_background_thread) { 46 | if (!background_thread_enabled() || is_background_thread) { 47 | return; 48 | } 49 | background_thread_info_t *info = 50 | arena_background_thread_info_get(arena); 51 | if (background_thread_indefinite_sleep(info)) { 52 | background_thread_interval_check(tsdn, arena, 53 | &arena->decay_dirty, 0); 54 | } 55 | } 56 | 57 | #endif /* JEMALLOC_INTERNAL_BACKGROUND_THREAD_INLINES_H */ 58 | -------------------------------------------------------------------------------- /JemallocDemo/JemallocDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // JemallocDemo 4 | // 5 | // Created by daniel on 2018/4/6. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /DDMallocDetector/DDMallocDetector/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // DDMallocDetector 4 | // 5 | // Created by hzduanjiashun on 2018/3/30. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/detector/MallocWrapZone.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // MallocWrapZone.hpp 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/27. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #ifndef MallocWrapZone_hpp 10 | #define MallocWrapZone_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include "Allocator.hpp" 16 | #include "../base/Macros.h" 17 | 18 | namespace MD { 19 | class MallocWrapZones { 20 | public: 21 | 22 | MallocWrapZones() { 23 | wrap_zones_.reserve(8); 24 | }; 25 | 26 | void WrapZone(malloc_zone_t* zone) { 27 | MallocWrapZone z(zone); 28 | z.Wrap(); 29 | wrap_zones_.emplace_back(z); 30 | } 31 | void UnWrapZone(malloc_zone_t* zone) { 32 | auto z = FindWrapZone(zone); 33 | z->UnWrap(); 34 | wrap_zones_.erase(z); 35 | } 36 | 37 | malloc_zone_t* orig_zone_value(malloc_zone_t* zone) { 38 | auto z = FindWrapZone(zone); 39 | return z->orig_zone(); 40 | } 41 | 42 | private: 43 | class MallocWrapZone { 44 | public: 45 | MallocWrapZone(malloc_zone_t *source) : orig_zone_(*source), orig_zone_ptr_(source) { }; 46 | 47 | malloc_zone_t *orig_zone_ptr() { return orig_zone_ptr_; } 48 | malloc_zone_t *orig_zone() { return &orig_zone_; } 49 | 50 | void Wrap(); 51 | void UnWrap(); 52 | 53 | private: 54 | malloc_zone_t *orig_zone_ptr_; 55 | malloc_zone_t orig_zone_; 56 | }; 57 | 58 | MD_NO_COPY_ASSIGN(MallocWrapZones); 59 | 60 | std::vector::iterator FindWrapZone(malloc_zone_t *z) { 61 | auto iz = std::find_if(wrap_zones_.begin(), wrap_zones_.end(), [z](MallocWrapZone& zone){ 62 | return zone.orig_zone_ptr() == z; 63 | }); 64 | return iz; 65 | } 66 | 67 | 68 | // var 69 | std::vector> wrap_zones_; 70 | }; 71 | 72 | } 73 | 74 | #endif /* MallocWrapZone_hpp */ 75 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/control/MDInspectorIcon.m: -------------------------------------------------------------------------------- 1 | // 2 | // MDInspectorIcon.m 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/3/31. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import "MDInspectorIcon.h" 10 | 11 | @implementation MDInspectorIcon 12 | 13 | - (instancetype)initWithFrame:(CGRect)frame 14 | { 15 | self = [super initWithFrame:frame]; 16 | if (self) { 17 | self.backgroundColor = [UIColor blackColor]; 18 | } 19 | return self; 20 | } 21 | 22 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 23 | [super touchesBegan:touches withEvent:event]; 24 | [self handleTouch:touches.anyObject]; 25 | } 26 | 27 | - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 28 | [super touchesCancelled:touches withEvent:event]; 29 | [self handleTouch:touches.anyObject]; 30 | } 31 | 32 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 33 | [super touchesEnded:touches withEvent:event]; 34 | [self handleTouch:touches.anyObject]; 35 | [self stickToEdges]; 36 | } 37 | 38 | - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { 39 | [super touchesCancelled:touches withEvent:event]; 40 | [self handleTouch:touches.anyObject]; 41 | [self stickToEdges]; 42 | } 43 | 44 | - (void)handleTouch:(UITouch *)touch { 45 | CGPoint loc = [touch locationInView:self.superview]; 46 | CGPoint preLoc = [touch previousLocationInView:self.superview]; 47 | 48 | CGPoint v = CGPointMake(loc.x - preLoc.x, loc.y - preLoc.y); 49 | CGRect r = self.frame; 50 | r.origin.x = MAX(0, MIN(self.superview.frame.size.width - self.frame.size.width, r.origin.x + v.x)); 51 | r.origin.y = MAX(0, MIN(self.superview.frame.size.height - self.frame.size.height, r.origin.y + v.y)); 52 | self.frame = r; 53 | } 54 | 55 | - (void)stickToEdges { 56 | CGRect r = self.frame; 57 | if (self.center.x > self.superview.frame.size.width / 2) { 58 | // right 59 | r.origin.x = self.superview.frame.size.width - self.frame.size.width; 60 | } 61 | else { 62 | r.origin.x = 0; 63 | } 64 | [UIView animateWithDuration:0.3 animations:^{ 65 | self.frame = r; 66 | }]; 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/graph/MDDrawableView.mm: -------------------------------------------------------------------------------- 1 | // 2 | // MDDrawableView.m 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/29. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #import "MDDrawableView.h" 10 | 11 | @interface MDDrawableView() { 12 | std::shared_ptr _canvas; 13 | BOOL _rebuildCanvas; 14 | } 15 | 16 | @end 17 | 18 | @implementation MDDrawableView 19 | 20 | - (instancetype)initWithFrame:(CGRect)frame 21 | { 22 | self = [super initWithFrame:frame]; 23 | if (self) { 24 | _xAxis = [self makeXAxis]; 25 | _xAxis->setTriangleHeight(10); 26 | _xAxis->setTextColor(0, 0, 0); 27 | _yAxis = [self makeYAxis]; 28 | _contentLayer = std::make_shared(); 29 | 30 | _canvas = std::make_shared(); 31 | _canvas->setBackgroundColor({ 1, 1, 1, 1 }); 32 | 33 | _contentLayer->setEdges(MD::Edges(20, 100, 20, 100)); 34 | _contentLayer->setBackgroundColor({0.9, 0.9, 0.9}); 35 | 36 | 37 | _xAxis->setName("X"); 38 | _xAxis->setEdges(MD::Edges(20, 100, 20, 100)); 39 | 40 | 41 | _yAxis->setName("Y"); 42 | _yAxis->setEdges(MD::Edges(20, 100, 20, 100)); 43 | } 44 | return self; 45 | } 46 | 47 | - (std::shared_ptr)makeXAxis { 48 | return std::make_shared>(); 49 | } 50 | 51 | - (std::shared_ptr)makeYAxis { 52 | return std::make_shared>(); 53 | } 54 | 55 | - (const std::shared_ptr&)canvas { 56 | return _canvas; 57 | } 58 | 59 | - (void)setNeedsRebuildCanvas { 60 | _rebuildCanvas = YES; 61 | } 62 | 63 | - (void)rebuildCanvasIfNeeded { 64 | if (_rebuildCanvas) { 65 | _rebuildCanvas = NO; 66 | [self rebuildCanvas]; 67 | [self setNeedsDisplay]; 68 | } 69 | } 70 | 71 | - (void)rebuildCanvas { 72 | auto& canvas = [self canvas]; 73 | canvas->RemoveLayers(); 74 | canvas->AddLayer(_contentLayer); 75 | canvas->AddLayer(_xAxis); 76 | canvas->AddLayer(_yAxis); 77 | } 78 | 79 | - (void)drawRect:(CGRect)rect { 80 | if (_canvas) { 81 | _canvas->setFrame(self.bounds); 82 | _canvas->Draw(); 83 | } 84 | } 85 | 86 | 87 | @end 88 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/jemalloc_internal_decls.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_DECLS_H 2 | #define JEMALLOC_INTERNAL_DECLS_H 3 | 4 | #include 5 | #ifdef _WIN32 6 | # include 7 | # include "msvc_compat/windows_extra.h" 8 | 9 | #else 10 | # include 11 | # include 12 | # if !defined(__pnacl__) && !defined(__native_client__) 13 | # include 14 | # if !defined(SYS_write) && defined(__NR_write) 15 | # define SYS_write __NR_write 16 | # endif 17 | # if defined(SYS_open) && defined(__aarch64__) 18 | /* Android headers may define SYS_open to __NR_open even though 19 | * __NR_open may not exist on AArch64 (superseded by __NR_openat). */ 20 | # undef SYS_open 21 | # endif 22 | # include 23 | # endif 24 | # include 25 | # include 26 | # ifdef JEMALLOC_OS_UNFAIR_LOCK 27 | # include 28 | # endif 29 | # ifdef JEMALLOC_GLIBC_MALLOC_HOOK 30 | # include 31 | # endif 32 | # include 33 | # include 34 | # include 35 | # ifdef JEMALLOC_HAVE_MACH_ABSOLUTE_TIME 36 | # include 37 | # endif 38 | #endif 39 | #include 40 | 41 | #include 42 | #ifndef SIZE_T_MAX 43 | # define SIZE_T_MAX SIZE_MAX 44 | #endif 45 | #ifndef SSIZE_MAX 46 | # define SSIZE_MAX ((ssize_t)(SIZE_T_MAX >> 1)) 47 | #endif 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #ifndef offsetof 55 | # define offsetof(type, member) ((size_t)&(((type *)NULL)->member)) 56 | #endif 57 | #include 58 | #include 59 | #include 60 | #ifdef _MSC_VER 61 | # include 62 | typedef intptr_t ssize_t; 63 | # define PATH_MAX 1024 64 | # define STDERR_FILENO 2 65 | # define __func__ __FUNCTION__ 66 | # ifdef JEMALLOC_HAS_RESTRICT 67 | # define restrict __restrict 68 | # endif 69 | /* Disable warnings about deprecated system functions. */ 70 | # pragma warning(disable: 4996) 71 | #if _MSC_VER < 1800 72 | static int 73 | isblank(int c) { 74 | return (c == '\t' || c == ' '); 75 | } 76 | #endif 77 | #else 78 | # include 79 | #endif 80 | #include 81 | 82 | #endif /* JEMALLOC_INTERNAL_H */ 83 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/jemalloc_mangle.h: -------------------------------------------------------------------------------- 1 | /* 2 | * By default application code must explicitly refer to mangled symbol names, 3 | * so that it is possible to use jemalloc in conjunction with another allocator 4 | * in the same application. Define JEMALLOC_MANGLE in order to cause automatic 5 | * name mangling that matches the API prefixing that happened as a result of 6 | * --with-mangling and/or --with-jemalloc-prefix configuration settings. 7 | */ 8 | #ifdef JEMALLOC_MANGLE 9 | # ifndef JEMALLOC_NO_DEMANGLE 10 | # define JEMALLOC_NO_DEMANGLE 11 | # endif 12 | # define aligned_alloc je_aligned_alloc 13 | # define calloc je_calloc 14 | # define dallocx je_dallocx 15 | # define free je_free 16 | # define mallctl je_mallctl 17 | # define mallctlbymib je_mallctlbymib 18 | # define mallctlnametomib je_mallctlnametomib 19 | # define malloc je_malloc 20 | # define malloc_conf je_malloc_conf 21 | # define malloc_message je_malloc_message 22 | # define malloc_stats_print je_malloc_stats_print 23 | # define malloc_usable_size je_malloc_usable_size 24 | # define mallocx je_mallocx 25 | # define nallocx je_nallocx 26 | # define posix_memalign je_posix_memalign 27 | # define rallocx je_rallocx 28 | # define realloc je_realloc 29 | # define sallocx je_sallocx 30 | # define sdallocx je_sdallocx 31 | # define xallocx je_xallocx 32 | # define valloc je_valloc 33 | #endif 34 | 35 | /* 36 | * The je_* macros can be used as stable alternative names for the 37 | * public jemalloc API if JEMALLOC_NO_DEMANGLE is defined. This is primarily 38 | * meant for use in jemalloc itself, but it can be used by application code to 39 | * provide isolation from the name mangling specified via --with-mangling 40 | * and/or --with-jemalloc-prefix. 41 | */ 42 | #ifndef JEMALLOC_NO_DEMANGLE 43 | # undef je_aligned_alloc 44 | # undef je_calloc 45 | # undef je_dallocx 46 | # undef je_free 47 | # undef je_mallctl 48 | # undef je_mallctlbymib 49 | # undef je_mallctlnametomib 50 | # undef je_malloc 51 | # undef je_malloc_conf 52 | # undef je_malloc_message 53 | # undef je_malloc_stats_print 54 | # undef je_malloc_usable_size 55 | # undef je_mallocx 56 | # undef je_nallocx 57 | # undef je_posix_memalign 58 | # undef je_rallocx 59 | # undef je_realloc 60 | # undef je_sallocx 61 | # undef je_sdallocx 62 | # undef je_xallocx 63 | # undef je_valloc 64 | #endif 65 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/tcache_types.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_TCACHE_TYPES_H 2 | #define JEMALLOC_INTERNAL_TCACHE_TYPES_H 3 | 4 | #include "jemalloc/internal/size_classes.h" 5 | 6 | typedef struct tcache_bin_info_s tcache_bin_info_t; 7 | typedef struct tcache_bin_s tcache_bin_t; 8 | typedef struct tcache_s tcache_t; 9 | typedef struct tcaches_s tcaches_t; 10 | 11 | /* ncached is cast to this type for comparison. */ 12 | typedef int32_t low_water_t; 13 | 14 | /* 15 | * tcache pointers close to NULL are used to encode state information that is 16 | * used for two purposes: preventing thread caching on a per thread basis and 17 | * cleaning up during thread shutdown. 18 | */ 19 | #define TCACHE_STATE_DISABLED ((tcache_t *)(uintptr_t)1) 20 | #define TCACHE_STATE_REINCARNATED ((tcache_t *)(uintptr_t)2) 21 | #define TCACHE_STATE_PURGATORY ((tcache_t *)(uintptr_t)3) 22 | #define TCACHE_STATE_MAX TCACHE_STATE_PURGATORY 23 | 24 | /* 25 | * Absolute minimum number of cache slots for each small bin. 26 | */ 27 | #define TCACHE_NSLOTS_SMALL_MIN 20 28 | 29 | /* 30 | * Absolute maximum number of cache slots for each small bin in the thread 31 | * cache. This is an additional constraint beyond that imposed as: twice the 32 | * number of regions per slab for this size class. 33 | * 34 | * This constant must be an even number. 35 | */ 36 | #define TCACHE_NSLOTS_SMALL_MAX 200 37 | 38 | /* Number of cache slots for large size classes. */ 39 | #define TCACHE_NSLOTS_LARGE 20 40 | 41 | /* (1U << opt_lg_tcache_max) is used to compute tcache_maxclass. */ 42 | #define LG_TCACHE_MAXCLASS_DEFAULT 15 43 | 44 | /* 45 | * TCACHE_GC_SWEEP is the approximate number of allocation events between 46 | * full GC sweeps. Integer rounding may cause the actual number to be 47 | * slightly higher, since GC is performed incrementally. 48 | */ 49 | #define TCACHE_GC_SWEEP 8192 50 | 51 | /* Number of tcache allocation/deallocation events between incremental GCs. */ 52 | #define TCACHE_GC_INCR \ 53 | ((TCACHE_GC_SWEEP / NBINS) + ((TCACHE_GC_SWEEP / NBINS == 0) ? 0 : 1)) 54 | 55 | /* Used in TSD static initializer only. Real init in tcache_data_init(). */ 56 | #define TCACHE_ZERO_INITIALIZER {0} 57 | 58 | /* Used in TSD static initializer only. Will be initialized to opt_tcache. */ 59 | #define TCACHE_ENABLED_ZERO_INITIALIZER false 60 | 61 | #endif /* JEMALLOC_INTERNAL_TCACHE_TYPES_H */ 62 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/jemalloc_mangle_jet.h: -------------------------------------------------------------------------------- 1 | /* 2 | * By default application code must explicitly refer to mangled symbol names, 3 | * so that it is possible to use jemalloc in conjunction with another allocator 4 | * in the same application. Define JEMALLOC_MANGLE in order to cause automatic 5 | * name mangling that matches the API prefixing that happened as a result of 6 | * --with-mangling and/or --with-jemalloc-prefix configuration settings. 7 | */ 8 | #ifdef JEMALLOC_MANGLE 9 | # ifndef JEMALLOC_NO_DEMANGLE 10 | # define JEMALLOC_NO_DEMANGLE 11 | # endif 12 | # define aligned_alloc jet_aligned_alloc 13 | # define calloc jet_calloc 14 | # define dallocx jet_dallocx 15 | # define free jet_free 16 | # define mallctl jet_mallctl 17 | # define mallctlbymib jet_mallctlbymib 18 | # define mallctlnametomib jet_mallctlnametomib 19 | # define malloc jet_malloc 20 | # define malloc_conf jet_malloc_conf 21 | # define malloc_message jet_malloc_message 22 | # define malloc_stats_print jet_malloc_stats_print 23 | # define malloc_usable_size jet_malloc_usable_size 24 | # define mallocx jet_mallocx 25 | # define nallocx jet_nallocx 26 | # define posix_memalign jet_posix_memalign 27 | # define rallocx jet_rallocx 28 | # define realloc jet_realloc 29 | # define sallocx jet_sallocx 30 | # define sdallocx jet_sdallocx 31 | # define xallocx jet_xallocx 32 | # define valloc jet_valloc 33 | #endif 34 | 35 | /* 36 | * The jet_* macros can be used as stable alternative names for the 37 | * public jemalloc API if JEMALLOC_NO_DEMANGLE is defined. This is primarily 38 | * meant for use in jemalloc itself, but it can be used by application code to 39 | * provide isolation from the name mangling specified via --with-mangling 40 | * and/or --with-jemalloc-prefix. 41 | */ 42 | #ifndef JEMALLOC_NO_DEMANGLE 43 | # undef jet_aligned_alloc 44 | # undef jet_calloc 45 | # undef jet_dallocx 46 | # undef jet_free 47 | # undef jet_mallctl 48 | # undef jet_mallctlbymib 49 | # undef jet_mallctlnametomib 50 | # undef jet_malloc 51 | # undef jet_malloc_conf 52 | # undef jet_malloc_message 53 | # undef jet_malloc_stats_print 54 | # undef jet_malloc_usable_size 55 | # undef jet_mallocx 56 | # undef jet_nallocx 57 | # undef jet_posix_memalign 58 | # undef jet_rallocx 59 | # undef jet_realloc 60 | # undef jet_sallocx 61 | # undef jet_sdallocx 62 | # undef jet_xallocx 63 | # undef jet_valloc 64 | #endif 65 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/tcache_externs.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_TCACHE_EXTERNS_H 2 | #define JEMALLOC_INTERNAL_TCACHE_EXTERNS_H 3 | 4 | #include "jemalloc/internal/size_classes.h" 5 | 6 | extern bool opt_tcache; 7 | extern ssize_t opt_lg_tcache_max; 8 | 9 | extern tcache_bin_info_t *tcache_bin_info; 10 | 11 | /* 12 | * Number of tcache bins. There are NBINS small-object bins, plus 0 or more 13 | * large-object bins. 14 | */ 15 | extern unsigned nhbins; 16 | 17 | /* Maximum cached size class. */ 18 | extern size_t tcache_maxclass; 19 | 20 | /* 21 | * Explicit tcaches, managed via the tcache.{create,flush,destroy} mallctls and 22 | * usable via the MALLOCX_TCACHE() flag. The automatic per thread tcaches are 23 | * completely disjoint from this data structure. tcaches starts off as a sparse 24 | * array, so it has no physical memory footprint until individual pages are 25 | * touched. This allows the entire array to be allocated the first time an 26 | * explicit tcache is created without a disproportionate impact on memory usage. 27 | */ 28 | extern tcaches_t *tcaches; 29 | 30 | size_t tcache_salloc(tsdn_t *tsdn, const void *ptr); 31 | void tcache_event_hard(tsd_t *tsd, tcache_t *tcache); 32 | void *tcache_alloc_small_hard(tsdn_t *tsdn, arena_t *arena, tcache_t *tcache, 33 | tcache_bin_t *tbin, szind_t binind, bool *tcache_success); 34 | void tcache_bin_flush_small(tsd_t *tsd, tcache_t *tcache, tcache_bin_t *tbin, 35 | szind_t binind, unsigned rem); 36 | void tcache_bin_flush_large(tsd_t *tsd, tcache_bin_t *tbin, szind_t binind, 37 | unsigned rem, tcache_t *tcache); 38 | void tcache_arena_reassociate(tsdn_t *tsdn, tcache_t *tcache, 39 | arena_t *arena); 40 | tcache_t *tcache_create_explicit(tsd_t *tsd); 41 | void tcache_cleanup(tsd_t *tsd); 42 | void tcache_stats_merge(tsdn_t *tsdn, tcache_t *tcache, arena_t *arena); 43 | bool tcaches_create(tsd_t *tsd, unsigned *r_ind); 44 | void tcaches_flush(tsd_t *tsd, unsigned ind); 45 | void tcaches_destroy(tsd_t *tsd, unsigned ind); 46 | bool tcache_boot(tsdn_t *tsdn); 47 | void tcache_arena_associate(tsdn_t *tsdn, tcache_t *tcache, arena_t *arena); 48 | void tcache_prefork(tsdn_t *tsdn); 49 | void tcache_postfork_parent(tsdn_t *tsdn); 50 | void tcache_postfork_child(tsdn_t *tsdn); 51 | void tcache_flush(tsd_t *tsd); 52 | bool tsd_tcache_data_init(tsd_t *tsd); 53 | bool tsd_tcache_enabled_data_init(tsd_t *tsd); 54 | 55 | #endif /* JEMALLOC_INTERNAL_TCACHE_EXTERNS_H */ 56 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/prof_inlines_a.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_PROF_INLINES_A_H 2 | #define JEMALLOC_INTERNAL_PROF_INLINES_A_H 3 | 4 | #include "jemalloc/internal/mutex.h" 5 | 6 | static inline bool 7 | prof_accum_add(tsdn_t *tsdn, prof_accum_t *prof_accum, uint64_t accumbytes) { 8 | cassert(config_prof); 9 | 10 | bool overflow; 11 | uint64_t a0, a1; 12 | 13 | /* 14 | * If the application allocates fast enough (and/or if idump is slow 15 | * enough), extreme overflow here (a1 >= prof_interval * 2) can cause 16 | * idump trigger coalescing. This is an intentional mechanism that 17 | * avoids rate-limiting allocation. 18 | */ 19 | #ifdef JEMALLOC_ATOMIC_U64 20 | a0 = atomic_load_u64(&prof_accum->accumbytes, ATOMIC_RELAXED); 21 | do { 22 | a1 = a0 + accumbytes; 23 | assert(a1 >= a0); 24 | overflow = (a1 >= prof_interval); 25 | if (overflow) { 26 | a1 %= prof_interval; 27 | } 28 | } while (!atomic_compare_exchange_weak_u64(&prof_accum->accumbytes, &a0, 29 | a1, ATOMIC_RELAXED, ATOMIC_RELAXED)); 30 | #else 31 | malloc_mutex_lock(tsdn, &prof_accum->mtx); 32 | a0 = prof_accum->accumbytes; 33 | a1 = a0 + accumbytes; 34 | overflow = (a1 >= prof_interval); 35 | if (overflow) { 36 | a1 %= prof_interval; 37 | } 38 | prof_accum->accumbytes = a1; 39 | malloc_mutex_unlock(tsdn, &prof_accum->mtx); 40 | #endif 41 | return overflow; 42 | } 43 | 44 | static inline void 45 | prof_accum_cancel(tsdn_t *tsdn, prof_accum_t *prof_accum, size_t usize) { 46 | cassert(config_prof); 47 | 48 | /* 49 | * Cancel out as much of the excessive prof_accumbytes increase as 50 | * possible without underflowing. Interval-triggered dumps occur 51 | * slightly more often than intended as a result of incomplete 52 | * canceling. 53 | */ 54 | uint64_t a0, a1; 55 | #ifdef JEMALLOC_ATOMIC_U64 56 | a0 = atomic_load_u64(&prof_accum->accumbytes, ATOMIC_RELAXED); 57 | do { 58 | a1 = (a0 >= LARGE_MINCLASS - usize) ? a0 - (LARGE_MINCLASS - 59 | usize) : 0; 60 | } while (!atomic_compare_exchange_weak_u64(&prof_accum->accumbytes, &a0, 61 | a1, ATOMIC_RELAXED, ATOMIC_RELAXED)); 62 | #else 63 | malloc_mutex_lock(tsdn, &prof_accum->mtx); 64 | a0 = prof_accum->accumbytes; 65 | a1 = (a0 >= LARGE_MINCLASS - usize) ? a0 - (LARGE_MINCLASS - usize) : 66 | 0; 67 | prof_accum->accumbytes = a1; 68 | malloc_mutex_unlock(tsdn, &prof_accum->mtx); 69 | #endif 70 | } 71 | 72 | #endif /* JEMALLOC_INTERNAL_PROF_INLINES_A_H */ 73 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/tcache_structs.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_TCACHE_STRUCTS_H 2 | #define JEMALLOC_INTERNAL_TCACHE_STRUCTS_H 3 | 4 | #include "jemalloc/internal/ql.h" 5 | #include "jemalloc/internal/size_classes.h" 6 | #include "jemalloc/internal/stats_tsd.h" 7 | #include "jemalloc/internal/ticker.h" 8 | 9 | /* 10 | * Read-only information associated with each element of tcache_t's tbins array 11 | * is stored separately, mainly to reduce memory usage. 12 | */ 13 | struct tcache_bin_info_s { 14 | unsigned ncached_max; /* Upper limit on ncached. */ 15 | }; 16 | 17 | struct tcache_bin_s { 18 | low_water_t low_water; /* Min # cached since last GC. */ 19 | uint32_t ncached; /* # of cached objects. */ 20 | /* 21 | * ncached and stats are both modified frequently. Let's keep them 22 | * close so that they have a higher chance of being on the same 23 | * cacheline, thus less write-backs. 24 | */ 25 | tcache_bin_stats_t tstats; 26 | /* 27 | * To make use of adjacent cacheline prefetch, the items in the avail 28 | * stack goes to higher address for newer allocations. avail points 29 | * just above the available space, which means that 30 | * avail[-ncached, ... -1] are available items and the lowest item will 31 | * be allocated first. 32 | */ 33 | void **avail; /* Stack of available objects. */ 34 | }; 35 | 36 | struct tcache_s { 37 | /* Data accessed frequently first: prof, ticker and small bins. */ 38 | uint64_t prof_accumbytes;/* Cleared after arena_prof_accum(). */ 39 | ticker_t gc_ticker; /* Drives incremental GC. */ 40 | /* 41 | * The pointer stacks associated with tbins follow as a contiguous 42 | * array. During tcache initialization, the avail pointer in each 43 | * element of tbins is initialized to point to the proper offset within 44 | * this array. 45 | */ 46 | tcache_bin_t tbins_small[NBINS]; 47 | /* Data accessed less often below. */ 48 | ql_elm(tcache_t) link; /* Used for aggregating stats. */ 49 | arena_t *arena; /* Associated arena. */ 50 | szind_t next_gc_bin; /* Next bin to GC. */ 51 | /* For small bins, fill (ncached_max >> lg_fill_div). */ 52 | uint8_t lg_fill_div[NBINS]; 53 | tcache_bin_t tbins_large[NSIZES-NBINS]; 54 | }; 55 | 56 | /* Linkage for list of available (previously used) explicit tcache IDs. */ 57 | struct tcaches_s { 58 | union { 59 | tcache_t *tcache; 60 | tcaches_t *next; 61 | }; 62 | }; 63 | 64 | #endif /* JEMALLOC_INTERNAL_TCACHE_STRUCTS_H */ 65 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/views/graph/MDPerThreadView.mm: -------------------------------------------------------------------------------- 1 | // 2 | // MDPerThreadView.m 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/4/1. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #include 10 | #import "MDPerThreadView.h" 11 | #include "StrokeLayer.hpp" 12 | 13 | typedef MD::PairStrokeLayer TimeSizeLayer; 14 | 15 | @implementation MDPerThreadView { 16 | MD::PerThreadData::memory_list_type_ptr _lines; 17 | std::shared_ptr _lineLayer; 18 | double _minX; 19 | } 20 | 21 | - (instancetype)initWithFrame:(CGRect)frame 22 | { 23 | self = [super initWithFrame:frame]; 24 | if (self) { 25 | _lineLayer = std::make_shared(); 26 | _lineLayer->setEdges(MD::Edges(20, 100, 20, 100)); 27 | _lineLayer->setColor(1, 0, 0); 28 | 29 | _xAxis->setName("Time"); 30 | 31 | _yAxis->setName("Mem(log2)"); 32 | 33 | // _yAxis->anchors().setFormatter([](auto f) { 34 | // std::strstream s; 35 | // s << "2^" << f; 36 | // return s.str(); 37 | // }); 38 | // 39 | // __weak typeof(self) weakSelf = self; 40 | // _xAxis->anchors().setFormatter([weakSelf](auto f) -> const char* { 41 | // if (weakSelf) { 42 | // __strong typeof(weakSelf) strongSelf = weakSelf; 43 | // double min = strongSelf->_minX; 44 | // std::strstream s; 45 | // s << int((f - min)/1000); 46 | // return s.str(); 47 | // } 48 | // return ""; 49 | // }); 50 | } 51 | return self; 52 | } 53 | 54 | - (void)setPerThreadData:(MD::PerThreadData::memory_list_type_ptr)data { 55 | if (data->size() > 2) { 56 | _lines = data; 57 | _lineLayer->setLine(_lines); 58 | _lineLayer->setXRange({CGFloat(_lines->at(0).first), CGFloat(_lines->at(_lines->size() - 1).first)}); 59 | 60 | CGFloat max = log(1024*1024*100); 61 | _lineLayer->setYRange({CGFloat(0), CGFloat(max)}); 62 | _minX = CGFloat(_lines->at(0).first); 63 | 64 | [self setNeedsRebuildCanvas]; 65 | } 66 | } 67 | 68 | - (void)rebuildCanvas { 69 | [super rebuildCanvas]; 70 | 71 | auto cvs = [self canvas]; 72 | cvs->AddLayer(_lineLayer); 73 | cvs->AddLayer(_xAxis); 74 | cvs->AddLayer(_yAxis); 75 | } 76 | 77 | @end 78 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/drawable/Layer.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Layer.cpp 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/29. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #include 10 | #include "Layer.hpp" 11 | #include "CanvasLayer.h" 12 | 13 | namespace MD { 14 | 15 | void Layer::AddLayer(std::shared_ptr layer) noexcept { 16 | if (layer->superLayer()) { 17 | layer->superLayer()->RemoveLayer(layer); 18 | } 19 | layer->super_layer_ = this; 20 | auto i = std::find(sub_layers_.begin(), sub_layers_.end(), layer); 21 | if (i != sub_layers_.end()) { 22 | sub_layers_.erase(i); 23 | } 24 | sub_layers_.emplace_back(layer); 25 | } 26 | 27 | void Layer::RemoveLayer(Layer* layer) noexcept { 28 | auto idx = std::find_if(sub_layers_.begin(), sub_layers_.end(), [=](auto& l) { 29 | return l.get() == layer; 30 | }); 31 | if (idx != sub_layers_.end()) { 32 | layer->super_layer_ = nullptr; 33 | sub_layers_.erase(idx); 34 | } 35 | } 36 | 37 | void Layer::RemoveLayer(std::shared_ptr &layer) noexcept { 38 | RemoveLayer(layer.get()); 39 | } 40 | 41 | void Layer::RemoveLayers() noexcept { 42 | std::for_each(sub_layers_.begin(), sub_layers_.end(), [](auto& layer) { 43 | layer->super_layer_ = nullptr; 44 | }); 45 | sub_layers_.clear(); 46 | } 47 | 48 | void Layer::Draw() { 49 | std::for_each(sub_layers_.begin(), sub_layers_.end(), [](auto& layer) { 50 | layer->Draw(); 51 | }); 52 | } 53 | 54 | CanvasLayer* Layer::canvas() const { 55 | if (this->isCanvas()) { 56 | return static_cast(const_cast(this)); 57 | } 58 | if (super_layer_ == nullptr) { 59 | return nullptr; 60 | } 61 | return super_layer_->canvas(); 62 | } 63 | 64 | Rect Layer::absoluteFrame() const { 65 | CanvasLayer* cvs = canvas(); 66 | if (cvs == nullptr) { 67 | return Rect(); 68 | } 69 | if (this == cvs) { 70 | return cvs->frame(); 71 | } 72 | 73 | auto layer = superLayer(); 74 | auto e = edges_; 75 | while (layer != cvs) { 76 | e += layer->edges(); 77 | } 78 | return cvs->frame().inset(e); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/detector/MallocPool.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // MallocPool.hpp 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/28. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #ifndef MallocPool_hpp 10 | #define MallocPool_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "Allocator.hpp" 18 | #include "MallocStorage.hpp" 19 | #include "MallocCollector.hpp" 20 | 21 | namespace MD { 22 | class MallocPool { 23 | public: 24 | typedef std::vector> pool_type; 25 | 26 | const pool_type& runningPool() const { return running_pool_; } 27 | const pool_type& deadPool() const { return dead_pool_; } 28 | 29 | void Attach(MemoryStorage *s) { 30 | std::lock_guard l(lock_); 31 | running_pool_.emplace_back(s); 32 | } 33 | 34 | void Detatch(MemoryStorage *s) { 35 | std::lock_guard l(lock_); 36 | auto idx = std::find(running_pool_.begin(), running_pool_.end(), s); 37 | if (idx != running_pool_.end()) { 38 | dead_pool_.emplace_back(std::move(*idx)); 39 | running_pool_.erase(idx); 40 | } 41 | } 42 | 43 | void ClearAll() { 44 | std::lock_guard l(lock_); 45 | 46 | std::for_each(dead_pool_.begin(), dead_pool_.end(), [](MemoryStorage *s) { 47 | delete s; 48 | }); 49 | dead_pool_.clear(); 50 | 51 | std::for_each(running_pool_.begin(), running_pool_.end(), [](MemoryStorage *s) { 52 | s->clear(); 53 | }); 54 | } 55 | 56 | void EnumerateRunningPool(std::function cb) { 57 | std::lock_guard l(lock_); 58 | 59 | std::for_each(running_pool_.begin(), running_pool_.end(), cb); 60 | } 61 | 62 | void EnumerateDeadPool(std::function cb) { 63 | std::lock_guard l(lock_); 64 | 65 | std::for_each(dead_pool_.begin(), dead_pool_.end(), cb); 66 | } 67 | 68 | private: 69 | std::mutex lock_; 70 | pool_type running_pool_; 71 | pool_type dead_pool_; 72 | }; 73 | } 74 | 75 | #endif /* MallocPool_hpp */ 76 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/jemalloc_typedefs.h: -------------------------------------------------------------------------------- 1 | typedef struct extent_hooks_s extent_hooks_t; 2 | 3 | /* 4 | * void * 5 | * extent_alloc(extent_hooks_t *extent_hooks, void *new_addr, size_t size, 6 | * size_t alignment, bool *zero, bool *commit, unsigned arena_ind); 7 | */ 8 | typedef void *(extent_alloc_t)(extent_hooks_t *, void *, size_t, size_t, bool *, 9 | bool *, unsigned); 10 | 11 | /* 12 | * bool 13 | * extent_dalloc(extent_hooks_t *extent_hooks, void *addr, size_t size, 14 | * bool committed, unsigned arena_ind); 15 | */ 16 | typedef bool (extent_dalloc_t)(extent_hooks_t *, void *, size_t, bool, 17 | unsigned); 18 | 19 | /* 20 | * void 21 | * extent_destroy(extent_hooks_t *extent_hooks, void *addr, size_t size, 22 | * bool committed, unsigned arena_ind); 23 | */ 24 | typedef void (extent_destroy_t)(extent_hooks_t *, void *, size_t, bool, 25 | unsigned); 26 | 27 | /* 28 | * bool 29 | * extent_commit(extent_hooks_t *extent_hooks, void *addr, size_t size, 30 | * size_t offset, size_t length, unsigned arena_ind); 31 | */ 32 | typedef bool (extent_commit_t)(extent_hooks_t *, void *, size_t, size_t, size_t, 33 | unsigned); 34 | 35 | /* 36 | * bool 37 | * extent_decommit(extent_hooks_t *extent_hooks, void *addr, size_t size, 38 | * size_t offset, size_t length, unsigned arena_ind); 39 | */ 40 | typedef bool (extent_decommit_t)(extent_hooks_t *, void *, size_t, size_t, 41 | size_t, unsigned); 42 | 43 | /* 44 | * bool 45 | * extent_purge(extent_hooks_t *extent_hooks, void *addr, size_t size, 46 | * size_t offset, size_t length, unsigned arena_ind); 47 | */ 48 | typedef bool (extent_purge_t)(extent_hooks_t *, void *, size_t, size_t, size_t, 49 | unsigned); 50 | 51 | /* 52 | * bool 53 | * extent_split(extent_hooks_t *extent_hooks, void *addr, size_t size, 54 | * size_t size_a, size_t size_b, bool committed, unsigned arena_ind); 55 | */ 56 | typedef bool (extent_split_t)(extent_hooks_t *, void *, size_t, size_t, size_t, 57 | bool, unsigned); 58 | 59 | /* 60 | * bool 61 | * extent_merge(extent_hooks_t *extent_hooks, void *addr_a, size_t size_a, 62 | * void *addr_b, size_t size_b, bool committed, unsigned arena_ind); 63 | */ 64 | typedef bool (extent_merge_t)(extent_hooks_t *, void *, size_t, void *, size_t, 65 | bool, unsigned); 66 | 67 | struct extent_hooks_s { 68 | extent_alloc_t *alloc; 69 | extent_dalloc_t *dalloc; 70 | extent_destroy_t *destroy; 71 | extent_commit_t *commit; 72 | extent_decommit_t *decommit; 73 | extent_purge_t *purge_lazy; 74 | extent_purge_t *purge_forced; 75 | extent_split_t *split; 76 | extent_merge_t *merge; 77 | }; 78 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/jemalloc_typedefs.h.in: -------------------------------------------------------------------------------- 1 | typedef struct extent_hooks_s extent_hooks_t; 2 | 3 | /* 4 | * void * 5 | * extent_alloc(extent_hooks_t *extent_hooks, void *new_addr, size_t size, 6 | * size_t alignment, bool *zero, bool *commit, unsigned arena_ind); 7 | */ 8 | typedef void *(extent_alloc_t)(extent_hooks_t *, void *, size_t, size_t, bool *, 9 | bool *, unsigned); 10 | 11 | /* 12 | * bool 13 | * extent_dalloc(extent_hooks_t *extent_hooks, void *addr, size_t size, 14 | * bool committed, unsigned arena_ind); 15 | */ 16 | typedef bool (extent_dalloc_t)(extent_hooks_t *, void *, size_t, bool, 17 | unsigned); 18 | 19 | /* 20 | * void 21 | * extent_destroy(extent_hooks_t *extent_hooks, void *addr, size_t size, 22 | * bool committed, unsigned arena_ind); 23 | */ 24 | typedef void (extent_destroy_t)(extent_hooks_t *, void *, size_t, bool, 25 | unsigned); 26 | 27 | /* 28 | * bool 29 | * extent_commit(extent_hooks_t *extent_hooks, void *addr, size_t size, 30 | * size_t offset, size_t length, unsigned arena_ind); 31 | */ 32 | typedef bool (extent_commit_t)(extent_hooks_t *, void *, size_t, size_t, size_t, 33 | unsigned); 34 | 35 | /* 36 | * bool 37 | * extent_decommit(extent_hooks_t *extent_hooks, void *addr, size_t size, 38 | * size_t offset, size_t length, unsigned arena_ind); 39 | */ 40 | typedef bool (extent_decommit_t)(extent_hooks_t *, void *, size_t, size_t, 41 | size_t, unsigned); 42 | 43 | /* 44 | * bool 45 | * extent_purge(extent_hooks_t *extent_hooks, void *addr, size_t size, 46 | * size_t offset, size_t length, unsigned arena_ind); 47 | */ 48 | typedef bool (extent_purge_t)(extent_hooks_t *, void *, size_t, size_t, size_t, 49 | unsigned); 50 | 51 | /* 52 | * bool 53 | * extent_split(extent_hooks_t *extent_hooks, void *addr, size_t size, 54 | * size_t size_a, size_t size_b, bool committed, unsigned arena_ind); 55 | */ 56 | typedef bool (extent_split_t)(extent_hooks_t *, void *, size_t, size_t, size_t, 57 | bool, unsigned); 58 | 59 | /* 60 | * bool 61 | * extent_merge(extent_hooks_t *extent_hooks, void *addr_a, size_t size_a, 62 | * void *addr_b, size_t size_b, bool committed, unsigned arena_ind); 63 | */ 64 | typedef bool (extent_merge_t)(extent_hooks_t *, void *, size_t, void *, size_t, 65 | bool, unsigned); 66 | 67 | struct extent_hooks_s { 68 | extent_alloc_t *alloc; 69 | extent_dalloc_t *dalloc; 70 | extent_destroy_t *destroy; 71 | extent_commit_t *commit; 72 | extent_decommit_t *decommit; 73 | extent_purge_t *purge_lazy; 74 | extent_purge_t *purge_forced; 75 | extent_split_t *split; 76 | extent_merge_t *merge; 77 | }; 78 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/qr.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_QR_H 2 | #define JEMALLOC_INTERNAL_QR_H 3 | 4 | /* Ring definitions. */ 5 | #define qr(a_type) \ 6 | struct { \ 7 | a_type *qre_next; \ 8 | a_type *qre_prev; \ 9 | } 10 | 11 | /* Ring functions. */ 12 | #define qr_new(a_qr, a_field) do { \ 13 | (a_qr)->a_field.qre_next = (a_qr); \ 14 | (a_qr)->a_field.qre_prev = (a_qr); \ 15 | } while (0) 16 | 17 | #define qr_next(a_qr, a_field) ((a_qr)->a_field.qre_next) 18 | 19 | #define qr_prev(a_qr, a_field) ((a_qr)->a_field.qre_prev) 20 | 21 | #define qr_before_insert(a_qrelm, a_qr, a_field) do { \ 22 | (a_qr)->a_field.qre_prev = (a_qrelm)->a_field.qre_prev; \ 23 | (a_qr)->a_field.qre_next = (a_qrelm); \ 24 | (a_qr)->a_field.qre_prev->a_field.qre_next = (a_qr); \ 25 | (a_qrelm)->a_field.qre_prev = (a_qr); \ 26 | } while (0) 27 | 28 | #define qr_after_insert(a_qrelm, a_qr, a_field) do { \ 29 | (a_qr)->a_field.qre_next = (a_qrelm)->a_field.qre_next; \ 30 | (a_qr)->a_field.qre_prev = (a_qrelm); \ 31 | (a_qr)->a_field.qre_next->a_field.qre_prev = (a_qr); \ 32 | (a_qrelm)->a_field.qre_next = (a_qr); \ 33 | } while (0) 34 | 35 | #define qr_meld(a_qr_a, a_qr_b, a_type, a_field) do { \ 36 | a_type *t; \ 37 | (a_qr_a)->a_field.qre_prev->a_field.qre_next = (a_qr_b); \ 38 | (a_qr_b)->a_field.qre_prev->a_field.qre_next = (a_qr_a); \ 39 | t = (a_qr_a)->a_field.qre_prev; \ 40 | (a_qr_a)->a_field.qre_prev = (a_qr_b)->a_field.qre_prev; \ 41 | (a_qr_b)->a_field.qre_prev = t; \ 42 | } while (0) 43 | 44 | /* 45 | * qr_meld() and qr_split() are functionally equivalent, so there's no need to 46 | * have two copies of the code. 47 | */ 48 | #define qr_split(a_qr_a, a_qr_b, a_type, a_field) \ 49 | qr_meld((a_qr_a), (a_qr_b), a_type, a_field) 50 | 51 | #define qr_remove(a_qr, a_field) do { \ 52 | (a_qr)->a_field.qre_prev->a_field.qre_next \ 53 | = (a_qr)->a_field.qre_next; \ 54 | (a_qr)->a_field.qre_next->a_field.qre_prev \ 55 | = (a_qr)->a_field.qre_prev; \ 56 | (a_qr)->a_field.qre_next = (a_qr); \ 57 | (a_qr)->a_field.qre_prev = (a_qr); \ 58 | } while (0) 59 | 60 | #define qr_foreach(var, a_qr, a_field) \ 61 | for ((var) = (a_qr); \ 62 | (var) != NULL; \ 63 | (var) = (((var)->a_field.qre_next != (a_qr)) \ 64 | ? (var)->a_field.qre_next : NULL)) 65 | 66 | #define qr_reverse_foreach(var, a_qr, a_field) \ 67 | for ((var) = ((a_qr) != NULL) ? qr_prev(a_qr, a_field) : NULL; \ 68 | (var) != NULL; \ 69 | (var) = (((var) != (a_qr)) \ 70 | ? (var)->a_field.qre_prev : NULL)) 71 | 72 | #endif /* JEMALLOC_INTERNAL_QR_H */ 73 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/jemalloc_internal_inlines_b.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_INLINES_B_H 2 | #define JEMALLOC_INTERNAL_INLINES_B_H 3 | 4 | #include "jemalloc/internal/rtree.h" 5 | 6 | /* Choose an arena based on a per-thread value. */ 7 | static inline arena_t * 8 | arena_choose_impl(tsd_t *tsd, arena_t *arena, bool internal) { 9 | arena_t *ret; 10 | 11 | if (arena != NULL) { 12 | return arena; 13 | } 14 | 15 | /* During reentrancy, arena 0 is the safest bet. */ 16 | if (unlikely(tsd_reentrancy_level_get(tsd) > 0)) { 17 | return arena_get(tsd_tsdn(tsd), 0, true); 18 | } 19 | 20 | ret = internal ? tsd_iarena_get(tsd) : tsd_arena_get(tsd); 21 | if (unlikely(ret == NULL)) { 22 | ret = arena_choose_hard(tsd, internal); 23 | assert(ret); 24 | if (tcache_available(tsd)) { 25 | tcache_t *tcache = tcache_get(tsd); 26 | if (tcache->arena != NULL) { 27 | /* See comments in tcache_data_init().*/ 28 | assert(tcache->arena == 29 | arena_get(tsd_tsdn(tsd), 0, false)); 30 | if (tcache->arena != ret) { 31 | tcache_arena_reassociate(tsd_tsdn(tsd), 32 | tcache, ret); 33 | } 34 | } else { 35 | tcache_arena_associate(tsd_tsdn(tsd), tcache, 36 | ret); 37 | } 38 | } 39 | } 40 | 41 | /* 42 | * Note that for percpu arena, if the current arena is outside of the 43 | * auto percpu arena range, (i.e. thread is assigned to a manually 44 | * managed arena), then percpu arena is skipped. 45 | */ 46 | if (have_percpu_arena && PERCPU_ARENA_ENABLED(opt_percpu_arena) && 47 | !internal && (arena_ind_get(ret) < 48 | percpu_arena_ind_limit(opt_percpu_arena)) && (ret->last_thd != 49 | tsd_tsdn(tsd))) { 50 | unsigned ind = percpu_arena_choose(); 51 | if (arena_ind_get(ret) != ind) { 52 | percpu_arena_update(tsd, ind); 53 | ret = tsd_arena_get(tsd); 54 | } 55 | ret->last_thd = tsd_tsdn(tsd); 56 | } 57 | 58 | return ret; 59 | } 60 | 61 | static inline arena_t * 62 | arena_choose(tsd_t *tsd, arena_t *arena) { 63 | return arena_choose_impl(tsd, arena, false); 64 | } 65 | 66 | static inline arena_t * 67 | arena_ichoose(tsd_t *tsd, arena_t *arena) { 68 | return arena_choose_impl(tsd, arena, true); 69 | } 70 | 71 | static inline bool 72 | arena_is_auto(arena_t *arena) { 73 | assert(narenas_auto > 0); 74 | return (arena_ind_get(arena) < narenas_auto); 75 | } 76 | 77 | JEMALLOC_ALWAYS_INLINE extent_t * 78 | iealloc(tsdn_t *tsdn, const void *ptr) { 79 | rtree_ctx_t rtree_ctx_fallback; 80 | rtree_ctx_t *rtree_ctx = tsdn_rtree_ctx(tsdn, &rtree_ctx_fallback); 81 | 82 | return rtree_extent_read(tsdn, &extents_rtree, rtree_ctx, 83 | (uintptr_t)ptr, true); 84 | } 85 | 86 | #endif /* JEMALLOC_INTERNAL_INLINES_B_H */ 87 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/pages.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_PAGES_EXTERNS_H 2 | #define JEMALLOC_INTERNAL_PAGES_EXTERNS_H 3 | 4 | /* Page size. LG_PAGE is determined by the configure script. */ 5 | #ifdef PAGE_MASK 6 | # undef PAGE_MASK 7 | #endif 8 | #define PAGE ((size_t)(1U << LG_PAGE)) 9 | #define PAGE_MASK ((size_t)(PAGE - 1)) 10 | /* Return the page base address for the page containing address a. */ 11 | #define PAGE_ADDR2BASE(a) \ 12 | ((void *)((uintptr_t)(a) & ~PAGE_MASK)) 13 | /* Return the smallest pagesize multiple that is >= s. */ 14 | #define PAGE_CEILING(s) \ 15 | (((s) + PAGE_MASK) & ~PAGE_MASK) 16 | 17 | /* Huge page size. LG_HUGEPAGE is determined by the configure script. */ 18 | #define HUGEPAGE ((size_t)(1U << LG_HUGEPAGE)) 19 | #define HUGEPAGE_MASK ((size_t)(HUGEPAGE - 1)) 20 | /* Return the huge page base address for the huge page containing address a. */ 21 | #define HUGEPAGE_ADDR2BASE(a) \ 22 | ((void *)((uintptr_t)(a) & ~HUGEPAGE_MASK)) 23 | /* Return the smallest pagesize multiple that is >= s. */ 24 | #define HUGEPAGE_CEILING(s) \ 25 | (((s) + HUGEPAGE_MASK) & ~HUGEPAGE_MASK) 26 | 27 | /* PAGES_CAN_PURGE_LAZY is defined if lazy purging is supported. */ 28 | #if defined(_WIN32) || defined(JEMALLOC_PURGE_MADVISE_FREE) 29 | # define PAGES_CAN_PURGE_LAZY 30 | #endif 31 | /* 32 | * PAGES_CAN_PURGE_FORCED is defined if forced purging is supported. 33 | * 34 | * The only supported way to hard-purge on Windows is to decommit and then 35 | * re-commit, but doing so is racy, and if re-commit fails it's a pain to 36 | * propagate the "poisoned" memory state. Since we typically decommit as the 37 | * next step after purging on Windows anyway, there's no point in adding such 38 | * complexity. 39 | */ 40 | #if !defined(_WIN32) && ((defined(JEMALLOC_PURGE_MADVISE_DONTNEED) && \ 41 | defined(JEMALLOC_PURGE_MADVISE_DONTNEED_ZEROS)) || \ 42 | defined(JEMALLOC_MAPS_COALESCE)) 43 | # define PAGES_CAN_PURGE_FORCED 44 | #endif 45 | 46 | static const bool pages_can_purge_lazy = 47 | #ifdef PAGES_CAN_PURGE_LAZY 48 | true 49 | #else 50 | false 51 | #endif 52 | ; 53 | static const bool pages_can_purge_forced = 54 | #ifdef PAGES_CAN_PURGE_FORCED 55 | true 56 | #else 57 | false 58 | #endif 59 | ; 60 | 61 | void *pages_map(void *addr, size_t size, size_t alignment, bool *commit); 62 | void pages_unmap(void *addr, size_t size); 63 | bool pages_commit(void *addr, size_t size); 64 | bool pages_decommit(void *addr, size_t size); 65 | bool pages_purge_lazy(void *addr, size_t size); 66 | bool pages_purge_forced(void *addr, size_t size); 67 | bool pages_huge(void *addr, size_t size); 68 | bool pages_nohuge(void *addr, size_t size); 69 | bool pages_boot(void); 70 | 71 | #endif /* JEMALLOC_INTERNAL_PAGES_EXTERNS_H */ 72 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/atomic.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_ATOMIC_H 2 | #define JEMALLOC_INTERNAL_ATOMIC_H 3 | 4 | #define ATOMIC_INLINE static inline 5 | 6 | #if defined(JEMALLOC_GCC_ATOMIC_ATOMICS) 7 | # include "jemalloc/internal/atomic_gcc_atomic.h" 8 | #elif defined(JEMALLOC_GCC_SYNC_ATOMICS) 9 | # include "jemalloc/internal/atomic_gcc_sync.h" 10 | #elif defined(_MSC_VER) 11 | # include "jemalloc/internal/atomic_msvc.h" 12 | #elif defined(JEMALLOC_C11_ATOMICS) 13 | # include "jemalloc/internal/atomic_c11.h" 14 | #else 15 | # error "Don't have atomics implemented on this platform." 16 | #endif 17 | 18 | /* 19 | * This header gives more or less a backport of C11 atomics. The user can write 20 | * JEMALLOC_GENERATE_ATOMICS(type, short_type, lg_sizeof_type); to generate 21 | * counterparts of the C11 atomic functions for type, as so: 22 | * JEMALLOC_GENERATE_ATOMICS(int *, pi, 3); 23 | * and then write things like: 24 | * int *some_ptr; 25 | * atomic_pi_t atomic_ptr_to_int; 26 | * atomic_store_pi(&atomic_ptr_to_int, some_ptr, ATOMIC_RELAXED); 27 | * int *prev_value = atomic_exchange_pi(&ptr_to_int, NULL, ATOMIC_ACQ_REL); 28 | * assert(some_ptr == prev_value); 29 | * and expect things to work in the obvious way. 30 | * 31 | * Also included (with naming differences to avoid conflicts with the standard 32 | * library): 33 | * atomic_fence(atomic_memory_order_t) (mimics C11's atomic_thread_fence). 34 | * ATOMIC_INIT (mimics C11's ATOMIC_VAR_INIT). 35 | */ 36 | 37 | /* 38 | * Pure convenience, so that we don't have to type "atomic_memory_order_" 39 | * quite so often. 40 | */ 41 | #define ATOMIC_RELAXED atomic_memory_order_relaxed 42 | #define ATOMIC_ACQUIRE atomic_memory_order_acquire 43 | #define ATOMIC_RELEASE atomic_memory_order_release 44 | #define ATOMIC_ACQ_REL atomic_memory_order_acq_rel 45 | #define ATOMIC_SEQ_CST atomic_memory_order_seq_cst 46 | 47 | /* 48 | * Not all platforms have 64-bit atomics. If we do, this #define exposes that 49 | * fact. 50 | */ 51 | #if (LG_SIZEOF_PTR == 3 || LG_SIZEOF_INT == 3) 52 | # define JEMALLOC_ATOMIC_U64 53 | #endif 54 | 55 | JEMALLOC_GENERATE_ATOMICS(void *, p, LG_SIZEOF_PTR) 56 | 57 | /* 58 | * There's no actual guarantee that sizeof(bool) == 1, but it's true on the only 59 | * platform that actually needs to know the size, MSVC. 60 | */ 61 | JEMALLOC_GENERATE_ATOMICS(bool, b, 0) 62 | 63 | JEMALLOC_GENERATE_INT_ATOMICS(unsigned, u, LG_SIZEOF_INT) 64 | 65 | JEMALLOC_GENERATE_INT_ATOMICS(size_t, zu, LG_SIZEOF_PTR) 66 | 67 | JEMALLOC_GENERATE_INT_ATOMICS(ssize_t, zd, LG_SIZEOF_PTR) 68 | 69 | JEMALLOC_GENERATE_INT_ATOMICS(uint32_t, u32, 2) 70 | 71 | #ifdef JEMALLOC_ATOMIC_U64 72 | JEMALLOC_GENERATE_INT_ATOMICS(uint64_t, u64, 3) 73 | #endif 74 | 75 | #undef ATOMIC_INLINE 76 | 77 | #endif /* JEMALLOC_INTERNAL_ATOMIC_H */ 78 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/ql.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_QL_H 2 | #define JEMALLOC_INTERNAL_QL_H 3 | 4 | #include "jemalloc/internal/qr.h" 5 | 6 | /* List definitions. */ 7 | #define ql_head(a_type) \ 8 | struct { \ 9 | a_type *qlh_first; \ 10 | } 11 | 12 | #define ql_head_initializer(a_head) {NULL} 13 | 14 | #define ql_elm(a_type) qr(a_type) 15 | 16 | /* List functions. */ 17 | #define ql_new(a_head) do { \ 18 | (a_head)->qlh_first = NULL; \ 19 | } while (0) 20 | 21 | #define ql_elm_new(a_elm, a_field) qr_new((a_elm), a_field) 22 | 23 | #define ql_first(a_head) ((a_head)->qlh_first) 24 | 25 | #define ql_last(a_head, a_field) \ 26 | ((ql_first(a_head) != NULL) \ 27 | ? qr_prev(ql_first(a_head), a_field) : NULL) 28 | 29 | #define ql_next(a_head, a_elm, a_field) \ 30 | ((ql_last(a_head, a_field) != (a_elm)) \ 31 | ? qr_next((a_elm), a_field) : NULL) 32 | 33 | #define ql_prev(a_head, a_elm, a_field) \ 34 | ((ql_first(a_head) != (a_elm)) ? qr_prev((a_elm), a_field) \ 35 | : NULL) 36 | 37 | #define ql_before_insert(a_head, a_qlelm, a_elm, a_field) do { \ 38 | qr_before_insert((a_qlelm), (a_elm), a_field); \ 39 | if (ql_first(a_head) == (a_qlelm)) { \ 40 | ql_first(a_head) = (a_elm); \ 41 | } \ 42 | } while (0) 43 | 44 | #define ql_after_insert(a_qlelm, a_elm, a_field) \ 45 | qr_after_insert((a_qlelm), (a_elm), a_field) 46 | 47 | #define ql_head_insert(a_head, a_elm, a_field) do { \ 48 | if (ql_first(a_head) != NULL) { \ 49 | qr_before_insert(ql_first(a_head), (a_elm), a_field); \ 50 | } \ 51 | ql_first(a_head) = (a_elm); \ 52 | } while (0) 53 | 54 | #define ql_tail_insert(a_head, a_elm, a_field) do { \ 55 | if (ql_first(a_head) != NULL) { \ 56 | qr_before_insert(ql_first(a_head), (a_elm), a_field); \ 57 | } \ 58 | ql_first(a_head) = qr_next((a_elm), a_field); \ 59 | } while (0) 60 | 61 | #define ql_remove(a_head, a_elm, a_field) do { \ 62 | if (ql_first(a_head) == (a_elm)) { \ 63 | ql_first(a_head) = qr_next(ql_first(a_head), a_field); \ 64 | } \ 65 | if (ql_first(a_head) != (a_elm)) { \ 66 | qr_remove((a_elm), a_field); \ 67 | } else { \ 68 | ql_first(a_head) = NULL; \ 69 | } \ 70 | } while (0) 71 | 72 | #define ql_head_remove(a_head, a_type, a_field) do { \ 73 | a_type *t = ql_first(a_head); \ 74 | ql_remove((a_head), t, a_field); \ 75 | } while (0) 76 | 77 | #define ql_tail_remove(a_head, a_type, a_field) do { \ 78 | a_type *t = ql_last(a_head, a_field); \ 79 | ql_remove((a_head), t, a_field); \ 80 | } while (0) 81 | 82 | #define ql_foreach(a_var, a_head, a_field) \ 83 | qr_foreach((a_var), ql_first(a_head), a_field) 84 | 85 | #define ql_reverse_foreach(a_var, a_head, a_field) \ 86 | qr_reverse_foreach((a_var), ql_first(a_head), a_field) 87 | 88 | #endif /* JEMALLOC_INTERNAL_QL_H */ 89 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/mutex_prof.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_MUTEX_PROF_H 2 | #define JEMALLOC_INTERNAL_MUTEX_PROF_H 3 | 4 | #include "jemalloc/internal/atomic.h" 5 | #include "jemalloc/internal/nstime.h" 6 | #include "jemalloc/internal/tsd_types.h" 7 | 8 | #define MUTEX_PROF_GLOBAL_MUTEXES \ 9 | OP(background_thread) \ 10 | OP(ctl) \ 11 | OP(prof) 12 | 13 | typedef enum { 14 | #define OP(mtx) global_prof_mutex_##mtx, 15 | MUTEX_PROF_GLOBAL_MUTEXES 16 | #undef OP 17 | mutex_prof_num_global_mutexes 18 | } mutex_prof_global_ind_t; 19 | 20 | #define MUTEX_PROF_ARENA_MUTEXES \ 21 | OP(large) \ 22 | OP(extent_avail) \ 23 | OP(extents_dirty) \ 24 | OP(extents_muzzy) \ 25 | OP(extents_retained) \ 26 | OP(decay_dirty) \ 27 | OP(decay_muzzy) \ 28 | OP(base) \ 29 | OP(tcache_list) 30 | 31 | typedef enum { 32 | #define OP(mtx) arena_prof_mutex_##mtx, 33 | MUTEX_PROF_ARENA_MUTEXES 34 | #undef OP 35 | mutex_prof_num_arena_mutexes 36 | } mutex_prof_arena_ind_t; 37 | 38 | #define MUTEX_PROF_COUNTERS \ 39 | OP(num_ops, uint64_t) \ 40 | OP(num_wait, uint64_t) \ 41 | OP(num_spin_acq, uint64_t) \ 42 | OP(num_owner_switch, uint64_t) \ 43 | OP(total_wait_time, uint64_t) \ 44 | OP(max_wait_time, uint64_t) \ 45 | OP(max_num_thds, uint32_t) 46 | 47 | typedef enum { 48 | #define OP(counter, type) mutex_counter_##counter, 49 | MUTEX_PROF_COUNTERS 50 | #undef OP 51 | mutex_prof_num_counters 52 | } mutex_prof_counter_ind_t; 53 | 54 | typedef struct { 55 | /* 56 | * Counters touched on the slow path, i.e. when there is lock 57 | * contention. We update them once we have the lock. 58 | */ 59 | /* Total time (in nano seconds) spent waiting on this mutex. */ 60 | nstime_t tot_wait_time; 61 | /* Max time (in nano seconds) spent on a single lock operation. */ 62 | nstime_t max_wait_time; 63 | /* # of times have to wait for this mutex (after spinning). */ 64 | uint64_t n_wait_times; 65 | /* # of times acquired the mutex through local spinning. */ 66 | uint64_t n_spin_acquired; 67 | /* Max # of threads waiting for the mutex at the same time. */ 68 | uint32_t max_n_thds; 69 | /* Current # of threads waiting on the lock. Atomic synced. */ 70 | atomic_u32_t n_waiting_thds; 71 | 72 | /* 73 | * Data touched on the fast path. These are modified right after we 74 | * grab the lock, so it's placed closest to the end (i.e. right before 75 | * the lock) so that we have a higher chance of them being on the same 76 | * cacheline. 77 | */ 78 | /* # of times the mutex holder is different than the previous one. */ 79 | uint64_t n_owner_switches; 80 | /* Previous mutex holder, to facilitate n_owner_switches. */ 81 | tsdn_t *prev_owner; 82 | /* # of lock() operations in total. */ 83 | uint64_t n_lock_ops; 84 | } mutex_prof_data_t; 85 | 86 | #endif /* JEMALLOC_INTERNAL_MUTEX_PROF_H */ 87 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/detector/MallocCollector.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // MallocCollector.cpp 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/27. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "ThreadLocal.hpp" 14 | #include "MallocStorage.hpp" 15 | #include "MallocCollector.hpp" 16 | #include "MallocWrapZone.hpp" 17 | #include "MemoryDetector.hpp" 18 | 19 | namespace MD { 20 | int64_t CollectorChecker::max() { 21 | return MemoryDetector::GetInstance()->max_data_count(); 22 | } 23 | void CollectorChecker::overflow(MemoryStorage* storage) { 24 | MemoryDetector::GetInstance()->DataOverflowNotifaction(); 25 | } 26 | 27 | namespace Wrap { 28 | static pthread_key_t key_; 29 | 30 | pthread_key_t key() { 31 | return key_; 32 | } 33 | 34 | void deallocate(void *p) { 35 | MemoryStorage *s = reinterpret_cast(p); 36 | s->end(); 37 | 38 | MemoryDetector::GetInstance()->pool().Detatch(s); 39 | } 40 | 41 | struct InitKey { 42 | InitKey() { 43 | pthread_key_create(&key_, deallocate); 44 | } 45 | }; 46 | static class InitKey initKey_; 47 | 48 | struct Constructor { 49 | MemoryStorage* operator()() { 50 | pthread_t pid = pthread_self(); 51 | auto p = new MemoryStorage(pid); 52 | 53 | if (pthread_main_np()) { 54 | p->setMainThread(); 55 | } 56 | 57 | char buf[128] = {0}; 58 | pthread_getname_np(pid, buf, sizeof(buf)); 59 | p->setName(buf); 60 | 61 | MemoryDetector::GetInstance()->pool().Attach(p); 62 | return p; 63 | } 64 | }; 65 | 66 | class ThreadStore : public ThreadLocal { 67 | public: 68 | ThreadStore() : ThreadLocal(key()) {} 69 | }; 70 | 71 | void *malloc(malloc_zone_t *zone, size_t size) { 72 | malloc_zone_t* orig_zone = MemoryDetector::GetInstance()->wrap_zones().orig_zone_value(zone); 73 | if (MemoryDetector::GetInstance()->isEnabled()) { 74 | ThreadStore s; 75 | MemoryCollector c(s.value()); 76 | c.set(zone, Action::Malloc, size); 77 | void *p = orig_zone->malloc(zone, size); 78 | 79 | return p; 80 | } 81 | else { 82 | void *p = orig_zone->malloc(zone, size); 83 | 84 | return p; 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Zones/jemalloc/src/sz.c: -------------------------------------------------------------------------------- 1 | #include "jemalloc/internal/jemalloc_preamble.h" 2 | #include "jemalloc/internal/sz.h" 3 | 4 | JEMALLOC_ALIGNED(CACHELINE) 5 | const size_t sz_pind2sz_tab[NPSIZES+1] = { 6 | #define PSZ_yes(lg_grp, ndelta, lg_delta) \ 7 | (((ZU(1)<name = name; 12 | witness->rank = rank; 13 | witness->comp = comp; 14 | witness->opaque = opaque; 15 | } 16 | 17 | static void 18 | witness_lock_error_impl(const witness_list_t *witnesses, 19 | const witness_t *witness) { 20 | witness_t *w; 21 | 22 | malloc_printf(": Lock rank order reversal:"); 23 | ql_foreach(w, witnesses, link) { 24 | malloc_printf(" %s(%u)", w->name, w->rank); 25 | } 26 | malloc_printf(" %s(%u)\n", witness->name, witness->rank); 27 | abort(); 28 | } 29 | witness_lock_error_t *JET_MUTABLE witness_lock_error = witness_lock_error_impl; 30 | 31 | static void 32 | witness_owner_error_impl(const witness_t *witness) { 33 | malloc_printf(": Should own %s(%u)\n", witness->name, 34 | witness->rank); 35 | abort(); 36 | } 37 | witness_owner_error_t *JET_MUTABLE witness_owner_error = 38 | witness_owner_error_impl; 39 | 40 | static void 41 | witness_not_owner_error_impl(const witness_t *witness) { 42 | malloc_printf(": Should not own %s(%u)\n", witness->name, 43 | witness->rank); 44 | abort(); 45 | } 46 | witness_not_owner_error_t *JET_MUTABLE witness_not_owner_error = 47 | witness_not_owner_error_impl; 48 | 49 | static void 50 | witness_depth_error_impl(const witness_list_t *witnesses, 51 | witness_rank_t rank_inclusive, unsigned depth) { 52 | witness_t *w; 53 | 54 | malloc_printf(": Should own %u lock%s of rank >= %u:", depth, 55 | (depth != 1) ? "s" : "", rank_inclusive); 56 | ql_foreach(w, witnesses, link) { 57 | malloc_printf(" %s(%u)", w->name, w->rank); 58 | } 59 | malloc_printf("\n"); 60 | abort(); 61 | } 62 | witness_depth_error_t *JET_MUTABLE witness_depth_error = 63 | witness_depth_error_impl; 64 | 65 | void 66 | witnesses_cleanup(witness_tsd_t *witness_tsd) { 67 | witness_assert_lockless(witness_tsd_tsdn(witness_tsd)); 68 | 69 | /* Do nothing. */ 70 | } 71 | 72 | void 73 | witness_prefork(witness_tsd_t *witness_tsd) { 74 | if (!config_debug) { 75 | return; 76 | } 77 | witness_tsd->forking = true; 78 | } 79 | 80 | void 81 | witness_postfork_parent(witness_tsd_t *witness_tsd) { 82 | if (!config_debug) { 83 | return; 84 | } 85 | witness_tsd->forking = false; 86 | } 87 | 88 | void 89 | witness_postfork_child(witness_tsd_t *witness_tsd) { 90 | if (!config_debug) { 91 | return; 92 | } 93 | #ifndef JEMALLOC_MUTEX_INIT_CB 94 | witness_list_t *witnesses; 95 | 96 | witnesses = &witness_tsd->witnesses; 97 | ql_new(witnesses); 98 | #endif 99 | witness_tsd->forking = false; 100 | } 101 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/analysis/AnalysisBySize.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // AnalysisBySize.hpp 3 | // DDMallocDetector 4 | // 5 | // Created by daniel on 2018/4/1. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #ifndef AnalysisBySize_hpp 10 | #define AnalysisBySize_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "AnalysisTask.hpp" 17 | #include "AnalysisHelper.h" 18 | 19 | namespace MD { 20 | 21 | template> 22 | class AnalysisBySize final : public AnalysisTask { 23 | public: 24 | // 25 | typedef std::pair item_type; 26 | typedef std::vector list_type; 27 | typedef std::shared_ptr list_type_ptr; 28 | 29 | struct ThreadInfo { 30 | list_type_ptr list; 31 | std::string name; 32 | std::int64_t min_size = 0, max_size = 0; 33 | 34 | private: 35 | friend class AnalysisBySize; 36 | void count(std::size_t size) { 37 | auto prev = list->begin(); 38 | for (auto i = list->begin(); i != list->end(); prev = i, ++i) { 39 | if (size < (*i).first) { 40 | (*prev).second += 1; 41 | break; 42 | } 43 | } 44 | } 45 | }; 46 | typedef std::vector thread_info_list_type; 47 | 48 | AnalysisBySize(std::size_t min, std::size_t max) 49 | : min_(std::max(std::size_t(1), min)), max_(max), step_value_(_S()(min_, max_)) { 50 | } 51 | 52 | std::shared_ptr data() { 53 | return thread_info_list_; 54 | } 55 | protected: 56 | void Run() override; 57 | list_type_ptr MakeEmptyList() { 58 | auto list = std::make_shared(); 59 | std::for_each(step_value_.begin(), step_value_.end(), [&](auto s) { 60 | list->push_back(std::make_pair(s, std::size_t(0))); 61 | }); 62 | return list; 63 | } 64 | 65 | private: 66 | std::size_t min_ = 0; 67 | std::size_t max_ = 0; 68 | std::shared_ptr thread_info_list_ = std::make_shared(); 69 | std::vector step_value_; 70 | }; 71 | 72 | 73 | template 74 | void AnalysisBySize<_S>::Run() { 75 | auto func = [&](auto s) { 76 | ThreadInfo threadInfo; 77 | threadInfo.name = s->name(); 78 | threadInfo.list = MakeEmptyList(); 79 | std::for_each(s->data().begin(), s->data().end(), [&](auto& mem) { 80 | threadInfo.count(mem.size); 81 | threadInfo.min_size = std::min(threadInfo.min_size, mem.size); 82 | threadInfo.max_size = std::max(threadInfo.max_size, mem.size); 83 | }); 84 | thread_info_list_->emplace_back(std::move(threadInfo)); 85 | }; 86 | pool().EnumerateRunningPool(func); 87 | pool().EnumerateDeadPool(func); 88 | } 89 | } 90 | 91 | #endif /* AnalysisBySize_hpp */ 92 | -------------------------------------------------------------------------------- /JemallocDemo/JemallocDemo.xcodeproj/xcshareddata/xcschemes/jemalloc.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 72 | 73 | 74 | 75 | 77 | 78 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /Zones/jemalloc/include/jemalloc/internal/mutex_pool.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_MUTEX_POOL_H 2 | #define JEMALLOC_INTERNAL_MUTEX_POOL_H 3 | 4 | #include "jemalloc/internal/hash.h" 5 | #include "jemalloc/internal/mutex.h" 6 | #include "jemalloc/internal/witness.h" 7 | 8 | /* We do mod reductions by this value, so it should be kept a power of 2. */ 9 | #define MUTEX_POOL_SIZE 256 10 | 11 | typedef struct mutex_pool_s mutex_pool_t; 12 | struct mutex_pool_s { 13 | malloc_mutex_t mutexes[MUTEX_POOL_SIZE]; 14 | }; 15 | 16 | bool mutex_pool_init(mutex_pool_t *pool, const char *name, witness_rank_t rank); 17 | 18 | /* Internal helper - not meant to be called outside this module. */ 19 | static inline malloc_mutex_t * 20 | mutex_pool_mutex(mutex_pool_t *pool, uintptr_t key) { 21 | size_t hash_result[2]; 22 | hash(&key, sizeof(key), 0xd50dcc1b, hash_result); 23 | return &pool->mutexes[hash_result[0] % MUTEX_POOL_SIZE]; 24 | } 25 | 26 | static inline void 27 | mutex_pool_assert_not_held(tsdn_t *tsdn, mutex_pool_t *pool) { 28 | for (int i = 0; i < MUTEX_POOL_SIZE; i++) { 29 | malloc_mutex_assert_not_owner(tsdn, &pool->mutexes[i]); 30 | } 31 | } 32 | 33 | /* 34 | * Note that a mutex pool doesn't work exactly the way an embdedded mutex would. 35 | * You're not allowed to acquire mutexes in the pool one at a time. You have to 36 | * acquire all the mutexes you'll need in a single function call, and then 37 | * release them all in a single function call. 38 | */ 39 | 40 | static inline void 41 | mutex_pool_lock(tsdn_t *tsdn, mutex_pool_t *pool, uintptr_t key) { 42 | mutex_pool_assert_not_held(tsdn, pool); 43 | 44 | malloc_mutex_t *mutex = mutex_pool_mutex(pool, key); 45 | malloc_mutex_lock(tsdn, mutex); 46 | } 47 | 48 | static inline void 49 | mutex_pool_unlock(tsdn_t *tsdn, mutex_pool_t *pool, uintptr_t key) { 50 | malloc_mutex_t *mutex = mutex_pool_mutex(pool, key); 51 | malloc_mutex_unlock(tsdn, mutex); 52 | 53 | mutex_pool_assert_not_held(tsdn, pool); 54 | } 55 | 56 | static inline void 57 | mutex_pool_lock2(tsdn_t *tsdn, mutex_pool_t *pool, uintptr_t key1, 58 | uintptr_t key2) { 59 | mutex_pool_assert_not_held(tsdn, pool); 60 | 61 | malloc_mutex_t *mutex1 = mutex_pool_mutex(pool, key1); 62 | malloc_mutex_t *mutex2 = mutex_pool_mutex(pool, key2); 63 | if ((uintptr_t)mutex1 < (uintptr_t)mutex2) { 64 | malloc_mutex_lock(tsdn, mutex1); 65 | malloc_mutex_lock(tsdn, mutex2); 66 | } else if ((uintptr_t)mutex1 == (uintptr_t)mutex2) { 67 | malloc_mutex_lock(tsdn, mutex1); 68 | } else { 69 | malloc_mutex_lock(tsdn, mutex2); 70 | malloc_mutex_lock(tsdn, mutex1); 71 | } 72 | } 73 | 74 | static inline void 75 | mutex_pool_unlock2(tsdn_t *tsdn, mutex_pool_t *pool, uintptr_t key1, 76 | uintptr_t key2) { 77 | malloc_mutex_t *mutex1 = mutex_pool_mutex(pool, key1); 78 | malloc_mutex_t *mutex2 = mutex_pool_mutex(pool, key2); 79 | if (mutex1 == mutex2) { 80 | malloc_mutex_unlock(tsdn, mutex1); 81 | } else { 82 | malloc_mutex_unlock(tsdn, mutex1); 83 | malloc_mutex_unlock(tsdn, mutex2); 84 | } 85 | 86 | mutex_pool_assert_not_held(tsdn, pool); 87 | } 88 | 89 | static inline void 90 | mutex_pool_assert_owner(tsdn_t *tsdn, mutex_pool_t *pool, uintptr_t key) { 91 | malloc_mutex_assert_owner(tsdn, mutex_pool_mutex(pool, key)); 92 | } 93 | 94 | #endif /* JEMALLOC_INTERNAL_MUTEX_POOL_H */ 95 | -------------------------------------------------------------------------------- /DDMallocDetector/MallocDetector/Classes/drawable/StrokeLayerHelper.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // StrokeLayer.hpp 3 | // cfunction 4 | // 5 | // Created by hzduanjiashun on 2018/3/29. 6 | // Copyright © 2018年 Daniel. All rights reserved. 7 | // 8 | 9 | #ifndef StrokeLayerHelper_hpp 10 | #define StrokeLayerHelper_hpp 11 | 12 | namespace MD { 13 | template 14 | struct ValueRange { 15 | _T min; 16 | _T max; 17 | 18 | ValueRange() = default; 19 | ValueRange(const ValueRange&) = default; 20 | ValueRange(_T min, _T max) : min(min), max(max) {} 21 | ValueRange(_T&& min, _T&& max) : min(min), max(max) {} 22 | ValueRange(std::initializer_list<_T> l) : min(*l.begin()), max(*(l.begin() + 1)) {} 23 | }; 24 | typedef ValueRange FloatRange; 25 | 26 | template 27 | struct AvarageLocation final { 28 | public: 29 | AvarageLocation(Rect& r, FloatRange& x, FloatRange& y, std::size_t count) 30 | : r_(r), x_(r.left()), 31 | yHeight_(y.max - y.min), count_(count), 32 | deltaX_(count > 1 ? r.width()/(count-1) : 0) { 33 | 34 | } 35 | 36 | Float x(_V& v) { 37 | Float r = x_; 38 | x_ += deltaX_; 39 | return r; 40 | } 41 | Float y(_V& v) { 42 | return r_.bottom() - (Float(v) / yHeight_ * r_.size.height); 43 | } 44 | private: 45 | Rect& r_; 46 | Float yHeight_; 47 | Float deltaX_; 48 | std::size_t count_; 49 | Float x_ = 0; 50 | }; 51 | 52 | // x以真实值位置排布 53 | template> 54 | struct PairLocation final { 55 | public: 56 | PairLocation(Rect& r, FloatRange& x, FloatRange& y, std::size_t count) 57 | : r_(r), yHeight_(y.max - y.min), xWidth_(x.max - x.min), xRange_(x), yRange_(y) {} 58 | 59 | Float x(_V& v) { 60 | return (Float(v.first) - xRange_.min) * r_.width() / xWidth_ + r_.left(); 61 | } 62 | Float y(_V& v) { 63 | return r_.bottom() - (Float(v.second) - yRange_.min) * r_.height() / yHeight_; 64 | } 65 | 66 | private: 67 | Rect& r_; 68 | Float yHeight_; 69 | Float xWidth_; 70 | FloatRange xRange_; 71 | FloatRange yRange_; 72 | }; 73 | 74 | // x以线性排布 75 | template> 76 | struct PairLinearLocation final { 77 | public: 78 | PairLinearLocation(Rect& r, FloatRange& x, FloatRange& y, std::size_t count) 79 | : r_(r), yHeight_(y.max - y.min), yRange_(y), x_(r.left()), deltaX_(count > 1 ? r.width()/(count-1) : 0) {} 80 | 81 | Float x(_V& v) { 82 | Float r = x_; 83 | x_ += deltaX_; 84 | return r; 85 | } 86 | Float y(_V& v) { 87 | return r_.bottom() - (Float(v.second) - yRange_.min) * r_.height() / yHeight_; 88 | } 89 | 90 | private: 91 | Rect& r_; 92 | Float yHeight_; 93 | FloatRange yRange_; 94 | Float x_ = 0; 95 | Float deltaX_; 96 | }; 97 | } 98 | 99 | #endif // StrokeLayerHelper_hpp 100 | -------------------------------------------------------------------------------- /DDMallocDetector/DDMallocDetector.xcodeproj/xcshareddata/xcschemes/MallocDetector.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 72 | 73 | 74 | 75 | 77 | 78 | 81 | 82 | 83 | --------------------------------------------------------------------------------