Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split registered_mutation_observers in two #23286

Closed
ferjm opened this issue Apr 29, 2019 · 3 comments
Closed

Split registered_mutation_observers in two #23286

ferjm opened this issue Apr 29, 2019 · 3 comments

Comments

@ferjm
Copy link
Member

@ferjm ferjm commented Apr 29, 2019

#22743 introduces a NodeRareData struct to store ... well... rare data. Ideally, this data should only be lazily initialized by setters, but the existing mutation observers getter is also initializing it, and that breaks the sole purpose of this struct.

@gatoWololo
Copy link
Contributor

@gatoWololo gatoWololo commented Jun 4, 2019

Hello! I'm currently looking at fixing this issue.

I think I have a sense of what's happening. The problem is:

    /// Return all registered mutation observers for this node.
    /// XXX(ferjm) This should probably be split into two functions,
    /// `registered_mutation_observers`, which returns an Option or
    /// an empty slice or something, and doesn't create the rare data,
    /// and `registered_mutation_observers_mut`, which does lazily
    /// initialize the raredata.
    pub fn registered_mutation_observers(&self) -> RefMut<Vec<RegisteredObserver>> {
        RefMut::map(self.ensure_rare_data(), |rare_data| {
            &mut rare_data.mutation_observers
        })
    }

As the comment helpfully points out, this is a getter that initializes rare_data via ensure_rare_data():

        fn ensure_rare_data(&self) -> RefMut<Box<$type>> {
            let mut rare_data = self.rare_data.borrow_mut();
            if rare_data.is_none() {
                *rare_data = Some(Default::default());
            }
            RefMut::map(rare_data, |rare_data| {
                rare_data.as_mut().unwrap()
            })
        }

Where if the data is not there, we just init with default(). I'm curious what the motivation behind lazy initialization is?

Looking at NodeRareData:

#[derive(Default, JSTraceable, MallocSizeOf)]
#[must_root]
pub struct NodeRareData {
    /// The shadow root the node belongs to.
    /// This is None if the node is not in a shadow tree or
    /// if it is a ShadowRoot.
    pub containing_shadow_root: Option<Dom<ShadowRoot>>,
    /// Registered observers for this node.
    pub mutation_observers: Vec<RegisteredObserver>,
}

Default just inits containing_shadow_root to None, and mutation_observers to empty vector. So it should be cheap?

Splitting registered_mutation_observers() into two methods seems fairly straightforward. Or am I missing something?

@jdm
Copy link
Member

@jdm jdm commented Jun 4, 2019

ensure_rare_data returns a Box value, which is an unconditional allocation (unlike an empty Vec, for example). The goal here is to add a new registered_mutation_observers variant that returns an Option and does not initialize the rare data if it does not already exist, and update callers of registered_mutation_observers that do not mutate the result to use this new method instead.

@gatoWololo
Copy link
Contributor

@gatoWololo gatoWololo commented Jun 4, 2019

I see, thanks. I'll try working on this then.

bors-servo added a commit that referenced this issue Jun 10, 2019
Split getter for mutation_observers() into two methods.

Please let me know if these API changes look good:

registered_mutation_observers() returns immutable references and does
not init mutation observers.

registered_mutation_observers_mut() lazily initializes raredata if it
does not exist.

Updated code that uses this methods to call appropriate method when
mutation is not necessary.

<!-- Please describe your changes on the following line: -->

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #23286

<!-- Either: -->
- [X] These changes do not require tests because: this is a small change to the API, and existing tests for Partial ShadowDOM support cover this API use/changes.

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/23529)
<!-- Reviewable:end -->
bors-servo added a commit that referenced this issue Jun 10, 2019
Split getter for mutation_observers() into two methods.

Please let me know if these API changes look good:

registered_mutation_observers() returns immutable references and does
not init mutation observers.

registered_mutation_observers_mut() lazily initializes raredata if it
does not exist.

Updated code that uses this methods to call appropriate method when
mutation is not necessary.

<!-- Please describe your changes on the following line: -->

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #23286

<!-- Either: -->
- [X] These changes do not require tests because: this is a small change to the API, and existing tests for Partial ShadowDOM support cover this API use/changes.

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/23529)
<!-- Reviewable:end -->
bors-servo added a commit that referenced this issue Jun 10, 2019
Split getter for mutation_observers() into two methods.

Please let me know if these API changes look good:

registered_mutation_observers() returns immutable references and does
not init mutation observers.

registered_mutation_observers_mut() lazily initializes raredata if it
does not exist.

Updated code that uses this methods to call appropriate method when
mutation is not necessary.

<!-- Please describe your changes on the following line: -->

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #23286

<!-- Either: -->
- [X] These changes do not require tests because: this is a small change to the API, and existing tests for Partial ShadowDOM support cover this API use/changes.

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/23529)
<!-- Reviewable:end -->
bors-servo added a commit that referenced this issue Jun 10, 2019
Split getter for mutation_observers() into two methods.

Please let me know if these API changes look good:

registered_mutation_observers() returns immutable references and does
not init mutation observers.

registered_mutation_observers_mut() lazily initializes raredata if it
does not exist.

Updated code that uses this methods to call appropriate method when
mutation is not necessary.

<!-- Please describe your changes on the following line: -->

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #23286

<!-- Either: -->
- [X] These changes do not require tests because: this is a small change to the API, and existing tests for Partial ShadowDOM support cover this API use/changes.

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/23529)
<!-- Reviewable:end -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

3 participants
You can’t perform that action at this time.