Bug 98498 - REGRESSION: Rapid memory growth calling DOM APIs with large strings
Summary: REGRESSION: Rapid memory growth calling DOM APIs with large strings
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: DOM (show other bugs)
Version: 528+ (Nightly build)
Hardware: All All
: P2 Normal
Assignee: Andreas Kling
URL:
Keywords: HasReduction, InRadar, Regression
Depends on:
Blocks:
 
Reported: 2012-10-05 01:50 PDT by Elliott Sprehn
Modified: 2012-10-12 12:19 PDT (History)
12 users (show)

See Also:


Attachments
Baseline memory growth (632 bytes, text/html)
2012-10-05 01:52 PDT, Elliott Sprehn
no flags Details
Webkit and Chrome (549 bytes, text/html)
2012-10-05 01:53 PDT, Elliott Sprehn
no flags Details
Chrome only (581 bytes, text/html)
2012-10-05 01:54 PDT, Elliott Sprehn
no flags Details
Patch (1.62 KB, patch)
2012-10-12 11:55 PDT, Andreas Kling
andersca: review+
buildbot: commit-queue-
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Elliott Sprehn 2012-10-05 01:50:56 PDT
Calling DOM APIs like querySelector, querySelectorAll or getElementsByTagName cause rapid memory growth when called with ever increasingly large strings.

getElementsByTagName: Reproduces in Chrome Canary and all the way back to Chrome 22, but not in Chrome 20. I don't have Chrome 21. Does *not* reproduce in WebKit nightly (r130451 ) or Safari (6.0.1 (8536.26.14)).

querySelectorAll: Reproduces in Chrome Canary all the way back to Chrome 22, but not Chrome 20 *and* WebKit Nightly r130451.

I don't know why WebKit nightly sees this on QSA but not getElementsByTagName.

Reproduction:
1) Open Activity Monitor.app
2) Load the test case.
3) Watch the memory grow really fast.

Chrome's render process crashes rather quickly with:
Google Chrome Helper(26560,0xacca1a28) malloc: *** mmap(size=8388608) failed (error code=12)
*** error: can't allocate region securely
*** set a breakpoint in malloc_error_break to debug

WebKit nightly seems to flatten out around 2.3GB for me and doesn't crash??
Comment 1 Elliott Sprehn 2012-10-05 01:52:41 PDT
Created attachment 167284 [details]
Baseline memory growth

This just tests memory growth of strings being appended. There's some kind of V8 or Chrome badness here, but it shows a big difference compared to the other test cases.
Comment 2 Elliott Sprehn 2012-10-05 01:53:34 PDT
Created attachment 167285 [details]
Webkit and Chrome

This test consumes memory rapidly in both Chrome and Webkit nightly.
Comment 3 Elliott Sprehn 2012-10-05 01:54:15 PDT
Created attachment 167286 [details]
Chrome only

