Skip to content

Commit

Permalink
Fix Debug for Value during GC
Browse files Browse the repository at this point in the history
Summary:
Context:

```
value = pointer ->
  union {
    [ vtable ptr                     | value data    ] # normal value
    [ target ptr with lowest bit set | old self size ] # "forward" value during GC
  }
```

During GC, `Value` after value is moved, data is replaced with forward value.

All normal `Value` operations crash on forward value. But debug should work.

Reviewed By: rajneesh

Differential Revision: D62771488

fbshipit-source-id: aba664c8ea56957a37db32b74e571a0e7ea3e4c1
  • Loading branch information
stepancheg authored and facebook-github-bot committed Sep 17, 2024
1 parent 350ca26 commit 6d0fdbf
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 0 deletions.
1 change: 1 addition & 0 deletions starlark/src/values/layout/heap/repr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ impl ForwardPtr {

/// This is object written over [`AValueRepr`] during GC.
#[repr(C)]
#[derive(Debug)]
pub(crate) struct AValueForward {
/// Moved object pointer with lowest bit set.
forward_ptr: usize,
Expand Down
9 changes: 9 additions & 0 deletions starlark/src/values/layout/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ use crate::values::iter::StarlarkIterator;
use crate::values::layout::avalue::AValue;
use crate::values::layout::avalue::AValueImpl;
use crate::values::layout::heap::repr::AValueHeader;
use crate::values::layout::heap::repr::AValueOrForwardUnpack;
use crate::values::layout::heap::repr::AValueRepr;
use crate::values::layout::pointer::FrozenPointer;
use crate::values::layout::pointer::Pointer;
Expand Down Expand Up @@ -176,6 +177,14 @@ impl Display for FrozenValue {
}

fn debug_value(typ: &str, v: Value, f: &mut fmt::Formatter) -> fmt::Result {
// When value is being moved during GC or freeze,
// `Value` pointee is not a proper value, but a GC-related information.
// Regular operations like `.to_repr()` crash, but `Debug` should work.
if let Some(x) = v.0.unpack_ptr() {
if let AValueOrForwardUnpack::Forward(fwd) = x.unpack() {
return f.debug_tuple(typ).field(&fwd).finish();
}
}
f.debug_tuple(typ).field(v.get_ref().as_debug()).finish()
}

Expand Down

0 comments on commit 6d0fdbf

Please sign in to comment.