.size diffs have too much noise in them |
||||
Issue descriptionNoticed some room for improvement when looking at bug 708841. 1. Looks like we should fold together [clone] symbols. 2. Seems to be some random symbols added/removed. I'm unsure as to whether this is due to multiple symbols sharing and address, or from differences in inlining. Attaching two .size files.
,
Apr 11 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/f70d47db0b462dbc08d4d6ae2e633e4e5b0af518 commit f70d47db0b462dbc08d4d6ae2e633e4e5b0af518 Author: agrieve <agrieve@chromium.org> Date: Tue Apr 11 17:48:20 2017 //tools/binary_size: Group [clone] and ** symbols Two types of groups: 1. Those that end with "[clone .part.#]" 2. Star symbols (e.g.: "** symbol gap 3") To handle grouped symbols: * Print(recursive=True) added * Diff() updated to be recursive * Tests updated For the .size files that motivated this change, the diff before had: 355 symbols added (+), 2964 changed (~), 300 removed (-) and after: 345 symbols added (+), 2975 changed (~), 290 removed (-) I was hoping for a bigger reduction, but it turns out the majority of the "noise" is actually from different functions being inlined. This change also changes map2size.py from positional arguments to having: --elf-file, --output-file. It also adds --no-source-paths. These flags make it obvious that the tool can still be used with only a .map file. BUG= 681694 , 708865 Review-Url: https://codereview.chromium.org/2809043003 Cr-Commit-Position: refs/heads/master@{#463678} [modify] https://crrev.com/f70d47db0b462dbc08d4d6ae2e633e4e5b0af518/tools/binary_size/console.py [modify] https://crrev.com/f70d47db0b462dbc08d4d6ae2e633e4e5b0af518/tools/binary_size/create_html_breakdown.py [modify] https://crrev.com/f70d47db0b462dbc08d4d6ae2e633e4e5b0af518/tools/binary_size/describe.py [modify] https://crrev.com/f70d47db0b462dbc08d4d6ae2e633e4e5b0af518/tools/binary_size/file_format.py [modify] https://crrev.com/f70d47db0b462dbc08d4d6ae2e633e4e5b0af518/tools/binary_size/integration_test.py [modify] https://crrev.com/f70d47db0b462dbc08d4d6ae2e633e4e5b0af518/tools/binary_size/map2size.py [modify] https://crrev.com/f70d47db0b462dbc08d4d6ae2e633e4e5b0af518/tools/binary_size/models.py [modify] https://crrev.com/f70d47db0b462dbc08d4d6ae2e633e4e5b0af518/tools/binary_size/testdata/ActualDiff.golden [modify] https://crrev.com/f70d47db0b462dbc08d4d6ae2e633e4e5b0af518/tools/binary_size/testdata/ConsoleNullDiff.golden [add] https://crrev.com/f70d47db0b462dbc08d4d6ae2e633e4e5b0af518/tools/binary_size/testdata/FullDescription.golden [modify] https://crrev.com/f70d47db0b462dbc08d4d6ae2e633e4e5b0af518/tools/binary_size/testdata/Map2Size.golden [modify] https://crrev.com/f70d47db0b462dbc08d4d6ae2e633e4e5b0af518/tools/binary_size/testdata/SymbolGroupMethods.golden [modify] https://crrev.com/f70d47db0b462dbc08d4d6ae2e633e4e5b0af518/tools/binary_size/testdata/test.map
,
Apr 13 2017
The commit in #2 helps this a bit, but I'm not 100% sure the remaining "noise" is from different inlining, or whether it could still be improved by using "nm" to gather all the names for symbols at the same address.
E.g.: nm --print-size | sort shows:
002a479c t $t
002a479d 00000004 t base::internal::LockImpl::Unlock()
002a479d 00000004 t ion::port::Mutex::Unlock()
002a479d 00000004 t rtc::CriticalSection::Leave() const
002a479d 00000004 t sfntly::Lock::Unlock()
002a479d 00000004 t unlock_buffer_pool
002a479d 00000004 t v8::base::Mutex::Unlock()
002a479d 00000004 t v8::base::RecursiveMutex::Unlock()
002a479d 00000004 t WTF::MutexBase::unlock()
002a47a0 t $t
And I've confirmed with codesearch that all of these methods are identical.
Only base::internal::LockImpl::Unlock() shows in the linker .map
Another example:
002a5288 t $t
002a5289 0000001a t scoped_refptr<base::SequencedTaskRunner>::~scoped_refptr()
002a5289 0000001a t scoped_refptr<base::SequencedTaskRunner>::~scoped_refptr()
002a5289 0000001a t scoped_refptr<base::SingleThreadTaskRunner>::~scoped_refptr()
002a5289 0000001a t scoped_refptr<base::SingleThreadTaskRunner>::~scoped_refptr()
002a5289 0000001a t scoped_refptr<base::TaskRunner>::~scoped_refptr()
002a5289 0000001a t scoped_refptr<base::TaskRunner>::~scoped_refptr()
002a5289 0000001a t scoped_refptr<blink::scheduler::internal::TaskQueueImpl>::~scoped_refptr()
002a5289 0000001a t scoped_refptr<blink::scheduler::internal::TaskQueueImpl>::~scoped_refptr()
002a5289 0000001a t scoped_refptr<blink::scheduler::TaskQueue>::~scoped_refptr()
002a5289 0000001a t scoped_refptr<blink::scheduler::TaskQueue>::~scoped_refptr()
002a5289 0000001a t syncer::internal::WeakHandleCoreBase::~WeakHandleCoreBase()
002a5289 0000001a t syncer::internal::WeakHandleCoreBase::~WeakHandleCoreBase()
002a52a4 t $t
Some smaller symbols are actually screens long (hundreds that map to the same address for no-op functions)
Some non-trivial functions also have screens worth of dupes, because they are all template specializations of the same template function for similar classes.
Another example: From map file we have:
560888 t@0x2b72c8 size=4 padding=0 size_without_padding=4
source_path=chrome/common/file_patcher.mojom.cc object_path=chrome/common/mojo_bindings/file_patcher.mojom.o
is_anonymous=0 name=chrome::mojom::FilePatcherStubDispatch::Accept
full_name=chrome::mojom::FilePatcherStubDispatch::Accept(chrome::mojom::FilePatcher*, mojo::Message*)
From nm we have:
002b72c8 t $t
002b72c9 00000004 t about_handler::AboutProtocolHandler::IsSafeRedirectTarget(GURL const&) const
002b72c9 00000004 t AndroidLiveTabContext::IsTabPinned(int) const
002b72c9 00000004 t AndroidLiveTabContext::ReplaceRestoredTab(std::__ndk1::vector<sessions::SerializedNavigationEntry, std::__ndk1::allocator<sessions::SerializedNavigationEntry> > const&, int, bool, st
d::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&, sessions::PlatformSpecificTabData const*, std::__ndk1::basic_string<char, std::__ndk1::char_traits<ch
ar>, std::__ndk1::allocator<char> > const&)
002b72c9 00000004 t android::SceneLayer::ShouldShowBackground()
002b72c9 00000004 t android::TabWebContentsDelegateAndroid::RequestPpapiBrokerPermission(content::WebContents*, GURL const&, base::FilePath const&, base::Callback<void (bool), (base::internal::CopyMode)
1, (base::internal::RepeatMode)1> const&)
002b72c9 00000004 t app_modal::AppModalDialog::IsJavaScriptModalDialog()
002b72c9 00000004 t autofill::AutofillSaveCardInfoBarDelegateMobile::ShouldExpire(infobars::InfoBarDelegate::NavigationDetails const&) const
002b72c9 00000004 t autofill::IsDesktopPlatform()
002b72c9 00000004 t autofill::mojom::AutofillAgentStubDispatch::AcceptWithResponder(autofill::mojom::AutofillAgent*, mojo::Message*, std::__ndk1::unique_ptr<mojo::MessageReceiverWithStatus, std::__ndk1:
:default_delete<mojo::MessageReceiverWithStatus> >)
002b72c9 00000004 t autofill::mojom::AutofillDriverStubDispatch::AcceptWithResponder(autofill::mojom::AutofillDriver*, mojo::Message*, std::__ndk1::unique_ptr<mojo::MessageReceiverWithStatus, std::__ndk1::default_delete<mojo::MessageReceiverWithStatus> >)
002b72c9 00000004 t autofill::mojom::PasswordGenerationAgentStubDispatch::AcceptWithResponder(autofill::mojom::PasswordGenerationAgent*, mojo::Message*, std::__ndk1::unique_ptr<mojo::MessageReceiverWithStatus, std::__ndk1::default_delete<mojo::MessageReceiverWithStatus> >)
002b72c9 00000004 t autofill::mojom::PasswordManagerClientStubDispatch::AcceptWithResponder(autofill::mojom::PasswordManagerClient*, mojo::Message*, std::__ndk1::unique_ptr<mojo::MessageReceiverWithStatus, std::__ndk1::default_delete<mojo::MessageReceiverWithStatus> >)
002b72c9 00000004 t autofill::mojom::PasswordManagerDriverStubDispatch::AcceptWithResponder(autofill::mojom::PasswordManagerDriver*, mojo::Message*, std::__ndk1::unique_ptr<mojo::MessageReceiverWithStatus, std::__ndk1::default_delete<mojo::MessageReceiverWithStatus> >)
002b72c9 00000004 t autofill::PasswordGenerationPopupViewAndroid::IsPointInPasswordBounds(gfx::Point const&)
002b72c9 00000004 t background_loader::BackgroundLoaderContents::CheckMediaAccessPermission(content::WebContents*, GURL const&, content::MediaStreamType)
002b72c9 00000004 t background_loader::BackgroundLoaderContents::ShouldCreateWebContents(content::WebContents*, content::SiteInstance*, int, int, int, content::mojom::WindowContainerType, GURL const&, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&, GURL const&, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&, content::SessionStorageNamespace*)
002b72c9 00000004 t background_loader::BackgroundLoaderContents::ShouldFocusPageAfterCrash()
002b72c9 00000004 t banners::AppBannerManager::IsWebAppInstalled(content::BrowserContext*, GURL const&, GURL const&)
002b72c9 00000004 t base::debug::BeingProfiled()
002b72c9 00000004 t base::debug::GetProfilerAddDynamicSymbolFunc()
002b72c9 00000004 t base::debug::GetProfilerDynamicFunctionEntryHookFunc()
002b72c9 00000004 t base::debug::GetProfilerMoveDynamicSymbolFunc()
002b72c9 00000004 t base::debug::GetProfilerReturnAddrResolutionFunc()
002b72c9 00000004 t base::debug::IsBinaryInstrumented()
002b72c9 00000004 t base::GetDefaultThreadStackSize(pthread_attr_t const&)
002b72c9 00000004 t base::HistogramBase::FindCorruption(base::HistogramSamples const&) const
002b72c9 00000004 t base::Histogram::GetHistogramType() const
002b72c9 00000004 t base::internal::LockImpl::PriorityInheritanceAvailable()
002b72c9 00000004 t base::Pickle::HasAttachments() const
002b72c9 00000004 t base::Pickle::ReadAttachment(base::PickleIterator*, scoped_refptr<base::Pickle::Attachment>*) const
002b72c9 00000004 t base::Pickle::WriteAttachment(scoped_refptr<base::Pickle::Attachment>)
<snip> (high hundreds of lines)
It's not clear whether the map file is stable or not though, because nm's output is sorted by symbol name rather than by address :/.
Just how many duplicate symbols are there?
nm.first3t has just <addr> <size>
nm.first3tu is run through uniq
-rw-r----- 1 agrieve eng 6431020 Apr 12 22:39 nm.first3t
-rw-r----- 1 agrieve eng 4949740 Apr 12 22:39 nm.first3tu
So, map file has only 75% of total symbol names in it, and 25% are identical!
Not sure if it's worth adding all the names to .size symbols, or maybe it's worth at least adding a count of symbols folded together so that we know removing a symbol would not help with code size.
,
Apr 13 2017
Hacked up a version that appends all names to shared symbols, and found that most shared large symbols belong to the same .o file:
Attached dump of "Print(size_info.symbols.WherePathMatches(r'\{shared'), verbose=True)".
Paths have the share count appended to them, and names are join()ed by |<==>|
Here are some interesting parts inline:
-------------------------------------------------------------------
Summary shows that 535kb of symbols in .text are shared. Total .text size is 35.0mb (about 1.5%)
Showing 9,205 symbols with total size: 548692 bytes
.text=535kb .rodata=0 bytes other=0 bytes total=535kb
Number of object files: 3567
-------------------------------------------------------------------
One category of de-dupes show symbols where it looks to be accurate to keep source-file information.
First columns are: running total, type, size
1640 t@0x8f8780 size=1640 padding=0 size_without_padding=1640
source_path=third_party/libvpx/source/libvpx/vpx_dsp/arm/loopfilter_16_neon.asm.S {shared by 2 symbols} object_path=third_party/libvpx/libvpx_assembly_arm.a/loopfilter_16_neon.asm.o {shared}
is_anonymous=0 name=* _mb_lpf_horizontal_edge|<==>|mb_lpf_horizontal_edge
3248 t@0x121faf0 size=1608 padding=0 size_without_padding=1608
source_path=v8/src/compiler/bytecode-analysis.cc {shared by 6 symbols} object_path=v8/v8_base/bytecode-analysis.o {shared}
is_anonymous=0 name=* std::__ndk1::deque<v8::internal::compiler::BytecodeAnalysis::LoopStackEntry, v8::internal::RecyclingZoneAllocator<v8::internal::compiler::BytecodeAnalysis::LoopStackEntry> >::__add_back_capacity()|<==>|std::__ndk1::deque<v8::internal::compiler::GraphReducer::NodeState, v8::internal::RecyclingZoneAllocator<v8::internal::compiler::GraphReducer::NodeState> >::__add_back_capacity()|<==>|std::__ndk1::deque<v8::internal::compiler::MemoryOptimizer::Token, v8::internal::RecyclingZoneAllocator<v8::internal::compiler::MemoryOptimizer::Token> >::__add_back_capacity()|<==>|std::__ndk1::deque<std::__ndk1::pair<v8::internal::compiler::PendingAssessment const*, int>, v8::internal::RecyclingZoneAllocator<std::__ndk1::pair<v8::internal::compiler::PendingAssessment const*, int> > >::__add_back_capacity()|<==>|std::__ndk1::deque<v8::internal::compiler::Node::InputEdges::iterator, v8::internal::RecyclingZoneAllocator<v8::internal::compiler::Node::InputEdges::iterator> >::__add_back_capacity()|<==>|std::__ndk1::deque<v8::internal::compiler::RepresentationSelector::NodeState, v8::internal::RecyclingZoneAllocator<v8::internal::compiler::RepresentationSelector::NodeState> >::__add_back_capacity()
4856 t@0x78ac64 size=1608 padding=0 size_without_padding=1608
source_path=v8/src/compiler/ast-graph-builder.cc {shared by 13 symbols} object_path=v8/v8_base/ast-graph-builder.o {shared}
is_anonymous=0 name=* std::__ndk1::deque<v8::internal::compiler::LivenessAnalyzerBlock*, v8::internal::RecyclingZoneAllocator<v8::internal::compiler::LivenessAnalyzerBlock*> >::__add_back_capacity()|<==>|std::__ndk1::deque<v8::internal::BitVector*, v8::internal::RecyclingZoneAllocator<v8::internal::BitVector*> >::__add_back_capacity()|<==>|std::__ndk1::deque<v8::internal::Handle<v8::internal::Object>, v8::internal::RecyclingZoneAllocator<v8::internal::Handle<v8::internal::Object> > >::__add_back_capacity()|<==>|std::__ndk1::deque<v8::internal::compiler::CodeGenerator::DeoptimizationState*, v8::internal::RecyclingZoneAllocator<v8::internal::compiler::CodeGenerator::DeoptimizationState*> >::__add_back_capacity()|<==>|std::__ndk1::deque<v8::internal::compiler::DeoptimizationExit*, v8::internal::RecyclingZoneAllocator<v8::internal::compiler::DeoptimizationExit*> >::__add_back_capacity()|<==>|std::__ndk1::deque<v8::internal::compiler::Node*, v8::internal::RecyclingZoneAllocator<v8::internal::compiler::Node*> >::__add_back_capacity()|<==>|std::__ndk1::deque<v8::internal::compiler::InstructionScheduler::ScheduleGraphNode*, v8::internal::RecyclingZoneAllocator<v8::internal::compiler::InstructionScheduler::ScheduleGraphNode*> >::__add_back_capacity()|<==>|std::__ndk1::deque<v8::internal::compiler::Instruction*, v8::internal::RecyclingZoneAllocator<v8::internal::compiler::Instruction*> >::__add_back_capacity()|<==>|std::__ndk1::deque<v8::internal::compiler::ReferenceMap*, v8::internal::RecyclingZoneAllocator<v8::internal::compiler::ReferenceMap*> >::__add_back_capacity()|<==>|std::__ndk1::deque<v8::internal::compiler::RpoNumber, v8::internal::RecyclingZoneAllocator<v8::internal::compiler::RpoNumber> >::__add_back_capacity()|<==>|std::__ndk1::deque<int, v8::internal::RecyclingZoneAllocator<int> >::__add_back_capacity()|<==>|std::__ndk1::deque<v8::internal::compiler::BasicBlock*, v8::internal::RecyclingZoneAllocator<v8::internal::compiler::BasicBlock*> >::__add_back_capacity()|<==>|std::__ndk1::deque<v8::internal::Map*, v8::internal::RecyclingZoneAllocator<v8::internal::Map*> >::__add_back_capacity()
6424 t@0x8f8160 size=1568 padding=0 size_without_padding=1568
source_path=third_party/libvpx/source/libvpx/vpx_dsp/arm/intrapred_neon_asm.asm.S {shared by 2 symbols} object_path=third_party/libvpx/libvpx_assembly_arm.a/intrapred_neon_asm.asm.o {shared}
is_anonymous=0 name=* _vpx_v_predictor_4x4_neon|<==>|vpx_v_predictor_4x4_neon
10420 t@0x8f7b48 size=1228 padding=0 size_without_padding=1228
source_path=third_party/opus/celt_pitch_xcorr_arm_gnu.S {shared by 2 symbols} object_path=third_party/opus/libopus.a/celt_pitch_xcorr_arm_gnu.o {shared}
is_anonymous=0 name=* xcorr_kernel_neon|<==>|xcorr_kernel_neon_start
16248 t@0x11ae6bc size=1140 padding=0 size_without_padding=1140
source_path=v8/src/ast/ast-expression-rewriter.cc {shared by 3 symbols} object_path=v8/v8_base/ast-expression-rewriter.o {shared}
is_anonymous=0 name=* v8::internal::AstExpressionRewriter::VisitReturnStatement(v8::internal::ReturnStatement*)|<==>|v8::internal::AstExpressionRewriter::VisitExpressionStatement(v8::internal::ExpressionStatement*)|<==>|v8::internal::AstExpressionRewriter::VisitSloppyBlockFunctionStatement(v8::internal::SloppyBlockFunctionStatement*)
17384 t@0x8faac0 size=1136 padding=0 size_without_padding=1136
source_path= {shared by 2 symbols} object_path=third_party/android_tools/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a/_arm_muldivdf3.o {shared}
is_anonymous=0 name=* __muldf3|<==>|__aeabi_dmul
18456 t@0x8f8de8 size=1072 padding=0 size_without_padding=1072
source_path=third_party/libvpx/source/libvpx/vpx_dsp/arm/loopfilter_4_neon.asm.S {shared by 2 symbols} object_path=third_party/libvpx/libvpx_assembly_arm.a/loopfilter_4_neon.asm.o {shared}
is_anonymous=0 name=* _vpx_lpf_horizontal_4_neon|<==>|vpx_lpf_horizontal_4_neon
19444 t@0x8f9218 size=988 padding=0 size_without_padding=988
source_path=third_party/libvpx/source/libvpx/vpx_dsp/arm/loopfilter_8_neon.asm.S {shared by 2 symbols} object_path=third_party/libvpx/libvpx_assembly_arm.a/loopfilter_8_neon.asm.o {shared}
is_anonymous=0 name=* _vpx_lpf_horizontal_8_neon|<==>|vpx_lpf_horizontal_8_neon
-------------------------------------------------------------------
Next category of de-dupes is ~100 different versions of std::__ndk1::__tree::destroy
7836 t@0x2b2eb8 size=1412 padding=0 size_without_padding=1412
source_path=base/command_line.cc {shared by 53 symbols} object_path=base/base/command_line.o {shared}
is_anonymous=0 name=* std::__ndk1::__tree<std::__ndk1::__value_type<base::BasicStringPiece<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > >, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const*>, std::__ndk1::__map_value_compare<base::BasicStringPiece<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > >, std::__ndk1::__value_type<base::BasicStringPiece<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > >, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const*>, std::__ndk1::less<base::BasicStringPiece<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > > >, true>, std::__ndk1::allocator<std::__ndk1::__value_type<base::BasicStringPiece<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > >, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const*> > >::destroy(std::__ndk1::__tree_node<std::__ndk1::__value_type<base::BasicStringPiece<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > >, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const*>, void*>*)|<==>|std::__ndk1::__tree<unsigned int, std::__ndk1::less<unsigned int>, std::__ndk1::allocator<unsigned int> >::destroy(std::__ndk1::__tree_node<unsigned int, void*>*)|<==>|std::__ndk1::__tree<long long, std::__ndk1::less<long long>, std::__ndk1::allocator<long long> >::destroy(std::__ndk1::__tree_node<long long, void*>*)|<==>| SNIP!
9192 t@0x2e7a38 size=1356 padding=0 size_without_padding=1356
source_path=base/feature_list.cc {shared by 13 symbols} object_path=base/base/feature_list.o {shared}
is_anonymous=0 name=* std::__ndk1::__tree<std::__ndk1::__value_type<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >, base::FeatureList::OverrideEntry>, std::__ndk1::__map_value_compare<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >, std::__ndk1::__value_type<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >, base::FeatureList::OverrideEntry>, std::__ndk1::less<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > >, true>, std::__ndk1::allocator<std::__ndk1::__value_type<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >, base::FeatureList::OverrideEntry> > >::destroy(std::__ndk1::__tree_node<std::__ndk1::__value_type<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >, base::FeatureList::OverrideEntry>, void*>*)|<==>|std::__ndk1::__tree<std::__ndk1::__value_type<std:
11604 t@0x736d7c size=1184 padding=0 size_without_padding=1184
source_path=v8/src/asmjs/asm-typer.cc {shared by 24 symbols} object_path=v8/v8_base/asm-typer.o {shared}
is_anonymous=0 name=* std::__ndk1::__tree<int, std::__ndk1::less<int>, v8::internal::ZoneAllocator<int> >::destroy(std::__ndk1::__tree_node<int, void*>*)|<==>|std::__ndk1::__tree<std::__ndk1::__value_type<int, unsigned int>, std::__ndk1::__map_value_compare<int, std::__ndk1::__value_type<int, unsigned int>, std::__ndk1::less<int>, true>, v8::internal::ZoneAllocator<std::__ndk1::__value_type<int, unsigned int> > >::destroy(std::__ndk1::__tree_node<std::__ndk1::__value_type<int, unsigned int>, void*>*)|<==>|std::
20428 t@0x5112f8 size=984 padding=0 size_without_padding=984
source_path=base/supports_user_data.cc {shared by 3 symbols} object_path=base/base/supports_user_data.o {shared}
is_anonymous=0 name=* std::__ndk1::__tree<std::__ndk1::__value_type<void const*, std::__ndk1::unique_ptr<base::SupportsUserData::Data, std::__ndk1::default_delete<base::SupportsUserData::Data> > >, std::__ndk1::__map_value_compare<void const*, std::__ndk1::__value_type<void const*, std::__ndk1::unique_ptr<base::SupportsUserData::Data, std::__ndk1::default_delete<base::SupportsUserData::Data> > >, std::__ndk1::less<void const*>, true>, std::__ndk1::allocator<std::__ndk1::__value_type<void const*, std::__ndk1::unique_ptr<base::SupportsUserData::Data, std::__ndk1::default_delete<base::SupportsUserData::Data> > > > >::destroy(std::__ndk1::__tree_node<std::__ndk1::__value_type<void const*, std::__ndk1::unique_ptr<base::SupportsUserData::Data, std::__ndk1::default_delete<base::SupportsUserData::Data> > >, void*>*)|<==>|std::__ndk1::__tree<std::__ndk1::__value_type<gfx::Image::RepresentationType, std::__ndk1::unique_ptr<gfx::internal::ImageRep, std::__ndk1::default_delete<gfx::internal::ImageRep> > >, std::__ndk1::__map_value_compare<gfx::Image::RepresentationType, std::__ndk1::__value_type<gfx::Image::RepresentationType, std::__ndk1::unique_ptr<gfx::internal::ImageRep, std::__ndk1::default_delete<gfx::internal::ImageRep> > >, std::__ndk1::less<gfx::Image::RepresentationType>, true>, std::__ndk1::allocator<std::__ndk1::__value_type<gfx::Image::RepresentationType, std::__ndk1::unique_ptr<gfx::internal::ImageRep, std::__ndk1::default_delete<gfx::internal::ImageRep> > > > >::destroy(std::__ndk1::__tree_node<std::__ndk1::__value_type<gfx::Image::RepresentationT
-------------------------------------------------------------------
Next, we have deque, where blame should be spread out:
12772 t@0x2b57ec size=1168 padding=0 size_without_padding=1168
source_path=base/at_exit.cc {shared by 15 symbols} object_path=base/base/at_exit.o {shared}
is_anonymous=0 name=* std::__ndk1::deque<base::Callback<void (), (base::internal::CopyMode)1, (base::internal::RepeatMode)1>, std::__ndk1::allocator<base::Callback<void (), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> > >::__add_back_capacity()|<==>|std::__ndk1::deque<std::__ndk1::unique_ptr<base::internal::Task, std::__ndk1::default_delete<base::internal::Task> >, std::__ndk1::allocator<std::__ndk1::unique_ptr<base::internal::Task, std::__ndk1::default_delete<base::internal::Task> > > >::__add_back_capacity()|<==>|std::__ndk1::deque<std::__ndk1::unique_ptr<cc::DrawPolygon, std::__ndk1::default_delete<cc::DrawPolygon> >, std::__ndk1::allocator<std::__ndk1::unique_ptr<cc::DrawPolygon, std::__ndk1::default_delete<cc::DrawPolygon> > > >::__add_back_capacity()|<==>|std::__ndk1::deque<std::__ndk1::unique_ptr<cc::GLRenderer::SyncQuery, std::__ndk1::default_delete<cc::GLRenderer::SyncQuery> >, std::__ndk1::allocator<std::__ndk1::unique_ptr<cc::GLRenderer::SyncQuery, std::__ndk1::default_delete<cc::GLRenderer::SyncQuery> > > >::__add_back_capacity()|<==>|std::__ndk1::deque<std::__ndk1::unique_ptr<cc::StagingBuffer, std::__ndk1::default_delete<cc::StagingBuffer> >, std::__ndk1::allocator<std::__ndk1::unique_ptr<cc::StagingBuffer, std::__ndk1::default_delete<cc::StagingBuffer> > > >::__add_back_capacity()|<==>|std::__ndk1::deque<v8::internal::CompilationJob*, std::__ndk1::allocator<v8::internal::CompilationJob*> >::__add_back_capacity()|<==>|std::__ndk1::deque<v8::internal::HeapObject*, std::__ndk1::allocator<v8::internal::HeapObject*> >::__add_
13940 t@0x433d18 size=1168 padding=0 size_without_padding=1168
source_path=base/files/file_enumerator_posix.cc {shared by 4 symbols} object_path=base/base/file_enumerator_posix.o {shared}
is_anonymous=0 name=* std::__ndk1::deque<base::FilePath, std::__ndk1::allocator<base::FilePath> >::__add_back_capacity()|<==>|std::__ndk1::deque<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >, std::__ndk1::allocator<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > > >::__add_back_capacity()|<==>|std::__ndk1::deque<std::__ndk1::vector<std::__ndk1::unique_ptr<cc::ResourceProvider::ScopedReadLockGL, std::__ndk1::default_delete<cc::ResourceProvider::ScopedReadLockGL> >, std::__ndk1::allocator<std::__ndk1::unique_ptr<cc::ResourceProvider::ScopedReadLockGL, std::__ndk1::default_delete<cc::ResourceProvider::ScopedReadLockGL> > > >, std::__ndk1::allocator<std::__ndk1::vector<std::__ndk1::unique_ptr<cc::ResourceProvider::ScopedReadLockGL, std::__ndk1::default_delete<cc::ResourceProvider::ScopedReadLockGL> >, std::__ndk1::allocator<std::__ndk1::unique_ptr<cc::ResourceProvider::ScopedReadLockGL, std::__ndk1::default_delete<cc::ResourceProvider::ScopedReadLockGL> > > > > >::__add_back_capacity()|<==>|std::__ndk1::deque<v8::internal::HeapGraphEdge, std::__ndk1::allocator<v8::internal::HeapGraphEdge> >::__add_back_capacity()
15108 t@0x942b28 size=1168 padding=0 size_without_padding=1168
source_path=base/trace_event/trace_log.cc {shared by 3 symbols} object_path=base/base/trace_log.o {shared}
is_anonymous=0 name=* std::__ndk1::deque<base::TimeTicks, std::__ndk1::allocator<base::TimeTicks> >::__add_back_capacity()|<==>|std::__ndk1::deque<v8::internal::TranslatedState::ObjectPosition, std::__ndk1::allocator<v8::internal::TranslatedState::ObjectPosition> >::__add_back_capacity()|<==>|std::__ndk1::deque<std::__ndk1::pair<void (*)(v8::Isolate*, void*), void*>, std::__ndk1::allocator<std::__ndk1::pair<void (*)(v8::Isolate*, void*), void*> > >::__add_back_capacity()
-------------------------------------------------------------------
But then, we have deque, where blame is localized to v8:
22260 t@0x1246edc size=884 padding=0 size_without_padding=884
source_path=v8/src/compiler/int64-lowering.cc {shared by 2 symbols} object_path=v8/v8_base/int64-lowering.o {shared}
is_anonymous=0 name=* std::__ndk1::deque<v8::internal::compiler::Int64Lowering::NodeState, v8::internal::RecyclingZoneAllocator<v8::internal::compiler::Int64Lowering::NodeState> >::__add_back_capacity()|<==>|std::__ndk1::deque<v8::internal::compiler::SimdScalarLowering::NodeState, v8::internal::RecyclingZoneAllocator<v8::internal::compiler::SimdScalarLowering::NodeState> >::__add_back_capacity()
Thus far, this is on 20kb out of 500kb total, and I don't see any great heuristics (other than: _vpx_convolve8_horiz_neon|<==>|vpx_convolve8_horiz_neon, which accounts for 7kb)
,
Apr 21 2017
,
May 1 2017
Here's another source of noise found in: https://bugs.chromium.org/p/chromium/issues/detail?id=716393 + 44 r@0x2a13ba8 24 obj/third_party/WebKit/Source/platform/platform/RecordingImageBufferSurface.o CSWTCH.61 - 20 r@0x2a0f9b8 -24 obj/third_party/WebKit/Source/platform/platform/RecordingImageBufferSurface.o CSWTCH.62 - 4 r@0x2b58888 -16 obj/third_party/WebKit/Source/modules/vr/libvr.a(VRDisplay.o) ._468 + 20 r@0x2b5ca88 16 obj/third_party/WebKit/Source/modules/vr/libvr.a(VRDisplay.o) ._470 - 4 r@0x2b7e148 -16 obj/components/history/content/browser/libbrowser.a(download_conversions.o) CSWTCH.29 - -12 r@0x2a101c0 -16 obj/third_party/WebKit/Source/platform/platform/SkiaUtils.o CSWTCH.31 + 4 r@0x2a143a0 16 obj/third_party/WebKit/Source/platform/platform/SkiaUtils.o CSWTCH.32 + 20 r@0x2b7e120 16 obj/chrome/browser/ui/libui.a(page_info_ui.o) CSWTCH.34
,
May 1 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/e2db5397b49842931f2f2a6b2c666c2a8892fd89 commit e2db5397b49842931f2f2a6b2c666c2a8892fd89 Author: agrieve <agrieve@chromium.org> Date: Mon May 01 18:34:24 2017 supersize: Track symbol aliases and shared symbols An alias is when multiple names map to the same symbol. This happens a lot with small member functions (e.g. getters), as well as with C++ templates. The .map file choses only one name for each symbol, but using nm we can recover the complete list. A shared symbol is one that exists in multiple .o files. The linker map picks one path to attribute the symbol to, but using nm we can recover the complete list of .o files containing the symbol. For aliases, each one is stored as a separate Symbol entry, and a new attribute "pss" returns size / num_aliases. For shared symbols, rather than storing all paths for a symbol, the paths are altered to be the common ancestor. E.g.: /a/b/c.o and /a/d/f.o --> /a/{shared}/2 (2 is the number of paths) For ChromePublic.apk: * 17717 symbols have shared ownership (991402 bytes) * Contains 83869 aliases, mapped to 9209 addresses (550582 bytes) BUG= 708865 Review-Url: https://codereview.chromium.org/2851473003 Cr-Commit-Position: refs/heads/master@{#468362} [modify] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/archive.py [add] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/concurrent.py [modify] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/console.py [modify] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/describe.py [add] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/diff.py [modify] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/file_format.py [modify] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/helpers.py [modify] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/html_report.py [modify] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/integration_test.py [modify] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/linker_map_parser.py [modify] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/main.py [modify] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/models.py [modify] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/ninja_parser.py [add] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/nm.py [modify] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/template/D3SymbolTreeMap.js [modify] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/Archive.golden [add] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/Archive_Elf.golden [add] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/Archive_OutputDirectory.golden [modify] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/Console.golden [rename] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/Diff_Basic.golden [modify] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/Diff_NullDiff.golden [modify] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/FullDescription.golden [modify] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/SymbolGroupMethods.golden [add] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/create-test-size.sh [add] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/mock_output_directory/args.gn [rename] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/mock_output_directory/build.ninja [add] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/mock_output_directory/elf [rename] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/mock_output_directory/sub.ninja [add] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/mock_toolchain/c++filt [add] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/mock_toolchain/git [add] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/mock_toolchain/mock_cppfilt.py [add] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/mock_toolchain/mock_git.py [add] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/mock_toolchain/mock_nm.py [add] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/mock_toolchain/mock_readelf.py [add] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/mock_toolchain/nm [add] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/mock_toolchain/readelf [modify] https://crrev.com/e2db5397b49842931f2f2a6b2c666c2a8892fd89/tools/binary_size/libsupersize/testdata/test.map
,
May 3 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/47f9431d5a69ae9e81faa6472d8b5a188eb63242 commit 47f9431d5a69ae9e81faa6472d8b5a188eb63242 Author: agrieve <agrieve@chromium.org> Date: Wed May 03 18:41:04 2017 supersize: Tweak diff symbol matching for generated symbols E.g. CSWTCH.61 and CSWTCH.62 will now match as long as they are in the same object file. BUG= 708865 , 717550 Review-Url: https://codereview.chromium.org/2857153002 Cr-Commit-Position: refs/heads/master@{#469045} [modify] https://crrev.com/47f9431d5a69ae9e81faa6472d8b5a188eb63242/tools/binary_size/libsupersize/diff.py [modify] https://crrev.com/47f9431d5a69ae9e81faa6472d8b5a188eb63242/tools/binary_size/libsupersize/integration_test.py [modify] https://crrev.com/47f9431d5a69ae9e81faa6472d8b5a188eb63242/tools/binary_size/libsupersize/models.py
,
May 3 2017
All known causes for noise are fixed! Let's file a new one should anything else come up as this is getting a bit hard to follow.
,
May 9 2017
|
||||
►
Sign in to add a comment |
||||
Comment 1 by agrieve@chromium.org
, Apr 6 2017