[CSA] Refactor the CSA_ASSERT macro

This refactors some CSA methods to receive an initializer list instead
of endless parameters, and simplifies the macros used to generate the
respecive calls.

R=tebbi@chromium.org

Bug: v8:9396, v8:7629
Change-Id: I318e785da62f139ed9e70df631c426fe1609a42a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1693002
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62624}
This commit is contained in:
Clemens Hammacher 2019-07-09 16:00:22 +02:00 committed by Commit Bot
parent 0fd3766b62
commit f41d3a9b89
2 changed files with 59 additions and 137 deletions

View File

@ -63,57 +63,27 @@ void CodeStubAssembler::HandleBreakOnNode() {
void CodeStubAssembler::Assert(const BranchGenerator& branch,
const char* message, const char* file, int line,
Node* extra_node1, const char* extra_node1_name,
Node* extra_node2, const char* extra_node2_name,
Node* extra_node3, const char* extra_node3_name,
Node* extra_node4, const char* extra_node4_name,
Node* extra_node5,
const char* extra_node5_name) {
std::initializer_list<ExtraNode> extra_nodes) {
#if defined(DEBUG)
if (FLAG_debug_code) {
Check(branch, message, file, line, extra_node1, extra_node1_name,
extra_node2, extra_node2_name, extra_node3, extra_node3_name,
extra_node4, extra_node4_name, extra_node5, extra_node5_name);
Check(branch, message, file, line, extra_nodes);
}
#endif
}
void CodeStubAssembler::Assert(const NodeGenerator& condition_body,
const char* message, const char* file, int line,
Node* extra_node1, const char* extra_node1_name,
Node* extra_node2, const char* extra_node2_name,
Node* extra_node3, const char* extra_node3_name,
Node* extra_node4, const char* extra_node4_name,
Node* extra_node5,
const char* extra_node5_name) {
std::initializer_list<ExtraNode> extra_nodes) {
#if defined(DEBUG)
if (FLAG_debug_code) {
Check(condition_body, message, file, line, extra_node1, extra_node1_name,
extra_node2, extra_node2_name, extra_node3, extra_node3_name,
extra_node4, extra_node4_name, extra_node5, extra_node5_name);
Check(condition_body, message, file, line, extra_nodes);
}
#endif
}
#ifdef DEBUG
namespace {
void MaybePrintNodeWithName(CodeStubAssembler* csa, Node* node,
const char* node_name) {
if (node != nullptr) {
csa->CallRuntime(Runtime::kPrintWithNameForAssert, csa->SmiConstant(0),
csa->StringConstant(node_name), node);
}
}
} // namespace
#endif
void CodeStubAssembler::Check(const BranchGenerator& branch,
const char* message, const char* file, int line,
Node* extra_node1, const char* extra_node1_name,
Node* extra_node2, const char* extra_node2_name,
Node* extra_node3, const char* extra_node3_name,
Node* extra_node4, const char* extra_node4_name,
Node* extra_node5, const char* extra_node5_name) {
std::initializer_list<ExtraNode> extra_nodes) {
Label ok(this);
Label not_ok(this, Label::kDeferred);
if (message != nullptr && FLAG_code_comments) {
@ -124,9 +94,7 @@ void CodeStubAssembler::Check(const BranchGenerator& branch,
branch(&ok, &not_ok);
BIND(&not_ok);
FailAssert(message, file, line, extra_node1, extra_node1_name, extra_node2,
extra_node2_name, extra_node3, extra_node3_name, extra_node4,
extra_node4_name, extra_node5, extra_node5_name);
FailAssert(message, file, line, extra_nodes);
BIND(&ok);
Comment("] Assert");
@ -134,20 +102,14 @@ void CodeStubAssembler::Check(const BranchGenerator& branch,
void CodeStubAssembler::Check(const NodeGenerator& condition_body,
const char* message, const char* file, int line,
Node* extra_node1, const char* extra_node1_name,
Node* extra_node2, const char* extra_node2_name,
Node* extra_node3, const char* extra_node3_name,
Node* extra_node4, const char* extra_node4_name,
Node* extra_node5, const char* extra_node5_name) {
std::initializer_list<ExtraNode> extra_nodes) {
BranchGenerator branch = [=](Label* ok, Label* not_ok) {
Node* condition = condition_body();
DCHECK_NOT_NULL(condition);
Branch(condition, ok, not_ok);
};
Check(branch, message, file, line, extra_node1, extra_node1_name, extra_node2,
extra_node2_name, extra_node3, extra_node3_name, extra_node4,
extra_node4_name, extra_node5, extra_node5_name);
Check(branch, message, file, line, extra_nodes);
}
void CodeStubAssembler::FastCheck(TNode<BoolT> condition) {
@ -162,12 +124,8 @@ void CodeStubAssembler::FastCheck(TNode<BoolT> condition) {
}
void CodeStubAssembler::FailAssert(
const char* message, const char* file, int line, Node* extra_node1,
const char* extra_node1_name, Node* extra_node2,
const char* extra_node2_name, Node* extra_node3,
const char* extra_node3_name, Node* extra_node4,
const char* extra_node4_name, Node* extra_node5,
const char* extra_node5_name) {
const char* message, const char* file, int line,
std::initializer_list<ExtraNode> extra_nodes) {
DCHECK_NOT_NULL(message);
EmbeddedVector<char, 1024> chars;
if (file != nullptr) {
@ -178,11 +136,10 @@ void CodeStubAssembler::FailAssert(
#ifdef DEBUG
// Only print the extra nodes in debug builds.
MaybePrintNodeWithName(this, extra_node1, extra_node1_name);
MaybePrintNodeWithName(this, extra_node2, extra_node2_name);
MaybePrintNodeWithName(this, extra_node3, extra_node3_name);
MaybePrintNodeWithName(this, extra_node4, extra_node4_name);
MaybePrintNodeWithName(this, extra_node5, extra_node5_name);
for (auto& node : extra_nodes) {
CallRuntime(Runtime::kPrintWithNameForAssert, SmiConstant(0),
StringConstant(node.second), node.first);
}
#endif
AbortCSAAssert(message_node);

View File

@ -111,59 +111,45 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
#endif
#ifdef DEBUG
// Add stringified versions to the given values, except the first. That is,
// transform
// x, a, b, c, d, e, f
// to
// a, "a", b, "b", c, "c", d, "d", e, "e", f, "f"
//
// __VA_ARGS__ is ignored to allow the caller to pass through too many
// parameters, and the first element is ignored to support having no extra
// values without empty __VA_ARGS__ (which cause all sorts of problems with
// extra commas).
#define CSA_ASSERT_STRINGIFY_EXTRA_VALUES_5(_, v1, v2, v3, v4, v5, ...) \
v1, #v1, v2, #v2, v3, #v3, v4, #v4, v5, #v5
// CSA_ASSERT_ARGS generates an
// std::initializer_list<CodeStubAssembler::ExtraNode> from __VA_ARGS__. It
// currently supports between 0 and 2 arguments.
// Stringify the given variable number of arguments. The arguments are trimmed
// to 5 if there are too many, and padded with nullptr if there are not enough.
#define CSA_ASSERT_STRINGIFY_EXTRA_VALUES(...) \
CSA_ASSERT_STRINGIFY_EXTRA_VALUES_5(__VA_ARGS__, nullptr, nullptr, nullptr, \
nullptr, nullptr)
#define CSA_ASSERT_GET_FIRST(x, ...) (x)
#define CSA_ASSERT_GET_FIRST_STR(x, ...) #x
// clang-format off
#define CSA_ASSERT_0_ARGS(...) {}
#define CSA_ASSERT_1_ARG(a, ...) {{a, #a}}
#define CSA_ASSERT_2_ARGS(a, b, ...) {{a, #a}, {b, #b}}
// clang-format on
#define SWITCH_CSA_ASSERT_ARGS(dummy, a, b, FUNC, ...) FUNC(a, b)
#define CSA_ASSERT_ARGS(...) \
SWITCH_CSA_ASSERT_ARGS(dummy, ##__VA_ARGS__, CSA_ASSERT_2_ARGS, \
CSA_ASSERT_1_ARG, CSA_ASSERT_0_ARGS)
// CSA_ASSERT(csa, <condition>, <extra values to print...>)
// We have to jump through some hoops to allow <extra values to print...> to be
// empty.
#define CSA_ASSERT(csa, ...) \
(csa)->Assert( \
[&]() -> compiler::Node* { \
return implicit_cast<compiler::SloppyTNode<Word32T>>( \
EXPAND(CSA_ASSERT_GET_FIRST(__VA_ARGS__))); \
}, \
EXPAND(CSA_ASSERT_GET_FIRST_STR(__VA_ARGS__)), __FILE__, __LINE__, \
CSA_ASSERT_STRINGIFY_EXTRA_VALUES(__VA_ARGS__))
#define CSA_ASSERT(csa, condition_node, ...) \
(csa)->Assert( \
[&]() -> compiler::Node* { \
return implicit_cast<compiler::SloppyTNode<Word32T>>(condition_node); \
}, \
#condition_node, __FILE__, __LINE__, CSA_ASSERT_ARGS(__VA_ARGS__))
// CSA_ASSERT_BRANCH(csa, [](Label* ok, Label* not_ok) {...},
// <extra values to print...>)
#define CSA_ASSERT_BRANCH(csa, ...) \
(csa)->Assert(EXPAND(CSA_ASSERT_GET_FIRST(__VA_ARGS__)), \
EXPAND(CSA_ASSERT_GET_FIRST_STR(__VA_ARGS__)), __FILE__, \
__LINE__, CSA_ASSERT_STRINGIFY_EXTRA_VALUES(__VA_ARGS__))
#define CSA_ASSERT_BRANCH(csa, gen, ...) \
(csa)->Assert(gen, #gen, __FILE__, __LINE__, CSA_ASSERT_ARGS(__VA_ARGS__))
#define CSA_ASSERT_JS_ARGC_OP(csa, Op, op, expected) \
(csa)->Assert( \
[&]() -> compiler::Node* { \
compiler::Node* const argc = \
(csa)->Parameter(Descriptor::kJSActualArgumentsCount); \
return (csa)->Op(argc, (csa)->Int32Constant(expected)); \
}, \
"argc " #op " " #expected, __FILE__, __LINE__, \
SmiFromInt32((csa)->Parameter(Descriptor::kJSActualArgumentsCount)), \
"argc")
#define CSA_ASSERT_JS_ARGC_OP(csa, Op, op, expected) \
(csa)->Assert( \
[&]() -> compiler::Node* { \
compiler::Node* const argc = \
(csa)->Parameter(Descriptor::kJSActualArgumentsCount); \
return (csa)->Op(argc, (csa)->Int32Constant(expected)); \
}, \
"argc " #op " " #expected, __FILE__, __LINE__, \
{{SmiFromInt32((csa)->Parameter(Descriptor::kJSActualArgumentsCount)), \
"argc"}})
#define CSA_ASSERT_JS_ARGC_EQ(csa, expected) \
CSA_ASSERT_JS_ARGC_OP(csa, Word32Equal, ==, expected)
@ -628,43 +614,22 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
using BranchGenerator = std::function<void(Label*, Label*)>;
using NodeGenerator = std::function<Node*()>;
using ExtraNode = std::pair<Node*, const char*>;
void Assert(const BranchGenerator& branch, const char* message = nullptr,
const char* file = nullptr, int line = 0,
Node* extra_node1 = nullptr, const char* extra_node1_name = "",
Node* extra_node2 = nullptr, const char* extra_node2_name = "",
Node* extra_node3 = nullptr, const char* extra_node3_name = "",
Node* extra_node4 = nullptr, const char* extra_node4_name = "",
Node* extra_node5 = nullptr, const char* extra_node5_name = "");
void Assert(const NodeGenerator& condition_body,
const char* message = nullptr, const char* file = nullptr,
int line = 0, Node* extra_node1 = nullptr,
const char* extra_node1_name = "", Node* extra_node2 = nullptr,
const char* extra_node2_name = "", Node* extra_node3 = nullptr,
const char* extra_node3_name = "", Node* extra_node4 = nullptr,
const char* extra_node4_name = "", Node* extra_node5 = nullptr,
const char* extra_node5_name = "");
void Check(const BranchGenerator& branch, const char* message = nullptr,
const char* file = nullptr, int line = 0,
Node* extra_node1 = nullptr, const char* extra_node1_name = "",
Node* extra_node2 = nullptr, const char* extra_node2_name = "",
Node* extra_node3 = nullptr, const char* extra_node3_name = "",
Node* extra_node4 = nullptr, const char* extra_node4_name = "",
Node* extra_node5 = nullptr, const char* extra_node5_name = "");
void Check(const NodeGenerator& condition_body, const char* message = nullptr,
const char* file = nullptr, int line = 0,
Node* extra_node1 = nullptr, const char* extra_node1_name = "",
Node* extra_node2 = nullptr, const char* extra_node2_name = "",
Node* extra_node3 = nullptr, const char* extra_node3_name = "",
Node* extra_node4 = nullptr, const char* extra_node4_name = "",
Node* extra_node5 = nullptr, const char* extra_node5_name = "");
void FailAssert(
const char* message = nullptr, const char* file = nullptr, int line = 0,
Node* extra_node1 = nullptr, const char* extra_node1_name = "",
Node* extra_node2 = nullptr, const char* extra_node2_name = "",
Node* extra_node3 = nullptr, const char* extra_node3_name = "",
Node* extra_node4 = nullptr, const char* extra_node4_name = "",
Node* extra_node5 = nullptr, const char* extra_node5_name = "");
void Assert(const BranchGenerator& branch, const char* message,
const char* file, int line,
std::initializer_list<ExtraNode> extra_nodes = {});
void Assert(const NodeGenerator& condition_body, const char* message,
const char* file, int line,
std::initializer_list<ExtraNode> extra_nodes = {});
void Check(const BranchGenerator& branch, const char* message,
const char* file, int line,
std::initializer_list<ExtraNode> extra_nodes = {});
void Check(const NodeGenerator& condition_body, const char* message,
const char* file, int line,
std::initializer_list<ExtraNode> extra_nodes = {});
void FailAssert(const char* message, const char* file, int line,
std::initializer_list<ExtraNode> extra_nodes = {});
void FastCheck(TNode<BoolT> condition);