RESOLVED FIXED Bug 70862
[MutationObservers] Support characterDataOldValue for characterData mutations
https://bugs.webkit.org/show_bug.cgi?id=70862
Summary [MutationObservers] Support characterDataOldValue for characterData mutations
Adam Klein
Reported 2011-10-25 16:32:24 PDT
[MutationObservers] Support characterDataOldValue for characterData mutations
Attachments
Patch (13.68 KB, patch)
2011-10-28 17:56 PDT, Adam Klein
no flags
Patch (13.66 KB, patch)
2011-10-31 13:11 PDT, Adam Klein
no flags
Patch for landing (13.65 KB, patch)
2011-10-31 16:28 PDT, Adam Klein
no flags
More const String&ification (13.66 KB, patch)
2011-10-31 16:33 PDT, Adam Klein
no flags
Adam Klein
Comment 1 2011-10-28 17:56:22 PDT
Adam Klein
Comment 2 2011-10-31 13:11:36 PDT
Adam Klein
Comment 3 2011-10-31 13:22:31 PDT
Now ready for review. Note that there are FIXMEs in Element.cpp and CharacterData.cpp to factor out the mutationWithNullOldValue logic. Those will be fixed after Rafael lands his attributeFilter patch, as we hope to clean up Node::getRegisteredMutationObserversOfType to return something smarter than a HashMap.
Ojan Vafai
Comment 4 2011-10-31 16:10:48 PDT
Comment on attachment 113077 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=113077&action=review > Source/WebCore/dom/CharacterData.cpp:216 > + RefPtr<MutationRecord> mutation = MutationRecord::createCharacterData(node, isOldValueRequested(observers) ? oldData : 0); Can we create this lazily in the for loop below? That would obviate the need for the isOldValueRequested and would avoid doing a second loop over the observers. I guess you're trying to have a single record for all observers. I think that's fine, but you could invert the way you create mutations...create the null old value record first and create the mutation record with the old value from the one without. It's not a big deal, but it seems the code is less complicated (or am I missing something?) and it avoids another O(n) operation, not that I actually expect that to affect real-world performance.
Adam Klein
Comment 5 2011-10-31 16:16:07 PDT
Comment on attachment 113077 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=113077&action=review >> Source/WebCore/dom/CharacterData.cpp:216 >> + RefPtr<MutationRecord> mutation = MutationRecord::createCharacterData(node, isOldValueRequested(observers) ? oldData : 0); > > Can we create this lazily in the for loop below? That would obviate the need for the isOldValueRequested and would avoid doing a second loop over the observers. > > I guess you're trying to have a single record for all observers. I think that's fine, but you could invert the way you create mutations...create the null old value record first and create the mutation record with the old value from the one without. > > It's not a big deal, but it seems the code is less complicated (or am I missing something?) and it avoids another O(n) operation, not that I actually expect that to affect real-world performance. The code-as-is optimizes for creating fewer mutation records at the cost of a bit more work up front to figure out what actually needs to be created. If all observers actually want old value, then we'd have two MutationRecords per mutation just to support them. Given that the common case is likely a single observer, it seems wasteful to create two records where one would do. I'm currently working on benchmarks for this stuff so we can get a better idea of what the right tradeoffs are, so I'd like to leave this for now as I find it "conceptually" simplest (minimizing the number of records). And of course the duplication of this logic will go away in the next patch.
Ryosuke Niwa
Comment 6 2011-10-31 16:24:04 PDT
Comment on attachment 113077 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=113077&action=review > Source/WebCore/dom/MutationRecord.cpp:98 > - CharacterDataRecord(PassRefPtr<Node> target) > + CharacterDataRecord(PassRefPtr<Node> target, StringImpl* oldValue) I don't think we want to pass StringImpl around like this.
Ojan Vafai
Comment 7 2011-10-31 16:25:18 PDT
(In reply to comment #5) > The code-as-is optimizes for creating fewer mutation records at the cost of a bit more work up front to figure out what actually needs to be created. If all observers actually want old value, then we'd have two MutationRecords per mutation just to support them. Given that the common case is likely a single observer, it seems wasteful to create two records where one would do. That makes sense. I think that's the right tradeoff. I'd be very surprised if this for-loop showed up in a profile.
Adam Klein
Comment 8 2011-10-31 16:28:24 PDT
Created attachment 113104 [details] Patch for landing
Adam Klein
Comment 9 2011-10-31 16:29:12 PDT
Comment on attachment 113077 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=113077&action=review >> Source/WebCore/dom/MutationRecord.cpp:98 >> + CharacterDataRecord(PassRefPtr<Node> target, StringImpl* oldValue) > > I don't think we want to pass StringImpl around like this. Changed to "const String&".
Ryosuke Niwa
Comment 10 2011-10-31 16:29:45 PDT
Comment on attachment 113104 [details] Patch for landing View in context: https://bugs.webkit.org/attachment.cgi?id=113104&action=review > Source/WebCore/dom/CharacterData.cpp:208 > +static void enqueueCharacterDataMutationRecord(Node* node, StringImpl* oldData) Same comment about StringImpl here. > Source/WebCore/dom/CharacterData.cpp:235 > +void CharacterData::dispatchModifiedEvent(StringImpl* oldData) and here.
Adam Klein
Comment 11 2011-10-31 16:31:21 PDT
Comment on attachment 113104 [details] Patch for landing View in context: https://bugs.webkit.org/attachment.cgi?id=113104&action=review >> Source/WebCore/dom/CharacterData.cpp:235 >> +void CharacterData::dispatchModifiedEvent(StringImpl* oldData) > > and here. I didn't write this code, do you want me to change this interface as part of the same patch?
Adam Klein
Comment 12 2011-10-31 16:33:48 PDT
Created attachment 113105 [details] More const String&ification
Ryosuke Niwa
Comment 13 2011-10-31 16:38:51 PDT
Comment on attachment 113105 [details] More const String&ification I think Ojan's r+ withstands here.
Adam Klein
Comment 14 2011-10-31 16:46:59 PDT
Adam Klein
Comment 15 2011-10-31 16:47:43 PDT
(In reply to comment #11) > (From update of attachment 113104 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=113104&action=review > > >> Source/WebCore/dom/CharacterData.cpp:235 > >> +void CharacterData::dispatchModifiedEvent(StringImpl* oldData) > > > > and here. > > I didn't write this code, do you want me to change this interface as part of the same patch? Assuming no due to the r+, I'll write up a second patch to use String instead of StringImpl inside CharacterData (though I do wonder if there's some reason for this usage).
Ryosuke Niwa
Comment 16 2011-10-31 16:51:38 PDT
(In reply to comment #15) > (In reply to comment #11) > > (From update of attachment 113104 [details] [details]) > > View in context: https://bugs.webkit.org/attachment.cgi?id=113104&action=review > > > > >> Source/WebCore/dom/CharacterData.cpp:235 > > >> +void CharacterData::dispatchModifiedEvent(StringImpl* oldData) > > > > > > and here. > > > > I didn't write this code, do you want me to change this interface as part of the same patch? > > Assuming no due to the r+, I'll write up a second patch to use String instead of StringImpl inside CharacterData (though I do wonder if there's some reason for this usage). r+ with comments mean that I still want the comments to be addressed although it can be landed either way.
Note You need to log in before you can comment on or make changes to this bug.