This test consumes memory rapidly in Chrome but not in Webkit nightly. I'm not sure what's different here.
Comment 4 Elliott Sprehn 2012-10-05 01:56:03 PDT
This is on OS X 10.8.2 non-retina.
Comment 5 Alexey Proskuryakov 2012-10-05 11:29:24 PDT
<rdar://problem/12443926>
Comment 6 Ryosuke Niwa 2012-10-05 11:43:07 PDT
Is it possible that this is caused by our use of AtomicString?
Comment 7 Elliott Sprehn 2012-10-05 11:52:48 PDT
(In reply to comment #6)
> Is it possible that this is caused by our use of AtomicString?

That seems plausible. It's also interesting because doing just regular string appends grows memory normally in shipping Safari, but as soon as you do querySelectorAll(selector) the memory growth slows way down. Is there some kind of rope compaction?
Comment 8 Ryosuke Niwa 2012-10-05 11:54:57 PDT
(In reply to comment #7)
> (In reply to comment #6)
> > Is it possible that this is caused by our use of AtomicString?
> 
> That seems plausible. It's also interesting because doing just regular string appends grows memory normally in shipping Safari, but as soon as you do querySelectorAll(selector) the memory growth slows way down. Is there some kind of rope compaction?

I don't really understand what you mean by this. Could you elaborate a little?
Comment 9 Andreas Kling 2012-10-12 11:07:21 PDT
(In reply to comment #6)
> Is it possible that this is caused by our use of AtomicString?

Yes indeed.

Bytes Used	Count		Symbol Name
1000.25 MB      50.0%	227039	 	 WTF::fastMalloc(unsigned long)
 993.27 MB      49.6%	45393	 	  WTF::StringImpl::create(unsigned char const*, unsigned int)
 993.27 MB      49.6%	45358	 	   WTF::HashTableAddResult<WTF::HashTableIterator<WTF::StringImpl*, WTF::StringImpl*, WTF::IdentityExtractor, WTF::StringHash, WTF::HashTraits<WTF::StringImpl*>, WTF::HashTraits<WTF::StringImpl*> > > WTF::HashTable<WTF::StringImpl*, WTF::StringImpl*, WTF::IdentityExtractor, WTF::StringHash, WTF::HashTraits<WTF::StringImpl*>, WTF::HashTraits<WTF::StringImpl*> >::addPassingHashCode<WTF::HashSetTranslatorAdapter<WTF::LCharBufferTranslator>, WTF::HashTranslatorCharBuffer<unsigned char>, WTF::HashTranslatorCharBuffer<unsigned char> >(WTF::HashTranslatorCharBuffer<unsigned char> const&, WTF::HashTranslatorCharBuffer<unsigned char> const&)
 993.27 MB      49.6%	45358	 	    WTF::AtomicString::add(unsigned char const*, unsigned int)
 993.27 MB      49.6%	45358	 	     cssyyparse(WebCore::CSSParser*)
 993.27 MB      49.6%	45358	 	      WebCore::CSSParser::parseSelector(WTF::String const&, WebCore::CSSSelectorList&)
 993.27 MB      49.6%	45358	 	       WebCore::SelectorQueryCache::add(WTF::AtomicString const&, WebCore::Document*, int&)
 993.27 MB      49.6%	45358	 	        WebCore::Node::querySelector(WTF::AtomicString const&, int&)
 993.27 MB      49.6%	45358	 	         WebCore::jsDocumentPrototypeFunctionQuerySelector(JSC::ExecState*)
Comment 10 Andreas Kling 2012-10-12 11:10:34 PDT
(In reply to comment #9)
> (In reply to comment #6)
> > Is it possible that this is caused by our use of AtomicString?
> 
> Yes indeed.

That, and the fact that SelectorQueryCache appears to grow without bounds.
Comment 11 Andreas Kling 2012-10-12 11:55:24 PDT
Created attachment 168458 [details]
Patch
Comment 12 Anders Carlsson 2012-10-12 11:57:28 PDT
Comment on attachment 168458 [details]
Patch

is bad bogs, gud poch. r=gooby.
Comment 13 Build Bot 2012-10-12 12:00:00 PDT
Comment on attachment 168458 [details]
Patch

Attachment 168458 [details] did not pass mac-ews (mac):
Output: http://queues.webkit.org/results/14283016
Comment 14 Geoffrey Garen 2012-10-12 12:05:28 PDT
Comment on attachment 168458 [details]
Patch

Weak sauce. Random eviction for the win:

m_entries.remove(m_entries.begin());
Comment 15 Geoffrey Garen 2012-10-12 12:06:46 PDT
See subimage() in GraphicsContextCG.cpp for a similar use of this idiom.
Comment 16 WebKit Review Bot 2012-10-12 12:16:41 PDT
Comment on attachment 168458 [details]
Patch

Attachment 168458 [details] did not pass chromium-ews (chromium-xvfb):
Output: http://queues.webkit.org/results/14260940
Comment 17 Andreas Kling 2012-10-12 12:19:53 PDT
Committed r131209: <http://trac.webkit.org/changeset/131209>