diff --git a/src/regexp/regexp-compiler-tonode.cc b/src/regexp/regexp-compiler-tonode.cc index d8c0d24732..d1c8c56545 100644 --- a/src/regexp/regexp-compiler-tonode.cc +++ b/src/regexp/regexp-compiler-tonode.cc @@ -778,6 +778,8 @@ void RegExpDisjunction::FixSingleCharacterDisjunctions( RegExpNode* RegExpDisjunction::ToNode(RegExpCompiler* compiler, RegExpNode* on_success) { + compiler->ToNodeMaybeCheckForStackOverflow(); + ZoneList* alternatives = this->alternatives(); if (alternatives->length() > 2) { @@ -1089,6 +1091,8 @@ class AssertionSequenceRewriter final { RegExpNode* RegExpAlternative::ToNode(RegExpCompiler* compiler, RegExpNode* on_success) { + compiler->ToNodeMaybeCheckForStackOverflow(); + ZoneList* children = nodes(); AssertionSequenceRewriter::MaybeRewrite(children, compiler->zone()); diff --git a/src/regexp/regexp-compiler.cc b/src/regexp/regexp-compiler.cc index c3ecff9d43..36366a38c0 100644 --- a/src/regexp/regexp-compiler.cc +++ b/src/regexp/regexp-compiler.cc @@ -3950,5 +3950,9 @@ RegExpNode* RegExpCompiler::PreprocessRegExp(RegExpCompileData* data, return node; } +void RegExpCompiler::ToNodeCheckForStackOverflow() { + CHECK(!StackLimitCheck{isolate()}.HasOverflowed()); +} + } // namespace internal } // namespace v8 diff --git a/src/regexp/regexp-compiler.h b/src/regexp/regexp-compiler.h index 832a966217..421fc9457c 100644 --- a/src/regexp/regexp-compiler.h +++ b/src/regexp/regexp-compiler.h @@ -550,6 +550,18 @@ class RegExpCompiler { current_expansion_factor_ = value; } + // The recursive nature of ToNode node generation means we may run into stack + // overflow issues. We introduce periodic checks to detect these, and the + // tick counter helps limit overhead of these checks. + // TODO(jgruber): This is super hacky and should be replaced by an abort + // mechanism or iterative node generation. + void ToNodeMaybeCheckForStackOverflow() { + if ((to_node_overflow_check_ticks_++ % 16 == 0)) { + ToNodeCheckForStackOverflow(); + } + } + void ToNodeCheckForStackOverflow(); + Isolate* isolate() const { return isolate_; } Zone* zone() const { return zone_; } @@ -567,6 +579,7 @@ class RegExpCompiler { bool one_byte_; bool reg_exp_too_big_; bool limiting_recursion_; + int to_node_overflow_check_ticks_ = 0; bool optimize_; bool read_backward_; int current_expansion_factor_; diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status index c9d9de4151..07272d0c7c 100644 --- a/test/mjsunit/mjsunit.status +++ b/test/mjsunit/mjsunit.status @@ -180,6 +180,9 @@ # https://crbug.com/v8/10948 'wasm/atomics': [PASS, ['arch == arm and not simulator_run', SKIP]], + # crbug.com/v8/12472 Stack overflow during regexp node generation. + 'regress/regress-crbug-595657': [SKIP], + ############################################################################## # Tests where variants make no sense. 'd8/enable-tracing': [PASS, NO_VARIANTS],