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

Using OnceCell<T> from Mitochondria #18059

Merged
merged 1 commit into from Sep 21, 2017
Merged

Conversation

sendilkumarn
Copy link
Contributor

@sendilkumarn sendilkumarn commented Aug 13, 2017



This change is Reviewable

@highfive
Copy link

Heads up! This PR modifies the following files:

  • @fitzgen: components/script/Cargo.toml, components/script/lib.rs, components/script/dom/bindings/js.rs
  • @KiChjang: components/script/Cargo.toml, components/script/lib.rs, components/script/dom/bindings/js.rs

@highfive highfive added the S-awaiting-review There is new code that needs to be reviewed. label Aug 13, 2017
@highfive
Copy link

warning Warning warning

  • These commits modify unsafe code. Please review it carefully!
  • These commits modify script code, but no tests are modified. Please consider adding a test!

@sendilkumarn sendilkumarn changed the title Mito using oncecell in Mitochondria Aug 13, 2017
@nox nox changed the title using oncecell in Mitochondria using OnceCell<T> in Mitochondria Aug 13, 2017
@nox nox changed the title using OnceCell<T> in Mitochondria Using OnceCell<T> in Mitochondria Aug 13, 2017
@nox
Copy link
Contributor

nox commented Aug 13, 2017

Checking files for tidiness...
./components/script/dom/bindings/js.rs:395: trailing whitespace
./components/script/dom/bindings/js.rs:442: trailing whitespace
./components/script/dom/bindings/js.rs:462: trailing whitespace
./components/script/dom/bindings/js.rs:496: trailing whitespace
./components/script/dom/bindings/js.rs:521: trailing whitespace
./components/script/dom/bindings/js.rs:759: no newline at EOF
./components/script/dom/bindings/js.rs:462: extra space after (

@nox nox added the S-fails-tidy `./mach test-tidy` reported errors. label Aug 13, 2017
/// on `JS<T>`.
#[must_root]
pub struct OnceCellJS<T: DomObject> {
ptr: OnceCell<Option<JS<T>>>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be no Option<T> here.


/// Retrieve a copy of the current inner value. If it is `None`, it is
/// initialized with the result of `cb` first.
pub fn or_init<F>(&self, cb: F) -> Root<T>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should call OnceCell::init_once.

debug_assert!(thread_state::get().is_layout());
match self.ptr.as_ref() {
Some(ptr_ref) => {
ptr::read(ptr_ref).map(|js| js.to_layout())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why ptr::read?

unsafe {
match self.ptr.as_ref() {
Some(ptr_ref) => {
ptr::read(ptr_ref).map(|o| Root::from_ref(&*o))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why ptr::read?

pub fn get(&self) -> Option<Root<T>> {
debug_assert!(thread_state::get().is_script());
unsafe {
match self.ptr.as_ref() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use Option::map instead of a match expression.

}

/// Set this `OnceCellJS` to the given value. If it is not already set
pub fn set(&self, val: Option<&T>) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method shouldn't exist at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using init_once straight away in or_init method causes the following error

expected type `core::option::Option<T>`
 found type `core::option::Option<&dom::bindings::js::JS<T>>`

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and if I pass it to this method it kinda works.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method shouldn't exist anyway.

}

/// Gets the current value out of this object and sets it to `None`.
pub fn take(&self) -> Option<Root<T>> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method shouldn't exist at all.

}
}

impl<T: DomObject> PartialEq for OnceCellJS<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be derived.

#[cfg(not(debug_assertions))]
let trace_info = "for DOM object on heap";

match self.ptr.as_ref().clone() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just call trace on the result of self.ptr.as_ref().

@@ -603,4 +756,4 @@ unsafe impl<T: DomObject> JSTraceable for Root<T> {
unsafe fn trace(&self, _: *mut JSTracer) {
// Already traced.
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: missing new line.

@nox nox assigned nox and unassigned wafflespeanut Aug 13, 2017
@nox nox added S-needs-code-changes Changes have not yet been made that were requested by a reviewer. and removed S-awaiting-review There is new code that needs to be reviewed. labels Aug 13, 2017

/// Get a rooted value out of this object
#[allow(unrooted_must_root)]
pub fn get(&self) -> Option<Root<T>> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is the right return type. The whole idea behind the issue is that whenever I call the get method, I shouldn't need to worry about whether the cell is empty or not, and that it will always get the appropriate value for me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. Since MutNullableJS and MutJS returns Root<T> , I decided to return something similar. Rather here I will return Option<JS<T>>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, Option<JS<T>> shouldn't be returned, but Option<&T>.

@sendilkumarn sendilkumarn changed the title Using OnceCell<T> in Mitochondria Using OnceCell<T> from Mitochondria Aug 15, 2017
@highfive highfive added S-awaiting-review There is new code that needs to be reviewed. and removed S-needs-code-changes Changes have not yet been made that were requested by a reviewer. labels Aug 15, 2017
/// Retrieve a copy of the current inner value. If it is `None`, it is
/// initialized with the result of `cb` first.
#[allow(unrooted_must_root)]
pub unsafe fn or_init<F>(&self, cb: F) -> &JS<T>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still not convinced this is an improvement over MutNullableJS<T>. In fact as it stands currently, it is an exact copy of it. Let me reiterate the goals of the issue:

Consider the Elements method in HTMLFormElement. It tries to see if the elements field is a Some; if so, it would return that inner value, and if not, it does a whole chunk of initialization for it, and finally setting that inner value into Some.

What I personally would like to see is to have that method body be reduced into simply self.elements.get(), and perhaps in the new method of the OnceCellJS that houses the list of elements, accept a closure/function that gets called whenever the get method encounters a None for its inner value.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should return &T. get should either not exist or return Option<&T>.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KiChjang thanks

@nox yeah it should return &T. We can remove the get too use or_init straightaway

@nox nox added S-needs-squash Some (or all) of the commits in the PR should be combined. and removed S-fails-tidy `./mach test-tidy` reported errors. labels Aug 16, 2017
@nox
Copy link
Contributor

nox commented Aug 16, 2017

My comments should be addressed, and then the commits should be squashed together.

Also, we can't land this as long as you don't also migrate at least one MutNullableJS to that new type, finally making use of it.

#[allow(unrooted_must_root)]
unsafe impl<T: DomObject> JSTraceable for OnceCellJS<T> {
unsafe fn trace(&self, trc: *mut JSTracer) {
match self.ptr.as_ref() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if let Some(ptr) = self.ptr.as_ref() {
    ptr.trace(trc);
}

/// Retrieve a copy of the current inner value. If it is `None`, it is
/// initialized with the result of `cb` first.
#[allow(unrooted_must_root)]
pub unsafe fn or_init<F>(&self, cb: F) -> &T
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still uncorrect.

  • It should not be unsafe.
  • F should be FnOnce() -> Root<T>.
  • The method should only call init_once with a wrapper of cb converting the Root<T> to JS<T> and dereferencing the returned JS<T> to &T.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still confused as to why this function exists. How is this any different than MutNullableJS?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You cannot retrieve a &T from a MutNullableJS<T>. IMO the method should be named init_once just like in Mitochondria.


impl<T: DomObject> OnceCellJS<T> {
/// Create a new `OnceCellJS` with value
pub fn new(initial: Option<&T>) -> OnceCellJS<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure there is no need for an initial value at all here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which makes this function similar to Default::default() Instead, we can change the signature to new_with_value similar to mitochondria

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really seem to see that use case at all... Why would you need to provide an initial value when the purpose is to either get it from the OnceCell or run a closure to produce a value?

@nox nox added S-needs-code-changes Changes have not yet been made that were requested by a reviewer. and removed S-awaiting-review There is new code that needs to be reviewed. labels Aug 16, 2017
@highfive highfive added S-awaiting-review There is new code that needs to be reviewed. and removed S-needs-code-changes Changes have not yet been made that were requested by a reviewer. labels Aug 18, 2017

impl<T: DomObject> OnceCellJS<T> {
/// Create a new `OnceCellJS` with value
pub fn new() -> OnceCellJS<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make that the impl of Default for OnceCellJS<T> and this is good to go!

Thanks for keeping up with my comments!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean change this method into default or implement default separately.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implement the Default trait on OnceCellJS, and move the method body below to be inside of fn default.

@nox nox added the S-needs-code-changes Changes have not yet been made that were requested by a reviewer. label Aug 21, 2017
@nox
Copy link
Contributor

nox commented Sep 7, 2017

Am stupid, the PR should be rebased to land. ><

@nox nox added S-needs-rebase There are merge conflict errors. and removed S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. labels Sep 7, 2017
@bors-servo
Copy link
Contributor

🔒 Merge conflict

let filter = box ElementsFilter { form: Root::from_ref(self) };
let window = window_from_node(self);
let elements = HTMLFormControlsCollection::new(&window, self.upcast(), filter);
elements
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the elements variable be removed here?

adding oncecell for JS references

removing option<JS<T>> to <JS<T>>

changing return types

removing get method and refactoring the function

changing getElements method

lint fixes

moving to default

simplifying return

ordering

Removing elements

linting
@sendilkumarn
Copy link
Contributor Author

@nox is it pending for any other thing?

@KiChjang
Copy link
Contributor

@bors-servo r=nox

@bors-servo
Copy link
Contributor

📌 Commit 8b33e0f has been approved by nox

@bors-servo
Copy link
Contributor

🌲 The tree is currently closed for pull requests below priority 9000, this pull request will be tested once the tree is reopened

@highfive highfive added S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. and removed S-awaiting-review There is new code that needs to be reviewed. S-needs-rebase There are merge conflict errors. labels Sep 16, 2017
@bors-servo
Copy link
Contributor

⌛ Testing commit 8b33e0f with merge b42a2b2918e79820c4b228bfa88cd8cf37eedfe4...

@bors-servo
Copy link
Contributor

💔 Test failed - linux-rel-wpt

@highfive highfive added S-tests-failed The changes caused existing tests to fail. and removed S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. labels Sep 17, 2017
@bors-servo
Copy link
Contributor

⌛ Testing commit 8b33e0f with merge 5c797d1...

bors-servo pushed a commit that referenced this pull request Sep 21, 2017
Using OnceCell<T> from Mitochondria

<!-- 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 #13402  (github issue number if applicable).

<!-- 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/18059)
<!-- Reviewable:end -->
@highfive highfive added S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. and removed S-tests-failed The changes caused existing tests to fail. labels Sep 21, 2017
@bors-servo
Copy link
Contributor

☀️ Test successful - android, arm32, arm64, linux-dev, linux-rel-css, linux-rel-wpt, mac-dev-unit, mac-rel-css1, mac-rel-css2, mac-rel-wpt1, mac-rel-wpt2, mac-rel-wpt3, mac-rel-wpt4, windows-msvc-dev
Approved by: nox
Pushing 5c797d1 to master...

@bors-servo bors-servo merged commit 8b33e0f into servo:master Sep 21, 2017
@highfive highfive removed the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Sep 21, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Investigate a Lazy<T> DOM member type instead of MutNullableHeap<T>
6 participants