mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 1171842 - Use jump table instead of nested if statements for peeking compute function of style struct. r=dbaron
--HG-- extra : source : c16172954389dff27f9fee7d4bacc949de662a4c
This commit is contained in:
parent
6508b24916
commit
7f4096ebd9
@ -9,33 +9,7 @@
|
||||
#
|
||||
# 1. To generate code for each inherited style struct.
|
||||
# 2. To generate code for each reset style struct.
|
||||
# 3. To generate a tree of nested if statements that can be used to run
|
||||
# some code on each style struct.
|
||||
#
|
||||
# As an example, if we assume that we have only four style structs, the
|
||||
# generated tree of nested if statements looks like this:
|
||||
#
|
||||
# if (STYLE_STRUCT_TEST < 4) {
|
||||
# if (STYLE_STRUCT_TEST < 2) {
|
||||
# if (STYLE_STRUCT_TEST == 0) {
|
||||
# ... code for style struct with id 0 ...
|
||||
# } else {
|
||||
# ... code for style struct with id 1 ...
|
||||
# }
|
||||
# } else {
|
||||
# if (STYLE_STRUCT_TEST == 2) {
|
||||
# ... code for style struct with id 2 ...
|
||||
# } else {
|
||||
# ... code for style struct with id 3 ...
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# The TOPLEVELBRANCHES variable controls how widely we branch on the outermost
|
||||
# if statement. In the example above, it splits the search space in 2, but with
|
||||
# a larger number of style structs to test -- particularly when the number is
|
||||
# closer to one power of two than the next higher one -- the average number of
|
||||
# comparisons can be reduced by splitting the top level check into more than 2.
|
||||
# 3. To generate the dependency of each style struct.
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
@ -77,9 +51,6 @@ STYLE_STRUCTS = [("INHERITED",) + x for x in [
|
||||
("Column", "nullptr", NORMAL_DEP + LENGTH_DEP + COLOR_DEP),
|
||||
]]
|
||||
|
||||
# How widely to branch on the outermost if statement.
|
||||
TOPLEVELBRANCHES = 4
|
||||
|
||||
|
||||
# ---- Generate nsStyleStructList.h ----
|
||||
|
||||
@ -116,42 +87,12 @@ for i in range(count):
|
||||
"the following structs:", " ".join(unsolved_items), file=sys.stderr)
|
||||
exit(1)
|
||||
|
||||
def nextPowerOf2(x):
|
||||
return int(pow(2, math.ceil(math.log(x, 2))))
|
||||
|
||||
def printEntry(header, i):
|
||||
print("STYLE_STRUCT_%s(%s, %s)" % STYLE_STRUCTS[i][:3], file=header)
|
||||
for dep in STYLE_STRUCTS[i][3]:
|
||||
print("STYLE_STRUCT_DEP(%s)" % (dep,), file=header)
|
||||
print("STYLE_STRUCT_END()", file=header)
|
||||
|
||||
def printTestTree(header, min, max, depth, branches):
|
||||
indent = " " * depth
|
||||
if min == count - 1 and max >= count:
|
||||
print(" STYLE_STRUCT_TEST_CODE(%sNS_ASSERTION(STYLE_STRUCT_TEST == %d, \"out of range\");)" % (indent, min), file=header)
|
||||
printEntry(header, min)
|
||||
elif max - min == 2:
|
||||
print(" STYLE_STRUCT_TEST_CODE(%sif (STYLE_STRUCT_TEST == %d) {)" % (indent, min), file=header)
|
||||
printEntry(header, min)
|
||||
print(" STYLE_STRUCT_TEST_CODE(%s} else {)" % indent, file=header)
|
||||
printEntry(header, min + 1)
|
||||
print(" STYLE_STRUCT_TEST_CODE(%s})" % indent, file=header)
|
||||
elif min < count:
|
||||
mid = min + (max - min) / branches
|
||||
print(" STYLE_STRUCT_TEST_CODE(%sif (STYLE_STRUCT_TEST < %d) {)" % (indent, mid), file=header)
|
||||
printTestTree(header, min, mid, depth + 1, 2)
|
||||
for branch in range(1, branches):
|
||||
lo = min + branch * (max - min) / branches
|
||||
hi = min + (branch + 1) * (max - min) / branches
|
||||
if lo >= count:
|
||||
break
|
||||
if branch == branches - 1 or hi >= count:
|
||||
print(" STYLE_STRUCT_TEST_CODE(%s} else {)" % indent, file=header)
|
||||
else:
|
||||
print(" STYLE_STRUCT_TEST_CODE(%s} else if (STYLE_STRUCT_TEST < %d) {)" % (indent, hi), file=header)
|
||||
printTestTree(header, lo, hi, depth + 1, 2)
|
||||
print(" STYLE_STRUCT_TEST_CODE(%s})" % indent, file=header)
|
||||
|
||||
HEADER = """/* THIS FILE IS AUTOGENERATED BY generate-stylestructlist.py - DO NOT EDIT */
|
||||
|
||||
// IWYU pragma: private, include "nsStyleStructFwd.h"
|
||||
@ -189,12 +130,6 @@ HEADER = """/* THIS FILE IS AUTOGENERATED BY generate-stylestructlist.py - DO NO
|
||||
#define UNDEF_STYLE_STRUCT_END
|
||||
#endif
|
||||
|
||||
#ifdef STYLE_STRUCT_TEST
|
||||
#define STYLE_STRUCT_TEST_CODE(c) c
|
||||
#else
|
||||
#define STYLE_STRUCT_TEST_CODE(c)
|
||||
#endif
|
||||
|
||||
// The inherited structs are listed before the Reset structs.
|
||||
// nsStyleStructID assumes this is the case, and callers other than
|
||||
// nsStyleStructFwd.h that want the structs in id-order just define
|
||||
@ -221,11 +156,10 @@ FOOTER = """
|
||||
#undef STYLE_STRUCT_END
|
||||
#undef UNDEF_STYLE_STRUCT_END
|
||||
#endif
|
||||
|
||||
#undef STYLE_STRUCT_TEST_CODE
|
||||
"""
|
||||
|
||||
def main(header):
|
||||
print(HEADER, file=header)
|
||||
printTestTree(header, 0, nextPowerOf2(count), 0, TOPLEVELBRANCHES)
|
||||
for i in range(count):
|
||||
printEntry(header, i)
|
||||
print(FOOTER, file=header)
|
||||
|
@ -2387,18 +2387,19 @@ nsRuleNode::WalkRuleTree(const nsStyleStructID aSID,
|
||||
return SetDefaultOnRoot(aSID, aContext);
|
||||
}
|
||||
|
||||
// We need to compute the data from the information that the rules specified.
|
||||
const void* res;
|
||||
#define STYLE_STRUCT_TEST aSID
|
||||
#define STYLE_STRUCT(name, checkdata_cb) \
|
||||
res = Compute##name##Data(startStruct, &ruleData, aContext, \
|
||||
highestNode, detail, ruleData.mCanStoreInRuleTree);
|
||||
typedef const void* (nsRuleNode::*ComputeFunc)(void*, const nsRuleData*,
|
||||
nsStyleContext*, nsRuleNode*,
|
||||
RuleDetail, const bool);
|
||||
static const ComputeFunc sComputeFuncs[] = {
|
||||
#define STYLE_STRUCT(name, checkdata_cb) &nsRuleNode::Compute##name##Data,
|
||||
#include "nsStyleStructList.h"
|
||||
#undef STYLE_STRUCT
|
||||
#undef STYLE_STRUCT_TEST
|
||||
};
|
||||
|
||||
// Now return the result.
|
||||
return res;
|
||||
// We need to compute the data from the information that the rules specified.
|
||||
return (this->*sComputeFuncs[aSID])(startStruct, &ruleData, aContext,
|
||||
highestNode, detail,
|
||||
ruleData.mCanStoreInRuleTree);
|
||||
}
|
||||
|
||||
const void*
|
||||
|
Loading…
Reference in New Issue
Block a user