Chromium Code Reviews| Index: chrome/browser/ui/cocoa/full_size_content_window.mm |
| diff --git a/chrome/browser/ui/cocoa/full_size_content_window.mm b/chrome/browser/ui/cocoa/full_size_content_window.mm |
| index 555c523fa209983c74662b42b9cfb23c12e579ca..988dc129e8bed23f59703151826091e60857b079 100644 |
| --- a/chrome/browser/ui/cocoa/full_size_content_window.mm |
| +++ b/chrome/browser/ui/cocoa/full_size_content_window.mm |
| @@ -4,8 +4,12 @@ |
| #import "chrome/browser/ui/cocoa/full_size_content_window.h" |
| +#include <crt_externs.h> |
| + |
| +#include "base/auto_reset.h" |
| #include "base/logging.h" |
| #include "base/mac/foundation_util.h" |
| +#include "base/mac/scoped_objc_class_swizzler.h" |
| @interface FullSizeContentWindow () |
| @@ -44,10 +48,66 @@ |
| @end |
| +static bool g_disable_symbolication = false; |
| +static IMP g_originalDescriptionWithLocaleImplementation; |
|
erikchen
2016/01/05 23:52:40
I would probably use the same nomenclature as g_di
Robert Sesek
2016/01/06 17:23:51
Yes, full under_scores is the correct way to write
|
| + |
| +@interface FullSizeContentWindowSwizzlingSupport : NSObject |
| +@end |
| + |
| +@implementation FullSizeContentWindowSwizzlingSupport |
| + |
| +// This method replaces [_NSCallStackArray descriptionWithLocale:indent:] via |
| +// swizzling - see +load below. |
| +- (NSString*)descriptionWithLocale:(id)aLocale |
| + indent:(unsigned long long)indent { |
| + return g_disable_symbolication ? |
| + @"" : |
| + g_originalDescriptionWithLocaleImplementation( |
| + self, @selector(descriptionWithLocale:indent:), aLocale, indent); |
| +} |
| + |
| +@end |
| + |
| @implementation FullSizeContentWindow |
| #pragma mark - Lifecycle |
| +// In initWithContentRect:styleMask:backing:defer:, the call to |
| +// [NSView addSubview:positioned:relativeTo:] causes NSWindow to complain that |
| +// an unknown view is being added to it, and to generate a stack trace. |
| +// Not only does this stack trace pollute the console, it can also take hundreds |
| +// of milliseconds to generate (because of symbolication). The AppKit uses an |
| +// _NSCallStackArray to dump the symbols to the console - by swizzling |
| +// descriptionWithLocale:indent: we can disable this output. See |
| +// crbug.com/520373 . |
| ++ (void)load { |
| + // Swizzling should only happen in the browser process. |
| + const char* const* const argv = *_NSGetArgv(); |
| + const int argc = *_NSGetArgc(); |
| + const char kType[] = "--type="; |
| + for (int i = 1; i < argc; ++i) { |
| + const char* arg = argv[i]; |
| + if (strncmp(arg, kType, strlen(kType)) == 0) { |
| + return; |
| + } |
| + } |
| + |
| + static dispatch_once_t onceToken; |
| + dispatch_once(&onceToken, ^{ |
| + Class callStackArrayClass = NSClassFromString(@"_NSCallStackArray"); |
| + Class swizzleClass = [FullSizeContentWindowSwizzlingSupport class]; |
| + SEL targetSelector = @selector(descriptionWithLocale:indent:); |
| + |
| + if (callStackArrayClass) { |
| + CR_DEFINE_STATIC_LOCAL(base::mac::ScopedObjCClassSwizzler, |
| + callStackSuppressor, (callStackArrayClass, |
| + swizzleClass, targetSelector)); |
| + g_originalDescriptionWithLocaleImplementation = |
| + callStackSuppressor.GetOriginalImplementation(); |
| + } |
| + }); |
| +} |
| + |
| - (instancetype)init { |
| NOTREACHED(); |
| return nil; |
| @@ -87,6 +147,13 @@ |
| // it is positioned below the buttons. |
| NSView* superview = [chromeWindowView_ superview]; |
| [chromeWindowView_ removeFromSuperview]; |
| + |
| + // Prevent the AppKit from generating a backtrace to include in it's |
| + // complaint about our upcoming call to addSubview:positioned:relativeTo:. |
| + // See +load for more info. |
| + base::AutoReset<bool> disable_symbolication(&g_disable_symbolication, |
| + true); |
| + |
| [superview addSubview:chromeWindowView_ |
| positioned:NSWindowBelow |
| relativeTo:nil]; |