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

Optimize RefCell refcount tracking #51630

Merged
merged 1 commit into from
Jun 28, 2018
Merged

Conversation

joshlf
Copy link
Contributor

@joshlf joshlf commented Jun 19, 2018

Address the performance concern raised in #51466 (comment)

cc @dtolnay @nnethercote @rust-lang/wg-compiler-performance

cc @RalfJung @jhjourdan for soundness concerns

Can somebody kick off a perf run on this? I'm not sure how that's done, but I understand it has to be started manually.

The idea of this change is to switch to representing mutable refcount as values below 0 to eliminate some branching that was required with the old algorithm.

@rust-highfive
Copy link
Collaborator

r? @alexcrichton

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 19, 2018
@kennytm
Copy link
Member

kennytm commented Jun 19, 2018

@bors try

@bors
Copy link
Contributor

bors commented Jun 19, 2018

⌛ Trying commit 583e283 with merge 145f4f4...

bors added a commit that referenced this pull request Jun 19, 2018
Optimize RefCell refcount tracking

Address the performance concern raised in #51466 (comment)

cc @dtolnay  @nnethercote @rust-lang/wg-compiler-performance

cc @RalfJung @jhjourdan for soundness concerns

Can somebody kick off a perf run on this? I'm not sure how that's done, but I understand it has to be started manually.

