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

Add EntriesTree #149

Merged
merged 4 commits into from
Oct 16, 2016
Merged

Add EntriesTree #149

merged 4 commits into from
Oct 16, 2016

Conversation

philipc
Copy link
Collaborator

@philipc philipc commented Oct 11, 2016

This allows recursive iteration of DIEs as a tree, without the caller needing to manage the depth changes, even if some levels of the tree are only partially iterated. It is implemented using a single EntriesCursor, so there is no duplicate parsing of entries, and next_sibling is used where possible. However, there is still some overhead compared to a DFS iteration:

test bench_parsing_debug_info       ...  bench:   2,398,562 ns/iter (+/- 68,747)
test bench_parsing_debug_info_tree  ...  bench:   2,840,048 ns/iter (+/- 72,544)

See the bench_parsing_debug_info_tree benchmark for an example of its usage.

My motivation for adding this is that it allows simpler use of gimli in ruby-stacktrace. However, I'm not sure how much of that benefit will remain once gimli gains higher level interpretation of the DIE tree.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.03%) to 93.735% when pulling 3169263 on philipc:tree into c7399c0 on gimli-rs:master.

///
/// Generally, this function should only be called when the `EntriesTree`
/// is first created. This will give an iterator for the children of the
/// root entry. The result of subsequent calls to this function is unspecified.
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 just make it take self instead of &mut self then, IMO. This would prevent subsequent calls from being possible. Any reason why you didn't pursue this?

Copy link
Member

Choose a reason for hiding this comment

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

Or maybe assert! against calling it more than once, if we need all the EntryTreeIters to share a single &mut EntriesTree reference?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We should just make it take self instead of &mut self then, IMO. This would prevent subsequent calls from being possible. Any reason why you didn't pursue this?

We would need to return both a new self and the iterator, and the iterator needs to be a borrow of the new self, which I don't think is possible.

Or maybe assert! against calling it more than once, if we need all the EntryTreeIters to share a single &mut EntriesTree reference?

We would need add a new flag to assert against. If we were going to take that approach, then I would prefer to instead make it possible to call iter more than once (I think this would simply need to store the starting offset of the cursor).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've added a commit to allow iteration more than once. Trying to get the cursor offset was complicated, so I've cloned the cursor. We can change that later if we ever add get_offset/set_offset operations on the cursor.

/// The `EntriesTree` can be used to recursively iterate through the DIE
/// tree, following the parent/child relationships. It maintains a single
/// `EntriesCursor` that is used to parse the entries, allowing it to avoid
/// any duplicate parsing of entries.
Copy link
Member

Choose a reason for hiding this comment

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

It would be really nice to have an example usage here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Will do.

This allows recursive iteration of DIEs as a tree, without the caller
needing to manage the depth changes, even if some levels of the tree
are only partially iterated.  It is implemented using a single
EntriesCursor, so there is no duplicate parsing of entries, and
next_sibling is used where possible.  However, there is still some
overhead compared to a DFS iteration:

test bench_parsing_debug_info       ...  bench:   2,398,562 ns/iter (+/- 68,747)
test bench_parsing_debug_info_tree  ...  bench:   2,840,048 ns/iter (+/- 72,544)
@coveralls
Copy link

Coverage Status

Coverage increased (+0.01%) to 93.782% when pulling 0c6d820 on philipc:tree into c7399c0 on gimli-rs:master.

1 similar comment
@coveralls
Copy link

Coverage Status

Coverage increased (+0.01%) to 93.782% when pulling 0c6d820 on philipc:tree into c7399c0 on gimli-rs:master.

Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

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

LGTM

@philipc philipc merged commit 3fcbffa into gimli-rs:master Oct 16, 2016
@philipc philipc deleted the tree branch October 16, 2016 02:45
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.

3 participants