Bug 112303
Summary: | [meta] Reduce startup mallocs | ||
---|---|---|---|
Product: | WebKit | Reporter: | Adam Barth <abarth> |
Component: | WebCore Misc. | Assignee: | Nobody <webkit-unassigned> |
Status: | RESOLVED INVALID | ||
Severity: | Normal | CC: | annevk, ap, benjamin, eric |
Priority: | P2 | ||
Version: | 528+ (Nightly build) | ||
Hardware: | Unspecified | ||
OS: | Unspecified | ||
Bug Depends on: | 112736, 112769, 112831 | ||
Bug Blocks: |
Adam Barth
The profile for startup is has a lot of malloc-related samples. We should reduce the number of mallocs we perform on startup to improve startup performance. Here are the heaviest stacks for malloc on chromium-linux in DumpRenderTree:
- tc_malloc
- 23.76% WTF::fastMalloc(unsigned long)
- 29.95% WTF::StringImpl::createFromLiteral(char const*, unsigned int)
- WTF::AtomicString::addFromLiteralData(char const*, unsigned int)
+ 59.36% WebCore::createQualifiedName(void*, char const*, unsigned int, WTF::AtomicString const&)
+ 29.88% WebCore::EventNames::EventNames()
+ 10.76% WebCore::createQualifiedName(void*, char const*, unsigned int)
- 18.95% WTF::StringImpl::createUninitialized(unsigned int, unsigned char*&)
- 78.44% WTF::StringImpl::create(unsigned char const*, unsigned int)
WTF::StringImpl::create(unsigned char const*)
WTF::String::String(char const*)
WebKit::WebView::removeAllUserContent()
WebTestRunner::TestRunner::reset()
WebTestRunner::TestInterfaces::resetAll()
TestShell::resetTestController()
runTest(TestShell&, TestParams&, std::string const&, bool)
main
__libc_start_main
- 21.56% WTF::StringBuilder::allocateBuffer(unsigned char const*, unsigned int)
WebCore::InspectorValue::toJSONString() const
WebCore::InspectorCompositeState::inspectorStateUpdated()
WebCore::InspectorState::setValue(WTF::String const&, WTF::PassRefPtr<WebCore::InspectorValue>)
WebCore::InspectorDebuggerAgent::InspectorDebuggerAgent(WebCore::InstrumentingAgents*, WebCore::InspectorCompositeState*, WebCore
WebCore::PageDebuggerAgent::PageDebuggerAgent(WebCore::InstrumentingAgents*, WebCore::InspectorCompositeState*, WebCore::Inspecto
WebCore::PageDebuggerAgent::create(WebCore::InstrumentingAgents*, WebCore::InspectorCompositeState*, WebCore::InspectorPageAgent*
WebCore::InspectorController::InspectorController(WebCore::Page*, WebCore::InspectorClient*)
WebCore::InspectorController::create(WebCore::Page*, WebCore::InspectorClient*)
WebCore::Page::Page(WebCore::Page::PageClients&)
WebKit::WebViewImpl::WebViewImpl(WebKit::WebViewClient*)
WebKit::WebView::create(WebKit::WebViewClient*)
TestShell::createNewWindow(WebKit::WebURL const&, DRTDevToolsAgent*, WebTestRunner::WebTestInterfaces*)
TestShell::createMainWindow()
main
__libc_start_main
- 14.18% WebCore::QualifiedName::QualifiedName(WTF::AtomicString const&, WTF::AtomicString const&, WTF::AtomicString const&)
WebCore::createQualifiedName(void*, char const*, unsigned int)
WebCore::SVGNames::init()
WebCore::Frame::create(WebCore::Page*, WebCore::HTMLFrameOwnerElement*, WebCore::FrameLoaderClient*)
WebKit::WebFrameImpl::initializeAsMainFrame(WebCore::Page*)
WebKit::WebViewImpl::initializeMainFrame(WebKit::WebFrameClient*)
TestShell::createNewWindow(WebKit::WebURL const&, DRTDevToolsAgent*, WebTestRunner::WebTestInterfaces*)
TestShell::createMainWindow()
main
__libc_start_main
- 13.44% WTF::Vector<WebCore::MediaPlayerFactory*, 0ul>::expandCapacity(unsigned long)
void WTF::Vector<WebCore::MediaPlayerFactory*, 0ul>::appendSlowCase<WebCore::MediaPlayerFactory*>(WebCore::MediaPlayerFactory* const
WebCore::addMediaEngine(WTF::PassOwnPtr<WebCore::MediaPlayerPrivateInterface> (*)(WebCore::MediaPlayer*), void (*)(WTF::HashSet<WTF:
WebCore::installedMediaEngines(WebCore::RequeryEngineOptions)
WebCore::MediaPlayer::isAvailable()
WebCore::V8DOMWindow::GetTemplate(v8::Isolate*, WebCore::WrapperWorldType)
WebCore::V8PerContextData::constructorForTypeSlowCase(WebCore::WrapperTypeInfo*)
WebCore::V8DOMWindowShell::installDOMWindow()
WebCore::V8DOMWindowShell::initializeIfNeeded()
WebCore::ScriptController::windowShell(WebCore::DOMWrapperWorld*)
WebCore::ScriptController::mainWorldContext(WebCore::Frame*)
WebKit::WebFrameImpl::mainWorldScriptContext() const
WebKit::WebTestingSupport::resetInternalsObject(WebKit::WebFrame*)
TestShell::resetTestController()
runTest(TestShell&, TestParams&, std::string const&, bool)
main
__libc_start_main
+ 11.06% WebCore::CSSValuePool::createValue(double, WebCore::CSSPrimitiveValue::UnitTypes)
+ 5.62% WebCore::ResourceHandle::create(WebCore::NetworkingContext*, WebCore::ResourceRequest const&, WebCore::ResourceHandleClient*, boo
+ 4.21% WTF::CStringBuffer::createUninitialized(unsigned long)
+ 2.59% WebCore::isolatedWorldMap()
+ 18.29% v8::internal::Malloced::New(unsigned long)
13.95% g_malloc
3.74% 0x6e000061746100
+ 3.70% 0x7fffabf1b1e0
3.69% 0x7f7075181995
3.68% 0x7f7075181a55
3.67% FcStrStaticName
3.66% XML_GetBuffer
3.64% 0x7f7075181678
3.35% _xcb_in_read
2.88% __alloc_dir
2.52% _nl_make_l10nflist
Attachments | ||
---|---|---|
Add attachment proposed patch, testcase, etc. |
Benjamin Poulain
I worked on this a couple of month ago. WebCore::createQualifiedName() is already an optimized version for startup time.
There is one more crazy thing we can do about it: instead of allocating all the StringImpl one by one, we could allocated one buffer and build the StringImpl in there.
The other mallocs are new to me.
Adam Barth
I'm going to try to lay out all the StringImpls statically at compile time.
Alexey Proskuryakov
See also: bug 61024.
Note that static allocation of mutable data is quite bad for memory use.
Adam Barth
> Note that static allocation of mutable data is quite bad for memory use.
Is that a concern here? The discussion on that bug seems to be about features that might not be used. The mallocs we're talking about here happen on every startup.
Benjamin Poulain
> Is that a concern here? The discussion on that bug seems to be about features that might not be used. The mallocs we're talking about here happen on every startup.
I think he was just expressing general concerns.
I have wanted those StringImpl to be completely statically built for a while (hashmap and 16bits strings included).
I think if done correctly, we can make the Names initialization almost free.
Benjamin Poulain
(I meant compile time Hash, not HashMap)
Alexey Proskuryakov
Yes, I think that it remains a concern. But I'm sure that improvements can be made while keeping it in mind.
1. We'll need to ensure that the data is allocated contiguously in linked binary, so that touching it doesn't dirty more pages than necessary.
2. Ideally, this static allocation will be done in a way that doesn't immediately make the memory dirty. If it's done this way, touching e.g. one EventName could dirty more pages than necessary.
(1) is could cause a memory use regression from what we have now. (2) can not be a regression, it's an improvement opportunity. Ordering EventNames by how common they are could save some memory.
Anne van Kesteren
Let's close this. Someone would have to do fresh profiling at this point so it's not really meaningful to keep this around.