The idea of this change is to switch to representing mutable refcount as values below 0 to eliminate some branching that was required with the old algorithm.
@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-3.9 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[01:04:36] ....................................................................................................
[01:04:43] ....................................................................................................
[01:04:51] ....................................................................................................
[01:04:57] ...i................................................................................................
[01:05:04] ..i..ii...................................................................................FFF.F.....
[01:05:18] ..............................................................................test [compile-fail] compile-fail/issue-22638.rs has been running for over 60 seconds
[01:05:19] ......................
[01:05:24] ....................................................................................i...............
[01:05:29] ..............................i.....................................................................
---
[01:05:46] failures:
[01:05:46] 
[01:05:46] ---- [compile-fail] compile-fail/not-panic-safe-2.rs stdout ----
[01:05:46] 
[01:05:46] error: /checkout/src/test/compile-fail/not-panic-safe-2.rs:20: unexpected error: '20:5: 20:31: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]'
[01:05:46] 
[01:05:46] error: /checkout/src/test/compile-fail/not-panic-safe-2.rs:20: expected error not found: `std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied
[01:05:46] 
[01:05:46] error: 1 unexpected errors found, 1 expected errors not found
[01:05:46] thread 'main' panicked at 'Some tests failed', tools/compiletest/src/main.rs:498:22
[01:05:46] thread 'main' panicked at 'Some tests failed', tools/compiletest/src/main.rs:498:22
[01:05:46] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/compile-fail/not-panic-safe-2.rs" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-2/a" "-Crpath" "-O" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-2/auxiliary" "-A" "unused"
[01:05:46] unexpected errors (from JSON output): [
[01:05:46]     Error {
[01:05:46]         line_num: 20,
[01:05:46]         kind: Some(
[01:05:46]         ),
[01:05:46]         ),
[01:05:46]         msg: "20:5: 20:31: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]"
[01:05:46] ]
[01:05:46] 
[01:05:46] not found errors (from test file): [
[01:05:46]     Error {
[01:05:46]     Error {
[01:05:46]         line_num: 20,
[01:05:46]         kind: Some(
[01:05:46]             Error
[01:05:46]         ),
[01:05:46]         msg: "`std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied"
[01:05:46] ]
[01:05:46] 
[01:05:46] thread '[compile-fail] compile-fail/not-panic-safe-2.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:1284:13
[01:05:46] 
[01:05:46] 
[01:05:46] ---- [compile-fail] compile-fail/not-panic-safe-3.rs stdout ----
[01:05:46] 
[01:05:46] error: /checkout/src/test/compile-fail/not-panic-safe-3.rs:20: unexpected error: '20:5: 20:32: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]'
[01:05:46] 
[01:05:46] error: /checkout/src/test/compile-fail/not-panic-safe-3.rs:20: expected error not found: `std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied
[01:05:46] 
[01:05:46] error: 1 unexpected errors found, 1 expected errors not found
[01:05:46] status: exit code: 101
[01:05:46] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/compile-fail/not-panic-safe-3.rs" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-3/a" "-Crpath" "-O" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-3/auxiliary" "-A" "unused"
[01:05:46] unexpected errors (from JSON output): [
[01:05:46]     Error {
[01:05:46]         line_num: 20,
[01:05:46]         kind: Some(
[01:05:46]         ),
[01:05:46]         ),
[01:05:46]         msg: "20:5: 20:32: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]"
[01:05:46] ]
[01:05:46] 
[01:05:46] not found errors (from test file): [
[01:05:46]     Error {
[01:05:46]     Error {
[01:05:46]         line_num: 20,
[01:05:46]         kind: Some(
[01:05:46]             Error
[01:05:46]         ),
[01:05:46]         msg: "`std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied"
[01:05:46] ]
[01:05:46] 
[01:05:46] thread '[compile-fail] compile-fail/not-panic-safe-3.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:1284:13
[01:05:46] 
[01:05:46] 
[01:05:46] ---- [compile-fail] compile-fail/not-panic-safe-4.rs stdout ----
[01:05:46] 
[01:05:46] error: /checkout/src/test/compile-fail/not-panic-safe-4.rs:19: unexpected error: '19:5: 19:28: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]'
[01:05:46] 
[01:05:46] error: /checkout/src/test/compile-fail/not-panic-safe-4.rs:19: expected error not found: `std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied
[01:05:46] 
[01:05:46] error: 1 unexpected errors found, 1 expected errors not found
[01:05:46] status: exit code: 101
[01:05:46] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/compile-fail/not-panic-safe-4.rs" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-4/a" "-Crpath" "-O" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-4/auxiliary" "-A" "unused"
[01:05:46] unexpected errors (from JSON output): [
[01:05:46]     Error {
[01:05:46]         line_num: 19,
[01:05:46]         kind: Some(
[01:05:46]         ),
[01:05:46]         ),
[01:05:46]         msg: "19:5: 19:28: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]"
[01:05:46] ]
[01:05:46] 
[01:05:46] not found errors (from test file): [
[01:05:46]     Error {
[01:05:46]     Error {
[01:05:46]         line_num: 19,
[01:05:46]         kind: Some(
[01:05:46]             Error
[01:05:46]         ),
[01:05:46]         msg: "`std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied"
[01:05:46] ]
[01:05:46] 
[01:05:46] thread '[compile-fail] compile-fail/not-panic-safe-4.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:1284:13
[01:05:46] 
[01:05:46] 
[01:05:46] ---- [compile-fail] compile-fail/not-panic-safe-6.rs stdout ----
[01:05:46] 
[01:05:46] error: /checkout/src/test/compile-fail/not-panic-safe-6.rs:19: unexpected error: '19:5: 19:32: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]'
[01:05:46] 
[01:05:46] error: /checkout/src/test/compile-fail/not-panic-safe-6.rs:19: expected error not found: `std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied
[01:05:46] 
[01:05:46] error: 1 unexpected errors found, 1 expected errors not found
[01:05:46] status: exit code: 101
[01:05:46] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/compile-fail/not-panic-safe-6.rs" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-6/a" "-Crpath" "-O" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-6/auxiliary" "-A" "unused"
[01:05:46] unexpected errors (from JSON output): [
[01:05:46]     Error {
[01:05:46]         line_num: 19,
[01:05:46]         kind: Some(
[01:05:46]         ),
[01:05:46]         ),
[01:05:46]         msg: "19:5: 19:32: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]"
[01:05:46] ]
[01:05:46] 
[01:05:46] not found errors (from test file): [
[01:05:46]     Error {
[01:05:46]     Error {
[01:05:46]         line_num: 19,
[01:05:46]         kind: Some(
[01:05:46]             Error
[01:05:46]         ),
[01:05:46]         msg: "`std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied"
[01:05:46] ]
[01:05:46] 
[01:05:46] thread '[compile-fail] compile-fail/not-panic-safe-6.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:1284:13
[01:05:46] 
---
[01:05:46] test result: FAILED. 2407 passed; 4 failed; 15 ignored; 0 measured; 0 filtered out
[01:05:46] 
[01:05:46] 
[01:05:46] 
[01:05:46] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/compile-fail" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "compile-fail" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-3.9/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Zunstable-options " "--target-rustcflags" "-Crpath -O -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "3.9.1\n" "--system-llvm" "--cc" "" "--cxx" "" "--cflags" "" "--llvm-components" "" "--llvm-cxxflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"
[01:05:46] 
[01:05:46] 
[01:05:46] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:05:46] Build completed unsuccessfully in 0:15:54
[01:05:46] Build completed unsuccessfully in 0:15:54
[01:05:46] Makefile:58: recipe for target 'check' failed
[01:05:46] make: *** [check] Error 1

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:35033ec8
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
---
travis_time:end:03cc6134:start=1529392269100473442,finish=1529392269107436781,duration=6963339
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:24b2f4f2
$ head -30 ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
head: cannot open ‘./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers’ for reading: No such file or directory
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:0fa6ee7e
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

