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
Reported 2013-03-13 17:43:33 PDT
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
Benjamin Poulain
Comment 1 2013-03-13 20:35:29 PDT
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
Comment 2 2013-03-13 21:16:16 PDT
I'm going to try to lay out all the StringImpls statically at compile time.
Alexey Proskuryakov
Comment 3 2013-03-14 09:44:24 PDT
See also: bug 61024. Note that static allocation of mutable data is quite bad for memory use.
Adam Barth
Comment 4 2013-03-14 10:04:19 PDT
> 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
Comment 5 2013-03-14 10:23:58 PDT
> 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
Comment 6 2013-03-14 10:24:38 PDT
(I meant compile time Hash, not HashMap)
Alexey Proskuryakov
Comment 7 2013-03-14 10:30:05 PDT
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
Comment 8 2023-12-25 10:07:22 PST
Let's close this. Someone would have to do fresh profiling at this point so it's not really meaningful to keep this around.
Note You need to log in before you can comment on or make changes to this bug.