Reduce the stack frame size for CmpHelper* functions by moving the failure path into their own functions.

This commit is contained in:
kosak 2014-11-17 00:06:22 +00:00
parent 64df8e349f
commit 6884259b7d

View File

@ -1457,6 +1457,20 @@ std::string FormatForComparisonFailureMessage(
return FormatForComparison<T1, T2>::Format(value); return FormatForComparison<T1, T2>::Format(value);
} }
// Separate the error generating code from the code path to reduce the stack
// frame size of CmpHelperEQ. This helps reduce the overhead of some sanitizers
// when calling EXPECT_* in a tight loop.
template <typename T1, typename T2>
AssertionResult CmpHelperEQFailure(const char* expected_expression,
const char* actual_expression,
const T1& expected, const T2& actual) {
return EqFailure(expected_expression,
actual_expression,
FormatForComparisonFailureMessage(expected, actual),
FormatForComparisonFailureMessage(actual, expected),
false);
}
// The helper function for {ASSERT|EXPECT}_EQ. // The helper function for {ASSERT|EXPECT}_EQ.
template <typename T1, typename T2> template <typename T1, typename T2>
AssertionResult CmpHelperEQ(const char* expected_expression, AssertionResult CmpHelperEQ(const char* expected_expression,
@ -1469,11 +1483,8 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4389 /* signed/unsigned mismatch */)
} }
GTEST_DISABLE_MSC_WARNINGS_POP_() GTEST_DISABLE_MSC_WARNINGS_POP_()
return EqFailure(expected_expression, return CmpHelperEQFailure(expected_expression, actual_expression, expected,
actual_expression, actual);
FormatForComparisonFailureMessage(expected, actual),
FormatForComparisonFailureMessage(actual, expected),
false);
} }
// With this overloaded version, we allow anonymous enums to be used // With this overloaded version, we allow anonymous enums to be used
@ -1561,6 +1572,19 @@ class EqHelper<true> {
} }
}; };
// Separate the error generating code from the code path to reduce the stack
// frame size of CmpHelperOP. This helps reduce the overhead of some sanitizers
// when calling EXPECT_OP in a tight loop.
template <typename T1, typename T2>
AssertionResult CmpHelperOpFailure(const char* expr1, const char* expr2,
const T1& val1, const T2& val2,
const char* op) {
return AssertionFailure()
<< "Expected: (" << expr1 << ") " << op << " (" << expr2
<< "), actual: " << FormatForComparisonFailureMessage(val1, val2)
<< " vs " << FormatForComparisonFailureMessage(val2, val1);
}
// A macro for implementing the helper functions needed to implement // A macro for implementing the helper functions needed to implement
// ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste // ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste
// of similar code. // of similar code.
@ -1571,6 +1595,7 @@ class EqHelper<true> {
// with gcc 4. // with gcc 4.
// //
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ #define GTEST_IMPL_CMP_HELPER_(op_name, op)\
template <typename T1, typename T2>\ template <typename T1, typename T2>\
AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \
@ -1578,10 +1603,7 @@ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \
if (val1 op val2) {\ if (val1 op val2) {\
return AssertionSuccess();\ return AssertionSuccess();\
} else {\ } else {\
return AssertionFailure() \ return CmpHelperOpFailure(expr1, expr2, val1, val2, #op);\
<< "Expected: (" << expr1 << ") " #op " (" << expr2\
<< "), actual: " << FormatForComparisonFailureMessage(val1, val2)\
<< " vs " << FormatForComparisonFailureMessage(val2, val1);\
}\ }\
}\ }\
GTEST_API_ AssertionResult CmpHelper##op_name(\ GTEST_API_ AssertionResult CmpHelper##op_name(\