None
} else {
// Prevent the borrow counter from overflowing into
// a writing borrow.
assert!(b < MIN_WRITING - 1);
assert!(b != isize::max_value());
Copy link
Contributor

@hanna-kruppe hanna-kruppe Jun 19, 2018

Choose a reason for hiding this comment

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

This assert was new in #51466 -- I missed the chance to comment there, but AFAICT (contrary to https://github.com/rust-lang/rust/pull/51466/files#r194758679), returning None in this case is exactly what the code did previously (before #51466). So I want to bring it up again: why do this?

If a mem::forget(rc.borrow()) loop overflows the borrow flag into the "writing" range, we'll just erroneously consider the RefCell mutably borrowed and refuse to create any new Refs or RefMuts, even without any extra checks. That's not quite as tidy as this assertion firing, but it's sound and the diagnostic value of this assertion failing isn't very high anyway. And since we're optimizing anyway...

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's a fair point. Given that there are no RefMuts in existence, there'd be no way to RefMut::map_split in order to create more RefMuts.

I suppose my one concern would be about the wrapping semantics. Is it well-defined that, in release mode, overflows wrap around to isize::min_value()? If not, we'll want explicit wrapping addition.

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 not a 100% sure I understand correctly, but overflows either result in two's complement wrapping or panics, it's not UB or implementation-defined or anything like that.

Copy link
Member

@RalfJung RalfJung Jun 19, 2018

Choose a reason for hiding this comment

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

Wow, this is a crazy trick (in a positive way ;). I agree it could work, but is it really needed? If panicking is the problem, why not turn the assert! into

if b == isize::max_value() { return None; }

That still keeps this function panic-free but avoids this strange state where the borrow flag is negative but there are Ref around.

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 know if panicking is the problem, everything's complete speculation anyway, extra computation and branching might also be an issue.

I could have sworn that the "benign overflow" trick is pre-existing (before #51466 that is). But on some more speluking, it seems it was just discussed, never actually implemented? We should probably try matching the previous behavior (i.e., returning None) first.

Copy link
Member

Choose a reason for hiding this comment

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

We should probably try matching the previous behavior (i.e., returning None) first.

I would prefer that, also for the sake of the sanity of whoever will try to prove this correct. ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I missed this comment. If that's the preference, I'll re-evaluate the discussion below about assertions.

@bors
Copy link
Contributor

bors commented Jun 19, 2018

☀️ Test successful - status-travis
State: approved= try=True

@kennytm
Copy link
Member

kennytm commented Jun 19, 2018

@Mark-Simulacrum perf requested, try#145f4f411684d06861b2a9a262061f5bc4ef9c93 vs master#ed39523406fea9d4c82f87f4ac9ad92388084123.

The test failure in #51630 (comment) does not seem to affect dist, so I guess we could disregard this for perf.

@kennytm kennytm added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. S-waiting-on-perf Status: Waiting on a perf run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 19, 2018
@Zoxc
Copy link
Contributor

Zoxc commented Jun 19, 2018

I think it would be nice to have a microbenchmark for RefCell so we could see the worst case impact of #51466 and experiment with a RefCell variant which only allows mutable borrows.

@Mark-Simulacrum
Copy link
Member

Perf has been queued.

@dtolnay
Copy link
Member

dtolnay commented Jun 19, 2018

The idea of this change is to switch to representing mutable refcount as values below 0 to eliminate some branching that was required with the old algorithm.

If I understand correctly, the only lines changed in this PR that are expected to affect performance are in BorrowRefMut::drop:

-        self.borrow.set(if borrow == MIN_WRITING {
-            UNUSED
-        } else {
-            borrow - 1
-        });
+        self.borrow.set(borrow + 1);

That's great but I don't believe it is the main source of slowdown in #51466 (though we'll find out for sure in the perf run). In my experience immutable Refs far outnumber RefMuts so I expect the main performance hit would have come from the panic codepath in BorrowRef::new which didn't exist before. It used to be that function could not panic. Now it can panic which requires extra control flow to handle in the caller.

I would be interested in comparing performance against @kruppe's suggestions of not panicking in BorrowRef::new.

@joshlf
Copy link
Contributor Author

joshlf commented Jun 19, 2018

I would be interested in comparing performance against @kruppe's suggestions of not panicking in BorrowRef::new.

Done.

@@ -1022,12 +1023,15 @@ impl<'b> BorrowRef<'b> {
#[inline]
fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRef<'b>> {
let b = borrow.get();
if b >= MIN_WRITING {
if b < UNUSED {
Copy link
Member

Choose a reason for hiding this comment

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

It's not clear at all that this is testing for "if nobody is writing". Could we have some #[inline(always)] function or a macro like is_writing(x: BorrowFlag) -> bool to make this code easier to understand?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

// writing borrow will simply prevent more borrows of any kind from
// being created. The only way to get a writing borrow when one
// already exists is to use RefMut::map_split, but we know that
// there cannot be any RefMuts in existence right now.
Copy link
Member

Choose a reason for hiding this comment

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

But what if you call this 2^31 more times (on a 32bit platform) to get the counter back to 0?

Oh, that's not possible because it will hit the b < UNUSED above. Maybe the comment should be extended to explain that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

@@ -1038,7 +1042,7 @@ impl<'b> Drop for BorrowRef<'b> {
#[inline]
fn drop(&mut self) {
let borrow = self.borrow.get();
debug_assert!(borrow < MIN_WRITING && borrow != UNUSED);
debug_assert!(borrow > UNUSED);
self.borrow.set(borrow - 1);
Copy link
Member

Choose a reason for hiding this comment

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

Oh wow and this can overflow again to a positive value so you can even keep using the RefCell... crazy.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep :)

Copy link
Member

Choose a reason for hiding this comment

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

Maybe be worth a comment though. (If you decide to reinstate that, that is.)

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 if we decide to allow overflow? It sounds like the decision was not to allow it.

Copy link
Member

Choose a reason for hiding this comment

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

Well I figured that'll depend on perf results.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True. If we go back to allowing overflow, I'll add a comment here.

@@ -1052,7 +1056,7 @@ impl<'b> Clone for BorrowRef<'b> {
debug_assert!(borrow != UNUSED);
// Prevent the borrow counter from overflowing into
// a writing borrow.
assert!(borrow < MIN_WRITING - 1);
assert!(borrow != isize::max_value());
Copy link
Member

Choose a reason for hiding this comment

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

Hm but what if borrow is isize::min_value() because it overflowed above? Then this will count upwards towards 0.

Seems like by first calling borrow() often enough to get the flag to overflow, and then calling map_split often enough to get the counter back to 0, I can break this?

Is that one check for making sure BorrowRef::new doesn't overflow really so expensive?

Copy link
Contributor

Choose a reason for hiding this comment

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

At minimum the above comment ("Since this Ref exists, we know the borrow flag is not set to WRITING") needs to be updated.

I dont' see how map_split is relevant, do you mean calling borrow() often enough to overflow to a negative number and then calling Clone often enough to get the counter back to zero? That's a good point, but I think it can be fixed by doing a < check like in borrow (either directly here, at the loss of 1/2^31 possible RefMuts, or by incrementing first and then checking it's still positive). All other locations that increment the counter need similar checks.

Copy link
Member

Choose a reason for hiding this comment

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

do you mean calling borrow() often enough to overflow to a negative number and then calling Clone often enough to get the counter back to zero?

Yes, and map_split is a way to call clone() here. (I forgot that Ref::clone() is a thing and can also be used for the same purpose. ;)

And yes, this could be fixed by something like assert!(borrow > UNUSED && borrow < isize::max_value()).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is, I believe, a mistake. Now that we're comfortable with overflowing into the writing territory, we should just remove this assertion.

Copy link
Contributor

Choose a reason for hiding this comment

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

Removing the check entirely would be wrong. Even if we're fine with overflowing past isize::MAX, we need to make sure we're not going much further, to 0, because that would allow having a Ref alongside a RefMut and thus be unsound.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I see. That's a fair point. I was thinking that it wouldn't be possible to create a new read reference once the refcount was in writing territory, but of course that's only true if you're actually checking first, which happens in BorrowRef::new, but not in clone.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Regardless, I recently saw the discussion about whether to allow overflow at all, and I saw that the conclusion was not to do it, so I'm going to go back to disallowing it.

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-3.9 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[00:54:38] ....................................................................................................
[00:54:43] ....................................................................................................
[00:54:51] ....................................................................................................
[00:54:56] ...i................................................................................................
[00:55:02] ..i..ii...................................................................................FFF..F....
[00:55:15] ....................................................................................................
[00:55:19] ....................................................................................i...............
[00:55:24] ..............................i.....................................................................
[00:55:30] ....................................................................................................
[00:55:30] ....................................................................................................
[00:55:35] ....................................................................................................
[00:55:38] ....................................................................................................
[00:55:40] ..........................
[00:55:40] failures:
[00:55:40] 
[00:55:40] ---- [compile-fail] compile-fail/not-panic-safe-2.rs stdout ----
[00:55:40] 
[00:55:40] error: /checkout/src/test/compile-fail/not-panic-safe-2.rs:20: unexpected error: '20:5: 20:31: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]'
[00:55:40] 
[00:55:40] error: /checkout/src/test/compile-fail/not-panic-safe-2.rs:20: expected error not found: `std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied
[00:55:40] 
[00:55:40] error: 1 unexpected errors found, 1 expected errors not found
[00:55:40] status: exit code: 101
[00:55:40] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/compile-fail/not-panic-safe-2.rs" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-2/a" "-Crpath" "-O" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-2/auxiliary" "-A" "unused"
[00:55:40] unexpected errors (from JSON output): [
[00:55:40]     Error {
[00:55:40]         line_num: 20,
[00:55:40]         kind: Some(
[00:55:40]         ),
[00:55:40]         ),
[00:55:40]         msg: "20:5: 20:31: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]"
[00:55:40] ]
[00:55:40] 
[00:55:40] not found errors (from test file): [
[00:55:40]     Error {
[00:55:40]     Error {
[00:55:40]         line_num: 20,
[00:55:40]         kind: Some(
[00:55:40]             Error
[00:55:40]         ),
[00:55:40]         msg: "`std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied"
[00:55:40] ]
[00:55:40] 
[00:55:40] thread '[compile-fail] compile-fail/not-panic-safe-2.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:1284:13
[00:55:40] 
[00:55:40] 
[00:55:40] ---- [compile-fail] compile-fail/not-panic-safe-3.rs stdout ----
[00:55:40] 
[00:55:40] error: /checkout/src/test/compile-fail/not-panic-safe-3.rs:20: unexpected error: '20:5: 20:32: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]'
[00:55:40] 
[00:55:40] error: /checkout/src/test/compile-fail/not-panic-safe-3.rs:20: expected error not found: `std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied
[00:55:40] 
[00:55:40] error: 1 unexpected errors found, 1 expected errors not found
[00:55:40] status: exit code: 101
[00:55:40] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/compile-fail/not-panic-safe-3.rs" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-3/a" "-Crpath" "-O" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-3/auxiliary" "-A" "unused"
[00:55:40] unexpected errors (from JSON output): [
[00:55:40]     Error {
[00:55:40]         line_num: 20,
[00:55:40]         kind: Some(
[00:55:40]         ),
[00:55:40]         ),
[00:55:40]         msg: "20:5: 20:32: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]"
[00:55:40] ]
[00:55:40] 
[00:55:40] not found errors (from test file): [
[00:55:40]     Error {
[00:55:40]     Error {
[00:55:40]         line_num: 20,
[00:55:40]         kind: Some(
[00:55:40]             Error
[00:55:40]         ),
[00:55:40]         msg: "`std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied"
[00:55:40] ]
[00:55:40] 
[00:55:40] thread '[compile-fail] compile-fail/not-panic-safe-3.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:1284:13
[00:55:40] 
[00:55:40] 
[00:55:40] ---- [compile-fail] compile-fail/not-panic-safe-4.rs stdout ----
[00:55:40] 
[00:55:40] error: /checkout/src/test/compile-fail/not-panic-safe-4.rs:19: unexpected error: '19:5: 19:28: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]'
[00:55:40] 
[00:55:40] error: /checkout/src/test/compile-fail/not-panic-safe-4.rs:19: expected error not found: `std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied
[00:55:40] 
[00:55:40] error: 1 unexpected errors found, 1 expected errors not found
[00:55:40] status: exit code: 101
[00:55:40] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/compile-fail/not-panic-safe-4.rs" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-4/a" "-Crpath" "-O" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-4/auxiliary" "-A" "unused"
[00:55:40] unexpected errors (from JSON output): [
[00:55:40]     Error {
[00:55:40]         line_num: 19,
[00:55:40]         kind: Some(
[00:55:40]         ),
[00:55:40]         ),
[00:55:40]         msg: "19:5: 19:28: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]"
[00:55:40] ]
[00:55:40] 
[00:55:40] not found errors (from test file): [
[00:55:40]     Error {
[00:55:40]     Error {
[00:55:40]         line_num: 19,
[00:55:40]         kind: Some(
[00:55:40]             Error
[00:55:40]         ),
[00:55:40]         msg: "`std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied"
[00:55:40] ]
[00:55:40] 
[00:55:40] thread '[compile-fail] compile-fail/not-panic-safe-4.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:1284:13
[00:55:40] 
[00:55:40] 
[00:55:40] ---- [compile-fail] compile-fail/not-panic-safe-6.rs stdout ----
[00:55:40] 
[00:55:40] error: /checkout/src/test/compile-fail/not-panic-safe-6.rs:19: unexpected error: '19:5: 19:32: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]'
[00:55:40] 
[00:55:40] error: /checkout/src/test/compile-fail/not-panic-safe-6.rs:19: expected error not found: `std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied
[00:55:40] 
[00:55:40] error: 1 unexpected errors found, 1 expected errors not found
[00:55:40] status: exit code: 101
[00:55:40] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/compile-fail/not-panic-safe-6.rs" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-6/a" "-Crpath" "-O" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-6/auxiliary" "-A" "unused"
[00:55:40] unexpected errors (from JSON output): [
[00:55:40]     Error {
[00:55:40]         line_num: 19,
[00:55:40]         kind: Some(
[00:55:40]         ),
[00:55:40]         ),
[00:55:40]         msg: "19:5: 19:32: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]"
[00:55:40] ]
[00:55:40] 
[00:55:40] not found errors (from test file): [
[00:55:40]     Error {
[00:55:40]     Error {
[00:55:40]         line_num: 19,
[00:55:40]         kind: Some(
[00:55:40]             Error
[00:55:40]         ),
[00:55:40]         msg: "`std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied"
[00:55:40] ]
[00:55:40] 
[00:55:40] thread '[compile-fail] compile-fail/not-panic-safe-6.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:1284:13
[00:55:40] 
---
[00:55:40] 
[00:55:40] thread 'main' panicked at 'Some tests failed', tools/compiletest/src/main.rs:498:22
[00:55:40] 
[00:55:40] 
[00:55:40] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/compile-fail" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "compile-fail" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-3.9/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Zunstable-options " "--target-rustcflags" "-Crpath -O -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "3.9.1\n" "--system-llvm" "--cc" "" "--cxx" "" "--cflags" "" "--llvm-components" "" "--llvm-cxxflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"
[00:55:40] 
[00:55:40] 
[00:55:40] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[00:55:40] Build completed unsuccessfully in 0:14:00
[00:55:40] Build completed unsuccessfully in 0:14:00
[00:55:40] make: *** [check] Error 1
[00:55:40] Makefile:58: recipe for target 'check' failed

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:044a8253
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@kennytm kennytm removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jun 19, 2018
@joshlf joshlf force-pushed the map-split-perf branch 2 times, most recently from cac5785 to 080bd8e Compare June 19, 2018 18:29
@joshlf
Copy link
Contributor Author

joshlf commented Jun 19, 2018

To consolidate the discussion on multiple threads with @rkruppe and @RalfJung: I've now updated the PR to go back to explicitly checking for overflow and underflow. However, in BorrowRef::new, overflow causes the function to return None instead of to panic. I hope that the is_writing(b) || b == isize::max_value() check won't be compiled into branching code, and so it will be nearly as fast if not as fast as simply checking is_writing(b).

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-3.9 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[00:55:48] ....................................................................................................
[00:55:54] ....................................................................................................
[00:56:02] ....................................................................................................
[00:56:07] ...i................................................................................................
[00:56:14] ..i..ii...................................................................................FFF.F.....
[00:56:27] ....................................................................................................
[00:56:31] ....................................................................................i...............
[00:56:36] ..............................i.....................................................................
[00:56:42] ....................................................................................................
[00:56:42] ....................................................................................................
[00:56:47] ....................................................................................................
[00:56:51] ....................................................................................................
[00:56:52] ..........................
[00:56:52] failures:
[00:56:52] 
[00:56:52] ---- [compile-fail] compile-fail/not-panic-safe-2.rs stdout ----
[00:56:52] 
[00:56:52] error: /checkout/src/test/compile-fail/not-panic-safe-2.rs:20: unexpected error: '20:5: 20:31: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]'
[00:56:52] 
[00:56:52] error: /checkout/src/test/compile-fail/not-panic-safe-2.rs:20: expected error not found: `std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied
[00:56:52] 
[00:56:52] error: 1 unexpected errors found, 1 expected errors not found
[00:56:52] status: exit code: 101
[00:56:52] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/compile-fail/not-panic-safe-2.rs" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-2/a" "-Crpath" "-O" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-2/auxiliary" "-A" "unused"
[00:56:52] unexpected errors (from JSON output): [
[00:56:52]     Error {
[00:56:52]         line_num: 20,
[00:56:52]         kind: Some(
[00:56:52]         ),
[00:56:52]         ),
[00:56:52]         msg: "20:5: 20:31: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]"
[00:56:52] ]
[00:56:52] 
[00:56:52] not found errors (from test file): [
[00:56:52]     Error {
[00:56:52]     Error {
[00:56:52]         line_num: 20,
[00:56:52]         kind: Some(
[00:56:52]             Error
[00:56:52]         ),
[00:56:52]         msg: "`std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied"
[00:56:52] ]
[00:56:52] 
[00:56:52] thread '[compile-fail] compile-fail/not-panic-safe-2.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:1284:13
[00:56:52] 
[00:56:52] 
[00:56:52] ---- [compile-fail] compile-fail/not-panic-safe-3.rs stdout ----
[00:56:52] 
[00:56:52] error: /checkout/src/test/compile-fail/not-panic-safe-3.rs:20: unexpected error: '20:5: 20:32: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]'
[00:56:52] 
[00:56:52] error: /checkout/src/test/compile-fail/not-panic-safe-3.rs:20: expected error not found: `std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied
[00:56:52] 
[00:56:52] error: 1 unexpected errors found, 1 expected errors not found
[00:56:52] status: exit code: 101
[00:56:52] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/compile-fail/not-panic-safe-3.rs" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-3/a" "-Crpath" "-O" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-3/auxiliary" "-A" "unused"
[00:56:52] unexpected errors (from JSON output): [
[00:56:52]     Error {
[00:56:52]         line_num: 20,
[00:56:52]         kind: Some(
[00:56:52]         ),
[00:56:52]         ),
[00:56:52]         msg: "20:5: 20:32: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]"
[00:56:52] ]
[00:56:52] 
[00:56:52] not found errors (from test file): [
[00:56:52]     Error {
[00:56:52]     Error {
[00:56:52]         line_num: 20,
[00:56:52]         kind: Some(
[00:56:52]             Error
[00:56:52]         ),
[00:56:52]         msg: "`std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied"
[00:56:52] ]
[00:56:52] 
[00:56:52] thread '[compile-fail] compile-fail/not-panic-safe-3.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:1284:13
[00:56:52] 
[00:56:52] 
[00:56:52] ---- [compile-fail] compile-fail/not-panic-safe-4.rs stdout ----
[00:56:52] 
[00:56:52] error: /checkout/src/test/compile-fail/not-panic-safe-4.rs:19: unexpected error: '19:5: 19:28: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]'
[00:56:52] 
[00:56:52] error: /checkout/src/test/compile-fail/not-panic-safe-4.rs:19: expected error not found: `std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied
[00:56:52] 
[00:56:52] error: 1 unexpected errors found, 1 expected errors not found
[00:56:52] status: exit code: 101
[00:56:52] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/compile-fail/not-panic-safe-4.rs" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-4/a" "-Crpath" "-O" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-4/auxiliary" "-A" "unused"
[00:56:52] unexpected errors (from JSON output): [
[00:56:52]     Error {
[00:56:52]         line_num: 19,
[00:56:52]         kind: Some(
[00:56:52]         ),
[00:56:52]         ),
[00:56:52]         msg: "19:5: 19:28: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]"
[00:56:52] ]
[00:56:52] 
[00:56:52] not found errors (from test file): [
[00:56:52]     Error {
[00:56:52]     Error {
[00:56:52]         line_num: 19,
[00:56:52]         kind: Some(
[00:56:52]             Error
[00:56:52]         ),
[00:56:52]         msg: "`std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied"
[00:56:52] ]
[00:56:52] 
[00:56:52] thread '[compile-fail] compile-fail/not-panic-safe-4.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:1284:13
[00:56:52] 
[00:56:52] 
[00:56:52] ---- [compile-fail] compile-fail/not-panic-safe-6.rs stdout ----
[00:56:52] 
[00:56:52] error: /checkout/src/test/compile-fail/not-panic-safe-6.rs:19: unexpected error: '19:5: 19:32: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]'
[00:56:52] 
[00:56:52] error: /checkout/src/test/compile-fail/not-panic-safe-6.rs:19: expected error not found: `std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied
[00:56:52] 
[00:56:52] error: 1 unexpected errors found, 1 expected errors not found
[00:56:52] status: exit code: 101
[00:56:52] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/compile-fail/not-panic-safe-6.rs" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-6/a" "-Crpath" "-O" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/not-panic-safe-6/auxiliary" "-A" "unused"
[00:56:52] unexpected errors (from JSON output): [
[00:56:52]     Error {
[00:56:52]         line_num: 19,
[00:56:52]         kind: Some(
[00:56:52]         ),
[00:56:52]         ),
[00:56:52]         msg: "19:5: 19:32: the trait bound `std::cell::UnsafeCell<isize>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::RefCell<i32>` [E0277]"
[00:56:52] ]
[00:56:52] 
[00:56:52] not found errors (from test file): [
[00:56:52]     Error {
[00:56:52]     Error {
[00:56:52]         line_num: 19,
[00:56:52]         kind: Some(
[00:56:52]             Error
[00:56:52]         ),
[00:56:52]         msg: "`std::cell::UnsafeCell<usize>: std::panic::RefUnwindSafe` is not satisfied"
[00:56:52] ]
[00:56:52] 
[00:56:52] thread '[compile-fail] compile-fail/not-panic-safe-6.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:1284:13
[00:56:52] 
---
[00:56:52] 
[00:56:52] thread 'main' panicked at 'Some tests failed', tools/compiletest/src/main.rs:498:22
[00:56:52] 
[00:56:52] 
[00:56:52] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/compile-fail" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "compile-fail" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-3.9/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Zunstable-options " "--target-rustcflags" "-Crpath -O -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "3.9.1\n" "--system-llvm" "--cc" "" "--cxx" "" "--cflags" "" "--llvm-components" "" "--llvm-cxxflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"
[00:56:52] 
[00:56:52] 
[00:56:52] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[00:56:52] Build completed unsuccessfully in 0:14:50
[00:56:52] Build completed unsuccessfully in 0:14:50
[00:56:52] Makefile:58: recipe for target 'check' failed
[00:56:52] make: *** [check] Error 1

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:00ea6b18
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@joshlf
Copy link
Contributor Author

joshlf commented Jun 19, 2018

@kennytm Can we kick off another perf run? Thanks!

@joshlf
Copy link
Contributor Author

joshlf commented Jun 27, 2018

That seems to have worked, thanks! I'm not going to pretend to understand why :P

@joshlf
Copy link
Contributor Author

joshlf commented Jun 27, 2018

OK, I think it's ready for another try.

@Mark-Simulacrum
Copy link
Member

@bors try

@bors
Copy link
Contributor

bors commented Jun 27, 2018

⌛ Trying commit 851cc39 with merge c80bceb...

bors added a commit that referenced this pull request Jun 27, 2018
Optimize RefCell refcount tracking

Address the performance concern raised in #51466 (comment)

cc @dtolnay  @nnethercote @rust-lang/wg-compiler-performance

cc @RalfJung @jhjourdan for soundness concerns

Can somebody kick off a perf run on this? I'm not sure how that's done, but I understand it has to be started manually.

The idea of this change is to switch to representing mutable refcount as values below 0 to eliminate some branching that was required with the old algorithm.
@eddyb
Copy link
Member

eddyb commented Jun 27, 2018

@RalfJung @joshlf The more straight-forward option, IME, is using git gui:

  • toggle the mode to Amend Last Commit
  • in Staged Changes (bottom left), click on all the submodules (this will unstage them)
  • click Commit. now your comment is free of submodule changes
  • run git submodule update, or just let x.py do it for you on the next build
    • I would avoid --init --recursive just because it does unnecessary work most of the time

git gui is also the best option for fine-grained committing (line/hunk/file) that comes with git and doesn't involve learning a key-driven TUI. IMO we should have a linkable PSA for this...

@bors
Copy link
Contributor

bors commented Jun 27, 2018

☀️ Test successful - status-travis
State: approved= try=True

@joshlf
Copy link
Contributor Author

joshlf commented Jun 27, 2018

Does something else need to happen for this to be merged?

@nnethercote
Copy link
Contributor

I think someone with appropriate permissions needs to give r+ again. @dtolnay?

@dtolnay
Copy link
Member

dtolnay commented Jun 28, 2018

@bors r+

@bors
Copy link
Contributor

bors commented Jun 28, 2018

📌 Commit 851cc39 has been approved by dtolnay

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 28, 2018
@bors
Copy link
Contributor

bors commented Jun 28, 2018

⌛ Testing commit 851cc39 with merge 8d45fe350d0760d94b50c30021276b5755895eb9...

@bors
Copy link
Contributor

bors commented Jun 28, 2018

💔 Test failed - status-travis

@rust-highfive
Copy link
Collaborator

The job arm-android of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[01:33:08] test time::tests::system_time_elapsed ... ok
[01:33:08] test time::tests::system_time_math ... ok
[01:33:14] test sync::mpsc::tests::stress_recv_timeout_two_threads ... ok
[01:33:15] test collections::hash::map::test_map::test_lots_of_insertions ... ok
[01:33:49] test process::tests::test_process_output_fail_to_start ... test process::tests::test_process_output_fail_to_start has been running for over 60 seconds
No output has been received in the last 30m0s, this potentially indicates a stalled build or something wrong with the build itself.
Check the details on how to adjust your build configuration on: https://docs.travis-ci.com/user/common-build-problems/#Build-times-out-because-no-output-was-received
The build has been terminated

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Jun 28, 2018
@rust-highfive
Copy link
Collaborator

The job arm-android of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[01:33:08] test time::tests::system_time_elapsed ... ok
[01:33:08] test time::tests::system_time_math ... ok
[01:33:14] test sync::mpsc::tests::stress_recv_timeout_two_threads ... ok
[01:33:15] test collections::hash::map::test_map::test_lots_of_insertions ... ok
[01:33:49] test process::tests::test_process_output_fail_to_start ... test process::tests::test_process_output_fail_to_start has been running for over 60 seconds
No output has been received in the last 30m0s, this potentially indicates a stalled build or something wrong with the build itself.
Check the details on how to adjust your build configuration on: https://docs.travis-ci.com/user/common-build-problems/#Build-times-out-because-no-output-was-received
The build has been terminated

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@kennytm
Copy link
Member

kennytm commented Jun 28, 2018

@bors retry

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 28, 2018
@bors
Copy link
Contributor

bors commented Jun 28, 2018

⌛ Testing commit 851cc39 with merge 5d95db3...

bors added a commit that referenced this pull request Jun 28, 2018
Optimize RefCell refcount tracking

Address the performance concern raised in #51466 (comment)

cc @dtolnay  @nnethercote @rust-lang/wg-compiler-performance

cc @RalfJung @jhjourdan for soundness concerns

Can somebody kick off a perf run on this? I'm not sure how that's done, but I understand it has to be started manually.

The idea of this change is to switch to representing mutable refcount as values below 0 to eliminate some branching that was required with the old algorithm.
@bors
Copy link
Contributor

bors commented Jun 28, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: dtolnay
Pushing 5d95db3 to master...

@bors bors merged commit 851cc39 into rust-lang:master Jun 28, 2018
@dtolnay dtolnay self-assigned this Mar 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.