WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
Bug 87334
Dynamic hash table in DOMObjectHashTableMap is wrong in multiple threads
https://bugs.webkit.org/show_bug.cgi?id=87334
Summary
Dynamic hash table in DOMObjectHashTableMap is wrong in multiple threads
Leo Yang
Reported
2012-05-23 19:36:45 PDT
Daynamic hash table in DOMObjectHashTableMap is copied from the static table which may be created by other thread and contains thread specific identifiers.
Attachments
Patch
(3.49 KB, patch)
2012-05-23 19:43 PDT
,
Leo Yang
webkit-ews
: commit-queue-
Details
Formatted Diff
Diff
Patch v2
(3.49 KB, patch)
2012-05-23 20:21 PDT
,
Leo Yang
no flags
Details
Formatted Diff
Diff
Patch v3
(35.33 KB, patch)
2012-06-05 21:07 PDT
,
Leo Yang
ggaren
: review-
buildbot
: commit-queue-
Details
Formatted Diff
Diff
Patch v4
(5.32 KB, patch)
2012-06-06 20:22 PDT
,
Leo Yang
no flags
Details
Formatted Diff
Diff
Show Obsolete
(3)
View All
Add attachment
proposed patch, testcase, etc.
Leo Yang
Comment 1
2012-05-23 19:43:40 PDT
Created
attachment 143706
[details]
Patch
Early Warning System Bot
Comment 2
2012-05-23 19:55:02 PDT
Comment on
attachment 143706
[details]
Patch
Attachment 143706
[details]
did not pass qt-wk2-ews (qt): Output:
http://queues.webkit.org/results/12804010
Early Warning System Bot
Comment 3
2012-05-23 19:58:30 PDT
Comment on
attachment 143706
[details]
Patch
Attachment 143706
[details]
did not pass qt-ews (qt): Output:
http://queues.webkit.org/results/12795046
Build Bot
Comment 4
2012-05-23 20:02:54 PDT
Comment on
attachment 143706
[details]
Patch
Attachment 143706
[details]
did not pass mac-ews (mac): Output:
http://queues.webkit.org/results/12805006
Leo Yang
Comment 5
2012-05-23 20:21:55 PDT
Created
attachment 143714
[details]
Patch v2 Rebased to fix build.
Geoffrey Garen
Comment 6
2012-05-24 11:09:28 PDT
Comment on
attachment 143714
[details]
Patch v2 View in context:
https://bugs.webkit.org/attachment.cgi?id=143714&action=review
> Source/WebCore/bindings/js/DOMObjectHashTableMap.h:56 > + // Don't copy dynamic allocated table which may be allocated on other thread and contains thread specific identifiers. > + // For example, a JSEntryArray's hash map was first initialized on a worker thread, and then the user reloaded > + // the page, another worker thread is created due to reload, the dynamic allocated table in *staticTable* is specific > + // to the first worker thread which has died. If the user reload the page again, the dynamic table will be freed > + // and memory corruption will occur. > + table->table = 0;
Is there any other code that copies a JSC::HashTable and needs this fix? I'd prefer to see this logic in a JSC::HashTable copy constructor. That's the best way to ensure that we get this idiom right in all uses of JSC::HashTable.
Alexey Proskuryakov
Comment 7
2012-05-24 12:27:00 PDT
Generally, I would not expect anything with "DOM" in its name to be used from non-main threads. Why is this an exception?
Leo Yang
Comment 8
2012-05-28 02:56:17 PDT
(In reply to
comment #6
)
> (From update of
attachment 143714
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=143714&action=review
> > > Source/WebCore/bindings/js/DOMObjectHashTableMap.h:56 > > + // Don't copy dynamic allocated table which may be allocated on other thread and contains thread specific identifiers. > > + // For example, a JSEntryArray's hash map was first initialized on a worker thread, and then the user reloaded > > + // the page, another worker thread is created due to reload, the dynamic allocated table in *staticTable* is specific > > + // to the first worker thread which has died. If the user reload the page again, the dynamic table will be freed > > + // and memory corruption will occur. > > + table->table = 0; > > Is there any other code that copies a JSC::HashTable and needs this fix?
I don't find.
> > I'd prefer to see this logic in a JSC::HashTable copy constructor. That's the best way to ensure that we get this idiom right in all uses of JSC::HashTable.
Auto-generated Lexer.lut.h is using POD style initializer for JSC::HasTable. It will fail compile if we add a constructor to JSC::HashTable.
Leo Yang
Comment 9
2012-05-28 03:01:00 PDT
(In reply to
comment #7
)
> Generally, I would not expect anything with "DOM" in its name to be used from non-main threads. Why is this an exception?
Actually, many idl files (like WebCore/Modules/filesystem/*.idl) which are not part of "DOM" is being used in multiple thread (for example, in worker thread).
Geoffrey Garen
Comment 10
2012-05-28 14:26:36 PDT
> Auto-generated Lexer.lut.h is using POD style initializer for JSC::HasTable. It will fail compile if we add a constructor to JSC::HashTable.
Is there some reason this can't change?
Leo Yang
Comment 11
2012-05-29 00:10:18 PDT
I'd prefer to keep the default bit-wise copy semantics. The copy constructor is being called implicitly when copy semantics is needed, for example when WTF::HashMap with value type JSC::HashTable moves values internally. For these cases bit-wise copy semantics is the right one. When we really don't need bit-wise copy we can do what we want explicitly just as the patch does.
Alexey Proskuryakov
Comment 12
2012-05-29 10:40:51 PDT
> > Generally, I would not expect anything with "DOM" in its name to be used from non-main threads. Why is this an exception? > > Actually, many idl files (like WebCore/Modules/filesystem/*.idl) which are not part of "DOM" is being used in multiple thread (for example, in worker thread).
OK, but what's DOMObjectHashTableMap anyway? "DOM Object" makes no sense if that includes both nodes and things like DOMFileSystem.idl - these objects have nothing in common.
Geoffrey Garen
Comment 13
2012-05-29 11:08:24 PDT
> The copy constructor is being called implicitly when copy semantics is needed, for example when > WTF::HashMap with value type JSC::HashTable moves values internally. For these cases bit-wise copy > semantics is the right one.
You can get a bitwise copy in HashMap using HashTraits. See, for example, the traits for OwnPtr.
> When we really don't need bit-wise copy we can do what we want explicitly just as the patch does.
My problem is with the word "we" here. Currently, there's no "we". There's only one person in the WebKit project who understands the subtle thread-related problems that can arise when copying a JSC::HashTable: you. If you give JSC::HashTable a copy constructor with correct semantics, along with a comment in the constructor explaining the semantics, then there is a "we": anyone who tries to use the class incorrectly will get a compile error, which will point them at the constructor function, and a comment explaining its behavior.
Leo Yang
Comment 14
2012-06-03 23:37:16 PDT
(In reply to
comment #13
)
> > The copy constructor is being called implicitly when copy semantics is needed, for example when > > WTF::HashMap with value type JSC::HashTable moves values internally. For these cases bit-wise copy > > semantics is the right one. > > You can get a bitwise copy in HashMap using HashTraits. See, for example, the traits for OwnPtr.
I can't see how to get bitwise copy when a copy constructor is not bitwise copy where copy semantics is need for the compiler. For example, how to get bitwise copy for a return value (e.g. return value of HashTraits::passOut) when the copy constructor for JSC::HashTable is not bitwise semantically?
> > > When we really don't need bit-wise copy we can do what we want explicitly just as the patch does. > > My problem is with the word "we" here. Currently, there's no "we". There's only one person in the WebKit project who understands the subtle thread-related problems that can arise when copying a JSC::HashTable: you. > > If you give JSC::HashTable a copy constructor with correct semantics, along with a comment in the constructor explaining the semantics, then there is a "we": anyone who tries to use the class incorrectly will get a compile error, which will point them at the constructor function, and a comment explaining its behavior.
Geoffrey Garen
Comment 15
2012-06-04 12:07:20 PDT
> For example, how to get bitwise copy for a return value (e.g. return value of HashTraits::passOut)
Are you asking how to implement DOMObjectHashTableMap::get()? Since that function already operates in terms of pointers and iterators, I don't think it requires an implementation of HashTraits::passOut(). If you need HashTraits::passOut() for JSC::HashTable, I'd recommend using JSC::HashTable* as the PassOut type, just like OwnPtr<T> uses T* as the PassOut type.
Leo Yang
Comment 16
2012-06-05 21:06:20 PDT
I would choose OwnPtr<JSC::HashTable> as value type of the hash map.
Leo Yang
Comment 17
2012-06-05 21:07:17 PDT
Created
attachment 145927
[details]
Patch v3
Build Bot
Comment 18
2012-06-05 21:42:59 PDT
Comment on
attachment 145927
[details]
Patch v3
Attachment 145927
[details]
did not pass mac-ews (mac): Output:
http://queues.webkit.org/results/12902703
Leo Yang
Comment 19
2012-06-05 22:42:24 PDT
(In reply to
comment #18
)
> (From update of
attachment 145927
[details]
) >
Attachment 145927
[details]
did not pass mac-ews (mac): > Output:
http://queues.webkit.org/results/12902703
It seems that Mac build doesn't allow global initializer for most files. Tools/Scripts/check-for-global-initializers was generating errors.
Geoffrey Garen
Comment 20
2012-06-06 10:54:04 PDT
Comment on
attachment 145927
[details]
Patch v3 View in context:
https://bugs.webkit.org/attachment.cgi?id=145927&action=review
> It seems that Mac build doesn't allow global initializer for most files.
Indeed, it doesn't. I'm surprised that constant initialization requires a global initializer. I guess we have to go back to struct initialization. Let's use a "copy" function in JSC::HashTable instead of a copy constructor.
> Source/JavaScriptCore/runtime/Lookup.h:122 > + { }
WebKit style is to put a newline between "{" and "}".
> Source/JavaScriptCore/runtime/Lookup.h:127 > + if (this == &other) > + return;
Since this is not the assignment operator, this == &other should be impossible.
> Source/JavaScriptCore/runtime/Lookup.h:132 > + compactSize = other.compactSize; > + compactHashSizeMask = other.compactHashSizeMask; > + values = other.values; > + // Don't copy dynamic table since it's thread specific. > + table = 0;
Please use initializer syntax here.
Leo Yang
Comment 21
2012-06-06 20:22:45 PDT
Created
attachment 146181
[details]
Patch v4
Leo Yang
Comment 22
2012-06-12 01:40:28 PDT
Could someone review the updated patch?
Geoffrey Garen
Comment 23
2012-06-12 16:32:45 PDT
Comment on
attachment 146181
[details]
Patch v4 r=me
Geoffrey Garen
Comment 24
2012-06-12 16:33:09 PDT
Would be nice, in clang builds, to delete the copy constructor from the class.
WebKit Review Bot
Comment 25
2012-06-12 17:24:07 PDT
Comment on
attachment 146181
[details]
Patch v4 Clearing flags on attachment: 146181 Committed
r120143
: <
http://trac.webkit.org/changeset/120143
>
WebKit Review Bot
Comment 26
2012-06-12 17:24:14 PDT
All reviewed patches have been landed. Closing bug.
Leo Yang
Comment 27
2012-06-12 19:08:41 PDT
Thanks for your review Geoffrey.
Leo Yang
Comment 28
2012-06-13 19:06:35 PDT
(In reply to
comment #24
)
> Would be nice, in clang builds, to delete the copy constructor from the class.
I'm not familiar with that part. Which files need to be updated?
Geoffrey Garen
Comment 29
2012-06-13 22:25:08 PDT
> I'm not familiar with that part. Which files need to be updated?
The JSC::HashTable declaration would need a declaration similar to the one in <wtf/Noncopyable.h>. The WTF_MAKE_NONCOPYABLE macro shows how to use "delete" syntax to remove the copy constructor for a class. I believe we could do this in clang builds without causing the problems created by adding private or special copy constructors.
Leo Yang
Comment 30
2012-06-14 01:23:00 PDT
(In reply to
comment #29
)
> > I'm not familiar with that part. Which files need to be updated? > > The JSC::HashTable declaration would need a declaration similar to the one in <wtf/Noncopyable.h>. > > The WTF_MAKE_NONCOPYABLE macro shows how to use "delete" syntax to remove the copy constructor for a class. I believe we could do this in clang builds without causing the problems created by adding private or special copy constructors.
I tried to use "HashTable(const HashTable&) = delete;" to delete the copy constructor. But it will cause compiling problems. 1. The deleted copy constructor will prevent POD style initializer. The error message in gcc 4.7 is like "error: could not convert ‘{133, 127, JSC::mainTableValues, 0}’ from ‘<brace-enclosed initializer list>’ to ‘const JSC::HashTable’" and "error: use of deleted function ‘JSC::HashTable::HashTable(const JSC::HashTable&)’". 2. JavaScriptCore/parser/Lexer.cpp is using bitwise copy semantics for m_keywordTable. But this problem can be resolved by adding a copy function that does bitwise copy. In summary, disallowing global initializer (as mentioned in previous comment) prevents us removing POD style initializer that prevents us removing copy constructor.
Geoffrey Garen
Comment 31
2012-06-14 13:09:41 PDT
Darn. Thanks for looking into this.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug