mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-31 06:16:03 +00:00
parser - push normalize_tree() ops into expr-tree classes
This is patch tries to reduce the number of dynamic_cast<>s needed during normalization by pushing the operations of normalize_tree() into the expr-tree classes themselves rather than perform it as an external function. This eliminates the need for dynamic_cast<> checks on the current object under inspection and reduces the number of checks needing to be performed on child Nodes as well. In non-strict benchmarking, doing the dynamic_cast<> reduction for just the tree normalization operation resulted in a ~10-15% improvement in overall time on a couple of different hosts (amd64, armel), as measured against apparmor_parser -Q. Valgrind's callgrind tool indicated a reduction in the number of calls to dynamic_cast<> on the tst/simple_tests/vars/dbus_vars_9.sd test profile from ~19 million calls to ~12 million. In comparisons with dumped expr trees over both the entire tst/simple_tests/ tree and from 1000 randomly generated profiles via stress.rb, the generated trees were identical. Patch history: v1: initial version of patch v2: update patch to take into account the infinite loop fix in trunk rev 1975 and refresh against current code. v3: no change Signed-off-by: Steve Beattie <steve@nxnw.org> Acked-by: Seth Arnold <seth.arnold@canonical.com> Acked-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* (C) 2006, 2007 Andreas Gruenbacher <agruen@suse.de>
|
||||
* Copyright (c) 2003-2008 Novell, Inc. (All rights reserved)
|
||||
* Copyright 2009-2012 Canonical Ltd.
|
||||
* Copyright 2009-2013 Canonical Ltd.
|
||||
*
|
||||
* The libapparmor library is licensed under the terms of the GNU
|
||||
* Lesser General Public License, version 2.1. Please see the file
|
||||
@@ -126,6 +126,15 @@ public:
|
||||
virtual int eq(Node *other) = 0;
|
||||
virtual ostream &dump(ostream &os) = 0;
|
||||
void dump_syntax_tree(ostream &os);
|
||||
virtual void normalize(int dir)
|
||||
{
|
||||
if (child[dir])
|
||||
child[dir]->normalize(dir);
|
||||
if (child[!dir])
|
||||
child[!dir]->normalize(dir);
|
||||
}
|
||||
/* return false if no work done */
|
||||
virtual int normalize_eps(int dir __attribute__((unused))) { return 0; }
|
||||
|
||||
bool nullable;
|
||||
NodeSet firstpos, lastpos, followpos;
|
||||
@@ -157,11 +166,13 @@ public:
|
||||
class TwoChildNode: public InnerNode {
|
||||
public:
|
||||
TwoChildNode(Node *left, Node *right): InnerNode(left, right) { };
|
||||
virtual int normalize_eps(int dir);
|
||||
};
|
||||
|
||||
class LeafNode: public Node {
|
||||
public:
|
||||
LeafNode(): Node() { };
|
||||
virtual void normalize(int dir __attribute__((unused))) { return; }
|
||||
};
|
||||
|
||||
/* Match nothing (//). */
|
||||
@@ -485,6 +496,7 @@ public:
|
||||
child[1]->dump(os);
|
||||
return os;
|
||||
}
|
||||
void normalize(int dir);
|
||||
};
|
||||
|
||||
/* Match one of two alternative nodes. */
|
||||
@@ -521,6 +533,7 @@ public:
|
||||
os << ')';
|
||||
return os;
|
||||
}
|
||||
void normalize(int dir);
|
||||
};
|
||||
|
||||
/* Traverse the syntax tree depth-first in an iterator-like manner. */
|
||||
|
Reference in New Issue
Block a user