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

Make dictionaries and unions containing GC values safer #17056

Merged
merged 7 commits into from Sep 25, 2017

Conversation

@jdm
Copy link
Member

jdm commented May 26, 2017

Problems:

  • the Heap::new constructor is memory-unsafe with any value other than Undefined/Null
  • this means that moving dictionaries containing Heap values (ie. any/object) is memory-unsafe
  • unions containing GC pointers are similarly unsafe

Solutions:

  • dictionaries containing GC pointers are now wrapped in RootedTraceableBox (even inside other dictionaries)
  • instead of using Heap::new, dictionaries containing GC pointers are now initialized to a default value (by deriving Default) and mutated one field at a time
  • dictionaries containing GC pointers are marked #[must_root]
  • FromJSVal for dictionaries containing GC pointers now returns RootedTraceableBox
  • unions wrap their variants that require rooting in RootedTraceableBox

Rather than attempting to derive Default for all dictionaries, we only do so for the dictionaries that require it. Because some dictionaries that require it inherit from dictionaries that do not, we need to write manual implementations for those parent dictionaries. This is a better option than having to figure out a default value for types like Root<T>, which would be required for deriving Default for all dictionaries.

I would still like to come up with an automated test for this, but I figured I would get eyes on this first.


  • ./mach build -d does not report any errors
  • ./mach test-tidy does not report any errors
  • These changes fix #16952
  • There are tests for these changes

This change is Reviewable

@highfive
Copy link

highfive commented May 26, 2017

Heads up! This PR modifies the following files:

  • @fitzgen: components/script/dom/bindings/codegen/CodegenRust.py, components/script/dom/testbinding.rs, components/script/dom/bindings/num.rs, components/script/dom/event.rs, components/script/dom/extendableevent.rs and 6 more
  • @KiChjang: components/script/dom/bindings/codegen/CodegenRust.py, components/script/dom/testbinding.rs, components/script/dom/bindings/num.rs, components/script/dom/event.rs, components/script/dom/extendableevent.rs and 6 more
@highfive
Copy link

highfive commented May 26, 2017

warning Warning warning

  • These commits modify unsafe code. Please review it carefully!
@jdm
Copy link
Member Author

jdm commented May 26, 2017

r? @nox
After this PR there is only one use of Heap::new left in the whole codebase.

@highfive highfive assigned nox and unassigned mbrubeck May 26, 2017
@jdm jdm force-pushed the jdm:heapdict branch from bfb58c4 to 9ea964c May 26, 2017
@jdm
Copy link
Member Author

jdm commented May 26, 2017

@MortimerGoro
Copy link
Contributor

MortimerGoro commented May 29, 2017

I have tested the PR and it works great, no more GC crashes with dictionary initializers!

@@ -4002,12 +3999,18 @@ def __init__(self, enum):
}
}
impl Default for super::%s {
fn default() -> super::%s {

This comment has been minimized.

@emilio

emilio May 29, 2017

Member

nit: use 4 space indents. Also, perhaps it's worth to use named arguments?

selfName = self.makeClassName(d)
if self.membersNeedTracing():
actualType = "RootedTraceableBox<%s>" % selfName
preInitial = "let mut dictionary = RootedTraceableBox::new(%s::default());\n" % selfName

This comment has been minimized.

@emilio

emilio May 29, 2017

Member

do you need the interpolation? I'd expected RootedTraceableBox::default() to just work.

@jdm
Copy link
Member Author

jdm commented May 29, 2017

I have had no luck creating a test for this yet.

@bors-servo
Copy link
Contributor

bors-servo commented Jul 21, 2017

The latest upstream changes (presumably #17822) made this pull request unmergeable. Please resolve the merge conflicts.

@MortimerGoro
Copy link
Contributor

MortimerGoro commented Aug 8, 2017

@jdm can we merge this? I have to cherry pick the commits each time I want to test/prepare A-Frame demos in a new branch.

@jdm
Copy link
Member Author

jdm commented Aug 8, 2017

My goal was to write an automated test that demonstrated the problem, but it has been more challenging than I anticipated. I'll try to merge this sometime this week.

@bors-servo
Copy link
Contributor

bors-servo commented Aug 23, 2017

The latest upstream changes (presumably #18179) made this pull request unmergeable. Please resolve the merge conflicts.

@jdm jdm force-pushed the jdm:heapdict branch from 9ea964c to adff462 Aug 24, 2017
@jdm
Copy link
Member Author

jdm commented Aug 24, 2017

@emilio I have addressed your first comment; the one about the RootedTraceableBox default caused compiler errors because it messed up some type inference.

@jdm jdm removed the S-needs-rebase label Aug 24, 2017
@jdm jdm force-pushed the jdm:heapdict branch from adff462 to 3ba2dd8 Aug 24, 2017
@bors-servo
Copy link
Contributor

bors-servo commented Sep 21, 2017

The latest upstream changes (presumably #18059) made this pull request unmergeable. Please resolve the merge conflicts.

jdm added 5 commits May 26, 2017
Mark dictionaries containing GC values as must_root, and wrap them in
RootedTraceableBox in automatically-generated APIs. To accommodate
union variants that are now flagged as unsafe, add RootedTraceableBox
to union variants that need to be rooted, rather than wrapping the
entire union value.
@jdm jdm force-pushed the jdm:heapdict branch from 3ba2dd8 to 44822c3 Sep 25, 2017
@jdm
Copy link
Member Author

jdm commented Sep 25, 2017

@bors-servo: r=emilio

@bors-servo
Copy link
Contributor

bors-servo commented Sep 25, 2017

📌 Commit 44822c3 has been approved by emilio

@bors-servo
Copy link
Contributor

bors-servo commented Sep 25, 2017

Testing commit 44822c3 with merge 532dee3...

bors-servo added a commit that referenced this pull request Sep 25, 2017
Make dictionaries and unions containing GC values safer

Problems:
* the Heap::new constructor is memory-unsafe with any value other than Undefined/Null
* this means that moving dictionaries containing Heap values (ie. any/object) is memory-unsafe
* unions containing GC pointers are similarly unsafe

Solutions:
- dictionaries containing GC pointers are now wrapped in RootedTraceableBox (even inside other dictionaries)
- instead of using Heap::new, dictionaries containing GC pointers are now initialized to a default value (by deriving Default) and mutated one field at a time
- dictionaries containing GC pointers are marked #[must_root]
- FromJSVal for dictionaries containing GC pointers now returns RootedTraceableBox<Dictionary>
- unions wrap their variants that require rooting in RootedTraceableBox

Rather than attempting to derive Default for all dictionaries, we only do so for the dictionaries that require it. Because some dictionaries that require it inherit from dictionaries that do not, we need to write manual implementations for those parent dictionaries. This is a better option than having to figure out a default value for types like `Root<T>`, which would be required for deriving Default for all dictionaries.

I would still like to come up with an automated test for this, but I figured I would get eyes on this first.

---
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #16952
- [ ] There are tests for these changes

<!-- 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/17056)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

bors-servo commented Sep 25, 2017

@bors-servo bors-servo merged commit 44822c3 into servo:master Sep 25, 2017
2 checks passed
2 checks passed
continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

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