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 validation of arrays #151

Merged
merged 26 commits into from
Oct 22, 2024
Merged

Optimize validation of arrays #151

merged 26 commits into from
Oct 22, 2024

Conversation

nikswamy
Copy link
Contributor

@nikswamy nikswamy commented Oct 18, 2024

In Issue #125, we note that validation for arrays like T f[:byte-size n] should be optimized in case:

  • T is of a fixed size k that divides n
  • Validation of T always succeeds and does not involve any actions

instead of generating a loop to validate the array element-wise, the entire array can be checked with a single arithmetic check.

This PR achieves this by first:

  1. Enhancing the indexing structure of validators so that we can statically detect from the type of a validator whether or not it runs any actions
  2. Revising the EverParse interpreter to target the validate_nlist_constant_size_without_actions combinator, in case the element type of the array has no actions.
  3. Revising the EverParse frontend to produce the appropriate metadata, both to record whether or not a combinator has actions and whether or not the size of T is a compile-time constant (in which case, the modulus check can be statically evaluated way).

Along the way, I migrated LowParse and 3D to use the F* option --ext context_pruning and simplified away the use of various settings, including the use of --using_facts_from in generated 3D code.

BOOLEAN hasEnoughBytes0 = (uint64_t)(uint32_t)10U <= (InputLength - StartPosition);
uint64_t positionAfterT;
if (!hasEnoughBytes0)
BOOLEAN hasBytes0 = (uint64_t)10U <= (InputLength - StartPosition);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

NB: This is generated code from this PR branch. The while loops are gone in favor of a simple arithmetic check

@nikswamy
Copy link
Contributor Author

nikswamy commented Oct 19, 2024

@tahina-pro, I merged in your PR for pairs and also for fixed size arrays (fixing one small bug, see 688122f)

But, still I don't see tuples like { UINT8 fst; UINT8 snd[7]} getting optimized into a single check

I think the issue is that UINT8 snd[7] is represented as T_nlist (Cast.uint8_to_uint32 7uy) _ rather than literally T_nlist (T.Constant _) ...

@nikswamy
Copy link
Contributor Author

nikswamy commented Oct 19, 2024

hi @tahina-pro, I don't think coalescing checking a pair {UINT32 fst; UINT8 f[8]} is going to work in the current design, since the parser kind kind_nlist is defined as

let kind_nlist
  : parser_kind false WeakKindStrongPrefix
  = let open LP in
    {
      parser_kind_low = 0;
      parser_kind_high = None;
      parser_kind_subkind = Some ParserStrong;
      parser_kind_metadata = None
    }

@tahina-pro tahina-pro merged commit 50ddf78 into master Oct 22, 2024
6 checks passed
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.

2 participants