summaryrefslogtreecommitdiff
path: root/deps/v8/src/regexp
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/regexp')
-rw-r--r--deps/v8/src/regexp/arm/regexp-macro-assembler-arm.cc9
-rw-r--r--deps/v8/src/regexp/loong64/regexp-macro-assembler-loong64.cc11
-rw-r--r--deps/v8/src/regexp/mips/regexp-macro-assembler-mips.cc9
-rw-r--r--deps/v8/src/regexp/mips64/regexp-macro-assembler-mips64.cc11
-rw-r--r--deps/v8/src/regexp/ppc/regexp-macro-assembler-ppc.cc17
-rw-r--r--deps/v8/src/regexp/ppc/regexp-macro-assembler-ppc.h3
-rw-r--r--deps/v8/src/regexp/regexp-compiler-tonode.cc101
-rw-r--r--deps/v8/src/regexp/regexp-compiler.cc6
-rw-r--r--deps/v8/src/regexp/regexp-compiler.h13
-rw-r--r--deps/v8/src/regexp/regexp-interpreter.cc4
-rw-r--r--deps/v8/src/regexp/regexp-parser.cc5
-rw-r--r--deps/v8/src/regexp/regexp-utils.cc3
-rw-r--r--deps/v8/src/regexp/regexp.cc5
-rw-r--r--deps/v8/src/regexp/riscv64/regexp-macro-assembler-riscv64.cc74
-rw-r--r--deps/v8/src/regexp/riscv64/regexp-macro-assembler-riscv64.h3
-rw-r--r--deps/v8/src/regexp/s390/regexp-macro-assembler-s390.cc14
-rw-r--r--deps/v8/src/regexp/s390/regexp-macro-assembler-s390.h3
17 files changed, 182 insertions, 109 deletions
diff --git a/deps/v8/src/regexp/arm/regexp-macro-assembler-arm.cc b/deps/v8/src/regexp/arm/regexp-macro-assembler-arm.cc
index 72770779b9..78be35552e 100644
--- a/deps/v8/src/regexp/arm/regexp-macro-assembler-arm.cc
+++ b/deps/v8/src/regexp/arm/regexp-macro-assembler-arm.cc
@@ -702,10 +702,9 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
// Start new stack frame.
// Store link register in existing stack-cell.
// Order here should correspond to order of offset constants in header file.
- RegList registers_to_retain = r4.bit() | r5.bit() | r6.bit() |
- r7.bit() | r8.bit() | r9.bit() | r10.bit() | fp.bit();
- RegList argument_registers = r0.bit() | r1.bit() | r2.bit() | r3.bit();
- __ stm(db_w, sp, argument_registers | registers_to_retain | lr.bit());
+ RegList registers_to_retain = {r4, r5, r6, r7, r8, r9, r10, fp};
+ RegList argument_registers = {r0, r1, r2, r3};
+ __ stm(db_w, sp, argument_registers | registers_to_retain | lr);
// Set frame pointer in space for it if this is not a direct call
// from generated code.
__ add(frame_pointer(), sp, Operand(4 * kPointerSize));
@@ -922,7 +921,7 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
// Skip sp past regexp registers and local variables..
__ mov(sp, frame_pointer());
// Restore registers r4..r11 and return (restoring lr to pc).
- __ ldm(ia_w, sp, registers_to_retain | pc.bit());
+ __ ldm(ia_w, sp, registers_to_retain | pc);
// Backtrack code (branch target for conditional backtracks).
if (backtrack_label_.is_linked()) {
diff --git a/deps/v8/src/regexp/loong64/regexp-macro-assembler-loong64.cc b/deps/v8/src/regexp/loong64/regexp-macro-assembler-loong64.cc
index 3db9a90c29..c60a714339 100644
--- a/deps/v8/src/regexp/loong64/regexp-macro-assembler-loong64.cc
+++ b/deps/v8/src/regexp/loong64/regexp-macro-assembler-loong64.cc
@@ -667,13 +667,12 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
// Order here should correspond to order of offset constants in header file.
// TODO(plind): we save s0..s7, but ONLY use s3 here - use the regs
// or dont save.
- RegList registers_to_retain = s0.bit() | s1.bit() | s2.bit() | s3.bit() |
- s4.bit() | s5.bit() | s6.bit() | s7.bit();
- RegList argument_registers = a0.bit() | a1.bit() | a2.bit() | a3.bit();
+ RegList registers_to_retain = {s0, s1, s2, s3, s4, s5, s6, s7};
+ RegList argument_registers = {a0, a1, a2, a3};
- argument_registers |= a4.bit() | a5.bit() | a6.bit() | a7.bit();
+ argument_registers |= {a4, a5, a6, a7};
- __ MultiPush(ra.bit(), fp.bit(), argument_registers | registers_to_retain);
+ __ MultiPush({ra}, {fp}, argument_registers | registers_to_retain);
// Set frame pointer in space for it if this is not a direct call
// from generated code.
// TODO(plind): this 8 is the # of argument regs, should have definition.
@@ -894,7 +893,7 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
// Skip sp past regexp registers and local variables..
__ mov(sp, frame_pointer());
// Restore registers s0..s7 and return (restoring ra to pc).
- __ MultiPop(ra.bit(), fp.bit(), registers_to_retain);
+ __ MultiPop({ra}, {fp}, registers_to_retain);
__ Ret();
// Backtrack code (branch target for conditional backtracks).
diff --git a/deps/v8/src/regexp/mips/regexp-macro-assembler-mips.cc b/deps/v8/src/regexp/mips/regexp-macro-assembler-mips.cc
index 74a42ef815..dafc657f81 100644
--- a/deps/v8/src/regexp/mips/regexp-macro-assembler-mips.cc
+++ b/deps/v8/src/regexp/mips/regexp-macro-assembler-mips.cc
@@ -681,10 +681,9 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// Start new stack frame.
// Store link register in existing stack-cell.
// Order here should correspond to order of offset constants in header file.
- RegList registers_to_retain = s0.bit() | s1.bit() | s2.bit() |
- s3.bit() | s4.bit() | s5.bit() | s6.bit() | s7.bit() | fp.bit();
- RegList argument_registers = a0.bit() | a1.bit() | a2.bit() | a3.bit();
- __ MultiPush(argument_registers | registers_to_retain | ra.bit());
+ RegList registers_to_retain = {s0, s1, s2, s3, s4, s5, s6, s7, fp};
+ RegList argument_registers = {a0, a1, a2, a3};
+ __ MultiPush(argument_registers | registers_to_retain | ra);
// Set frame pointer in space for it if this is not a direct call
// from generated code.
__ Addu(frame_pointer(), sp, Operand(4 * kPointerSize));
@@ -905,7 +904,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// Skip sp past regexp registers and local variables..
__ mov(sp, frame_pointer());
// Restore registers s0..s7 and return (restoring ra to pc).
- __ MultiPop(registers_to_retain | ra.bit());
+ __ MultiPop(registers_to_retain | ra);
__ Ret();
// Backtrack code (branch target for conditional backtracks).
diff --git a/deps/v8/src/regexp/mips64/regexp-macro-assembler-mips64.cc b/deps/v8/src/regexp/mips64/regexp-macro-assembler-mips64.cc
index bee0e57501..17546ed52d 100644
--- a/deps/v8/src/regexp/mips64/regexp-macro-assembler-mips64.cc
+++ b/deps/v8/src/regexp/mips64/regexp-macro-assembler-mips64.cc
@@ -715,13 +715,12 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// Order here should correspond to order of offset constants in header file.
// TODO(plind): we save s0..s7, but ONLY use s3 here - use the regs
// or dont save.
- RegList registers_to_retain = s0.bit() | s1.bit() | s2.bit() |
- s3.bit() | s4.bit() | s5.bit() | s6.bit() | s7.bit() | fp.bit();
- RegList argument_registers = a0.bit() | a1.bit() | a2.bit() | a3.bit();
+ RegList registers_to_retain = {s0, s1, s2, s3, s4, s5, s6, s7, fp};
+ RegList argument_registers = {a0, a1, a2, a3};
- argument_registers |= a4.bit() | a5.bit() | a6.bit() | a7.bit();
+ argument_registers |= {a4, a5, a6, a7};
- __ MultiPush(argument_registers | registers_to_retain | ra.bit());
+ __ MultiPush(argument_registers | registers_to_retain | ra);
// Set frame pointer in space for it if this is not a direct call
// from generated code.
// TODO(plind): this 8 is the # of argument regs, should have definition.
@@ -942,7 +941,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// Skip sp past regexp registers and local variables..
__ mov(sp, frame_pointer());
// Restore registers s0..s7 and return (restoring ra to pc).
- __ MultiPop(registers_to_retain | ra.bit());
+ __ MultiPop(registers_to_retain | ra);
__ Ret();
// Backtrack code (branch target for conditional backtracks).
diff --git a/deps/v8/src/regexp/ppc/regexp-macro-assembler-ppc.cc b/deps/v8/src/regexp/ppc/regexp-macro-assembler-ppc.cc
index fda0060e47..fb9425f008 100644
--- a/deps/v8/src/regexp/ppc/regexp-macro-assembler-ppc.cc
+++ b/deps/v8/src/regexp/ppc/regexp-macro-assembler-ppc.cc
@@ -737,13 +737,13 @@ Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) {
FrameScope scope(masm_.get(), StackFrame::MANUAL);
// Ensure register assigments are consistent with callee save mask
- DCHECK(r25.bit() & kRegExpCalleeSaved);
- DCHECK(code_pointer().bit() & kRegExpCalleeSaved);
- DCHECK(current_input_offset().bit() & kRegExpCalleeSaved);
- DCHECK(current_character().bit() & kRegExpCalleeSaved);
- DCHECK(backtrack_stackpointer().bit() & kRegExpCalleeSaved);
- DCHECK(end_of_input_address().bit() & kRegExpCalleeSaved);
- DCHECK(frame_pointer().bit() & kRegExpCalleeSaved);
+ DCHECK(kRegExpCalleeSaved.has(r25));
+ DCHECK(kRegExpCalleeSaved.has(code_pointer()));
+ DCHECK(kRegExpCalleeSaved.has(current_input_offset()));
+ DCHECK(kRegExpCalleeSaved.has(current_character()));
+ DCHECK(kRegExpCalleeSaved.has(backtrack_stackpointer()));
+ DCHECK(kRegExpCalleeSaved.has(end_of_input_address()));
+ DCHECK(kRegExpCalleeSaved.has(frame_pointer()));
// Actually emit code to start a new stack frame.
// Push arguments
@@ -752,8 +752,7 @@ Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) {
// Store link register in existing stack-cell.
// Order here should correspond to order of offset constants in header file.
RegList registers_to_retain = kRegExpCalleeSaved;
- RegList argument_registers = r3.bit() | r4.bit() | r5.bit() | r6.bit() |
- r7.bit() | r8.bit() | r9.bit() | r10.bit();
+ RegList argument_registers = {r3, r4, r5, r6, r7, r8, r9, r10};
__ mflr(r0);
__ push(r0);
__ MultiPush(argument_registers | registers_to_retain);
diff --git a/deps/v8/src/regexp/ppc/regexp-macro-assembler-ppc.h b/deps/v8/src/regexp/ppc/regexp-macro-assembler-ppc.h
index b1ed035134..5760809d96 100644
--- a/deps/v8/src/regexp/ppc/regexp-macro-assembler-ppc.h
+++ b/deps/v8/src/regexp/ppc/regexp-macro-assembler-ppc.h
@@ -215,8 +215,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerPPC
};
// Set of non-volatile registers saved/restored by generated regexp code.
-const RegList kRegExpCalleeSaved =
- 1 << 25 | 1 << 26 | 1 << 27 | 1 << 28 | 1 << 29 | 1 << 30 | 1 << 31;
+const RegList kRegExpCalleeSaved = {r25, r26, r27, r28, r29, r30, fp};
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/regexp/regexp-compiler-tonode.cc b/deps/v8/src/regexp/regexp-compiler-tonode.cc
index d8c0d24732..4cb9e8e689 100644
--- a/deps/v8/src/regexp/regexp-compiler-tonode.cc
+++ b/deps/v8/src/regexp/regexp-compiler-tonode.cc
@@ -519,12 +519,29 @@ int CompareFirstChar(RegExpTree* const* a, RegExpTree* const* b) {
#ifdef V8_INTL_SUPPORT
-// Case Insensitve comparesion
-int CompareFirstCharCaseInsensitve(RegExpTree* const* a, RegExpTree* const* b) {
+int CompareCaseInsensitive(const icu::UnicodeString& a,
+ const icu::UnicodeString& b) {
+ return a.caseCompare(b, U_FOLD_CASE_DEFAULT);
+}
+
+int CompareFirstCharCaseInsensitive(RegExpTree* const* a,
+ RegExpTree* const* b) {
RegExpAtom* atom1 = (*a)->AsAtom();
RegExpAtom* atom2 = (*b)->AsAtom();
- icu::UnicodeString character1(atom1->data().at(0));
- return character1.caseCompare(atom2->data().at(0), U_FOLD_CASE_DEFAULT);
+ return CompareCaseInsensitive(icu::UnicodeString{atom1->data().at(0)},
+ icu::UnicodeString{atom2->data().at(0)});
+}
+
+bool Equals(bool ignore_case, const icu::UnicodeString& a,
+ const icu::UnicodeString& b) {
+ if (a == b) return true;
+ if (ignore_case) return CompareCaseInsensitive(a, b) == 0;
+ return false; // Case-sensitive equality already checked above.
+}
+
+bool CharAtEquals(bool ignore_case, int index, const RegExpAtom* a,
+ const RegExpAtom* b) {
+ return Equals(ignore_case, a->data().at(index), b->data().at(index));
}
#else
@@ -540,20 +557,43 @@ unibrow::uchar Canonical(
return canonical;
}
-int CompareFirstCharCaseIndependent(
+int CompareCaseInsensitive(
+ unibrow::Mapping<unibrow::Ecma262Canonicalize>* canonicalize,
+ unibrow::uchar a, unibrow::uchar b) {
+ if (a == b) return 0;
+ if (a >= 'a' || b >= 'a') {
+ a = Canonical(canonicalize, a);
+ b = Canonical(canonicalize, b);
+ }
+ return static_cast<int>(a) - static_cast<int>(b);
+}
+
+int CompareFirstCharCaseInsensitive(
unibrow::Mapping<unibrow::Ecma262Canonicalize>* canonicalize,
RegExpTree* const* a, RegExpTree* const* b) {
RegExpAtom* atom1 = (*a)->AsAtom();
RegExpAtom* atom2 = (*b)->AsAtom();
- unibrow::uchar character1 = atom1->data().at(0);
- unibrow::uchar character2 = atom2->data().at(0);
- if (character1 == character2) return 0;
- if (character1 >= 'a' || character2 >= 'a') {
- character1 = Canonical(canonicalize, character1);
- character2 = Canonical(canonicalize, character2);
- }
- return static_cast<int>(character1) - static_cast<int>(character2);
+ return CompareCaseInsensitive(canonicalize, atom1->data().at(0),
+ atom2->data().at(0));
+}
+
+bool Equals(bool ignore_case,
+ unibrow::Mapping<unibrow::Ecma262Canonicalize>* canonicalize,
+ unibrow::uchar a, unibrow::uchar b) {
+ if (a == b) return true;
+ if (ignore_case) {
+ return CompareCaseInsensitive(canonicalize, a, b) == 0;
+ }
+ return false; // Case-sensitive equality already checked above.
+}
+
+bool CharAtEquals(bool ignore_case,
+ unibrow::Mapping<unibrow::Ecma262Canonicalize>* canonicalize,
+ int index, const RegExpAtom* a, const RegExpAtom* b) {
+ return Equals(ignore_case, canonicalize, a->data().at(index),
+ b->data().at(index));
}
+
#endif // V8_INTL_SUPPORT
} // namespace
@@ -591,14 +631,14 @@ bool RegExpDisjunction::SortConsecutiveAtoms(RegExpCompiler* compiler) {
DCHECK_LE(first_atom, i);
if (IsIgnoreCase(compiler->flags())) {
#ifdef V8_INTL_SUPPORT
- alternatives->StableSort(CompareFirstCharCaseInsensitve, first_atom,
+ alternatives->StableSort(CompareFirstCharCaseInsensitive, first_atom,
i - first_atom);
#else
unibrow::Mapping<unibrow::Ecma262Canonicalize>* canonicalize =
compiler->isolate()->regexp_macro_assembler_canonicalize();
auto compare_closure = [canonicalize](RegExpTree* const* a,
RegExpTree* const* b) {
- return CompareFirstCharCaseIndependent(canonicalize, a, b);
+ return CompareFirstCharCaseInsensitive(canonicalize, a, b);
};
alternatives->StableSort(compare_closure, first_atom, i - first_atom);
#endif // V8_INTL_SUPPORT
@@ -615,6 +655,7 @@ void RegExpDisjunction::RationalizeConsecutiveAtoms(RegExpCompiler* compiler) {
Zone* zone = compiler->zone();
ZoneList<RegExpTree*>* alternatives = this->alternatives();
int length = alternatives->length();
+ const bool ignore_case = IsIgnoreCase(compiler->flags());
int write_posn = 0;
int i = 0;
@@ -629,7 +670,12 @@ void RegExpDisjunction::RationalizeConsecutiveAtoms(RegExpCompiler* compiler) {
#ifdef V8_INTL_SUPPORT
icu::UnicodeString common_prefix(atom->data().at(0));
#else
+ unibrow::Mapping<unibrow::Ecma262Canonicalize>* const canonicalize =
+ compiler->isolate()->regexp_macro_assembler_canonicalize();
unibrow::uchar common_prefix = atom->data().at(0);
+ if (ignore_case) {
+ common_prefix = Canonical(canonicalize, common_prefix);
+ }
#endif // V8_INTL_SUPPORT
int first_with_prefix = i;
int prefix_length = atom->length();
@@ -640,21 +686,10 @@ void RegExpDisjunction::RationalizeConsecutiveAtoms(RegExpCompiler* compiler) {
RegExpAtom* const alt_atom = alternative->AsAtom();
#ifdef V8_INTL_SUPPORT
icu::UnicodeString new_prefix(alt_atom->data().at(0));
- if (new_prefix != common_prefix) {
- if (!IsIgnoreCase(compiler->flags())) break;
- if (common_prefix.caseCompare(new_prefix, U_FOLD_CASE_DEFAULT) != 0)
- break;
- }
+ if (!Equals(ignore_case, new_prefix, common_prefix)) break;
#else
unibrow::uchar new_prefix = alt_atom->data().at(0);
- if (new_prefix != common_prefix) {
- if (!IsIgnoreCase(compiler->flags())) break;
- unibrow::Mapping<unibrow::Ecma262Canonicalize>* canonicalize =
- compiler->isolate()->regexp_macro_assembler_canonicalize();
- new_prefix = Canonical(canonicalize, new_prefix);
- common_prefix = Canonical(canonicalize, common_prefix);
- if (new_prefix != common_prefix) break;
- }
+ if (!Equals(ignore_case, canonicalize, new_prefix, common_prefix)) break;
#endif // V8_INTL_SUPPORT
prefix_length = std::min(prefix_length, alt_atom->length());
i++;
@@ -672,7 +707,11 @@ void RegExpDisjunction::RationalizeConsecutiveAtoms(RegExpCompiler* compiler) {
RegExpAtom* old_atom =
alternatives->at(j + first_with_prefix)->AsAtom();
for (int k = 1; k < prefix_length; k++) {
- if (alt_atom->data().at(k) != old_atom->data().at(k)) {
+#ifdef V8_INTL_SUPPORT
+ if (!CharAtEquals(ignore_case, k, alt_atom, old_atom)) {
+#else
+ if (!CharAtEquals(ignore_case, canonicalize, k, alt_atom, old_atom)) {
+#endif // V8_INTL_SUPPORT
prefix_length = k;
break;
}
@@ -778,6 +817,8 @@ void RegExpDisjunction::FixSingleCharacterDisjunctions(
RegExpNode* RegExpDisjunction::ToNode(RegExpCompiler* compiler,
RegExpNode* on_success) {
+ compiler->ToNodeMaybeCheckForStackOverflow();
+
ZoneList<RegExpTree*>* alternatives = this->alternatives();
if (alternatives->length() > 2) {
@@ -1089,6 +1130,8 @@ class AssertionSequenceRewriter final {
RegExpNode* RegExpAlternative::ToNode(RegExpCompiler* compiler,
RegExpNode* on_success) {
+ compiler->ToNodeMaybeCheckForStackOverflow();
+
ZoneList<RegExpTree*>* children = nodes();
AssertionSequenceRewriter::MaybeRewrite(children, compiler->zone());
diff --git a/deps/v8/src/regexp/regexp-compiler.cc b/deps/v8/src/regexp/regexp-compiler.cc
index c3ecff9d43..df15764dff 100644
--- a/deps/v8/src/regexp/regexp-compiler.cc
+++ b/deps/v8/src/regexp/regexp-compiler.cc
@@ -3950,5 +3950,11 @@ RegExpNode* RegExpCompiler::PreprocessRegExp(RegExpCompileData* data,
return node;
}
+void RegExpCompiler::ToNodeCheckForStackOverflow() {
+ if (StackLimitCheck{isolate()}.HasOverflowed()) {
+ FatalProcessOutOfMemory(isolate(), "RegExpCompiler");
+ }
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/regexp/regexp-compiler.h b/deps/v8/src/regexp/regexp-compiler.h
index 832a966217..421fc9457c 100644
--- a/deps/v8/src/regexp/regexp-compiler.h
+++ b/deps/v8/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/deps/v8/src/regexp/regexp-interpreter.cc b/deps/v8/src/regexp/regexp-interpreter.cc
index e1549f95be..bf7769b86e 100644
--- a/deps/v8/src/regexp/regexp-interpreter.cc
+++ b/deps/v8/src/regexp/regexp-interpreter.cc
@@ -1088,6 +1088,10 @@ IrregexpInterpreter::Result IrregexpInterpreter::MatchInternal(
base::uc16 previous_char = '\n';
String::FlatContent subject_content = subject_string.GetFlatContent(no_gc);
+ // Because interrupts can result in GC and string content relocation, the
+ // checksum verification in FlatContent may fail even though this code is
+ // safe. See (2) above.
+ subject_content.UnsafeDisableChecksumVerification();
if (subject_content.IsOneByte()) {
base::Vector<const uint8_t> subject_vector =
subject_content.ToOneByteVector();
diff --git a/deps/v8/src/regexp/regexp-parser.cc b/deps/v8/src/regexp/regexp-parser.cc
index 675df8de58..5d71527eba 100644
--- a/deps/v8/src/regexp/regexp-parser.cc
+++ b/deps/v8/src/regexp/regexp-parser.cc
@@ -428,11 +428,6 @@ void RegExpParserImpl<CharT>::Advance() {
FATAL("Aborting on stack overflow");
}
ReportError(RegExpError::kStackOverflow);
- } else if (zone()->excess_allocation()) {
- if (FLAG_correctness_fuzzer_suppressions) {
- FATAL("Aborting on excess zone allocation");
- }
- ReportError(RegExpError::kTooLarge);
} else {
current_ = ReadNext<true>();
}
diff --git a/deps/v8/src/regexp/regexp-utils.cc b/deps/v8/src/regexp/regexp-utils.cc
index dabe5ee4a2..b26007191d 100644
--- a/deps/v8/src/regexp/regexp-utils.cc
+++ b/deps/v8/src/regexp/regexp-utils.cc
@@ -49,7 +49,8 @@ MaybeHandle<Object> RegExpUtils::SetLastIndex(Isolate* isolate,
Handle<Object> value_as_object =
isolate->factory()->NewNumberFromInt64(value);
if (HasInitialRegExpMap(isolate, *recv)) {
- JSRegExp::cast(*recv).set_last_index(*value_as_object, SKIP_WRITE_BARRIER);
+ JSRegExp::cast(*recv).set_last_index(*value_as_object,
+ UPDATE_WRITE_BARRIER);
return recv;
} else {
return Object::SetProperty(
diff --git a/deps/v8/src/regexp/regexp.cc b/deps/v8/src/regexp/regexp.cc
index c1b8fc4fd9..df50034b16 100644
--- a/deps/v8/src/regexp/regexp.cc
+++ b/deps/v8/src/regexp/regexp.cc
@@ -569,7 +569,6 @@ bool RegExpImpl::CompileIrregexp(Isolate* isolate, Handle<JSRegExp> re,
Handle<FixedArray> data =
Handle<FixedArray>(FixedArray::cast(re->data()), isolate);
if (compile_data.compilation_target == RegExpCompilationTarget::kNative) {
- // TODO(ishell): avoid roundtrips between cdc and code.
Code code = Code::cast(*compile_data.code);
data->set(JSRegExp::code_index(is_one_byte), ToCodeT(code));
@@ -583,9 +582,9 @@ bool RegExpImpl::CompileIrregexp(Isolate* isolate, Handle<JSRegExp> re,
// Store code generated by compiler in bytecode and trampoline to
// interpreter in code.
data->set(JSRegExp::bytecode_index(is_one_byte), *compile_data.code);
- Handle<Code> trampoline =
+ Handle<CodeT> trampoline =
BUILTIN_CODE(isolate, RegExpInterpreterTrampoline);
- data->set(JSRegExp::code_index(is_one_byte), ToCodeT(*trampoline));
+ data->set(JSRegExp::code_index(is_one_byte), *trampoline);
}
Handle<FixedArray> capture_name_map =
RegExp::CreateCaptureNameMap(isolate, compile_data.named_captures);
diff --git a/deps/v8/src/regexp/riscv64/regexp-macro-assembler-riscv64.cc b/deps/v8/src/regexp/riscv64/regexp-macro-assembler-riscv64.cc
index 74fb625e61..8f6b5e278d 100644
--- a/deps/v8/src/regexp/riscv64/regexp-macro-assembler-riscv64.cc
+++ b/deps/v8/src/regexp/riscv64/regexp-macro-assembler-riscv64.cc
@@ -221,16 +221,16 @@ void RegExpMacroAssemblerRISCV::CheckGreedyLoop(Label* on_equal) {
// Push (pop) caller-saved registers used by irregexp.
void RegExpMacroAssemblerRISCV::PushCallerSavedRegisters() {
- RegList caller_saved_regexp =
- current_input_offset().bit() | current_character().bit() |
- end_of_input_address().bit() | backtrack_stackpointer().bit();
+ RegList caller_saved_regexp = {current_input_offset(), current_character(),
+ end_of_input_address(),
+ backtrack_stackpointer()};
__ MultiPush(caller_saved_regexp);
}
void RegExpMacroAssemblerRISCV::PopCallerSavedRegisters() {
- RegList caller_saved_regexp =
- current_input_offset().bit() | current_character().bit() |
- end_of_input_address().bit() | backtrack_stackpointer().bit();
+ RegList caller_saved_regexp = {current_input_offset(), current_character(),
+ end_of_input_address(),
+ backtrack_stackpointer()};
__ MultiPop(caller_saved_regexp);
}
@@ -696,10 +696,9 @@ Handle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(Handle<String> source) {
// Order here should correspond to order of offset constants in header file.
// TODO(plind): we save fp..s11, but ONLY use s3 here - use the regs
// or dont save.
- RegList registers_to_retain =
- fp.bit() | s1.bit() | s2.bit() | s3.bit() | s4.bit() | s5.bit() |
- s6.bit() | s7.bit() | s8.bit() /*| s9.bit() | s10.bit() | s11.bit()*/;
- DCHECK(NumRegs(registers_to_retain) == kNumCalleeRegsToRetain);
+ RegList registers_to_retain = {fp, s1, s2, s3, s4,
+ s5, s6, s7, s8 /*, s9, s10, s11*/};
+ DCHECK(registers_to_retain.Count() == kNumCalleeRegsToRetain);
// The remaining arguments are passed in registers, e.g.by calling the code
// entry as cast to a function with the signature:
@@ -713,17 +712,16 @@ Handle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(Handle<String> source) {
// int call_origin, // a6
// Isolate* isolate, // a7
// Address regexp); // on the stack
- RegList argument_registers = a0.bit() | a1.bit() | a2.bit() | a3.bit() |
- a4.bit() | a5.bit() | a6.bit() | a7.bit();
+ RegList argument_registers = {a0, a1, a2, a3, a4, a5, a6, a7};
// According to MultiPush implementation, registers will be pushed in the
// order of ra, fp, then s8, ..., s1, and finally a7,...a0
- __ MultiPush(ra.bit() | registers_to_retain | argument_registers);
+ __ MultiPush(RegList{ra} | registers_to_retain | argument_registers);
// Set frame pointer in space for it if this is not a direct call
// from generated code.
__ Add64(frame_pointer(), sp,
- Operand(NumRegs(argument_registers) * kSystemPointerSize));
+ Operand(argument_registers.Count() * kSystemPointerSize));
STATIC_ASSERT(kSuccessfulCaptures == kInputString - kSystemPointerSize);
__ mv(a0, zero_reg);
@@ -844,8 +842,8 @@ Handle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(Handle<String> source) {
DCHECK_EQ(0, num_saved_registers_ % 2);
// Always an even number of capture registers. This allows us to
- // unroll the loop once to add an operation between a load of a register
- // and the following use of that register.
+ // unroll the loop once to add an operation between a load of a
+ // register and the following use of that register.
for (int i = 0; i < num_saved_registers_; i += 2) {
__ Ld(a2, register_location(i));
__ Ld(a3, register_location(i + 1));
@@ -928,7 +926,7 @@ Handle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(Handle<String> source) {
__ mv(sp, frame_pointer());
// Restore registers fp..s11 and return (restoring ra to pc).
- __ MultiPop(registers_to_retain | ra.bit());
+ __ MultiPop(registers_to_retain | ra);
__ Ret();
@@ -1144,9 +1142,9 @@ void RegExpMacroAssemblerRISCV::ClearRegisters(int reg_from, int reg_to) {
__ Sd(a0, register_location(reg));
}
}
-
+#ifdef RISCV_HAS_NO_UNALIGNED
bool RegExpMacroAssemblerRISCV::CanReadUnaligned() const { return false; }
-
+#endif
// Private methods:
void RegExpMacroAssemblerRISCV::CallCheckStackGuardState(Register scratch) {
@@ -1328,20 +1326,40 @@ void RegExpMacroAssemblerRISCV::CheckStackLimit() {
void RegExpMacroAssemblerRISCV::LoadCurrentCharacterUnchecked(int cp_offset,
int characters) {
Register offset = current_input_offset();
+
+ // If unaligned load/stores are not supported then this function must only
+ // be used to load a single character at a time.
+ if (!CanReadUnaligned()) {
+ DCHECK_EQ(1, characters);
+ }
if (cp_offset != 0) {
- // s3 is not being used to store the capture start index at this point.
- __ Add64(s3, current_input_offset(), Operand(cp_offset * char_size()));
- offset = s3;
+ // t3 is not being used to store the capture start index at this point.
+ __ Add64(t3, current_input_offset(), Operand(cp_offset * char_size()));
+ offset = t3;
}
- // We assume that we cannot do unaligned loads on RISC-V, so this function
- // must only be used to load a single character at a time.
- DCHECK_EQ(1, characters);
- __ Add64(t1, end_of_input_address(), Operand(offset));
+
if (mode_ == LATIN1) {
- __ Lbu(current_character(), MemOperand(t1, 0));
+ if (characters == 4) {
+ __ Add64(kScratchReg, end_of_input_address(), offset);
+ __ Lwu(current_character(), MemOperand(kScratchReg));
+ } else if (characters == 2) {
+ __ Add64(kScratchReg, end_of_input_address(), offset);
+ __ Lhu(current_character(), MemOperand(kScratchReg));
+ } else {
+ DCHECK_EQ(1, characters);
+ __ Add64(kScratchReg, end_of_input_address(), offset);
+ __ Lbu(current_character(), MemOperand(kScratchReg));
+ }
} else {
DCHECK(mode_ == UC16);
- __ Lhu(current_character(), MemOperand(t1, 0));
+ if (characters == 2) {
+ __ Add64(kScratchReg, end_of_input_address(), offset);
+ __ Lwu(current_character(), MemOperand(kScratchReg));
+ } else {
+ DCHECK_EQ(1, characters);
+ __ Add64(kScratchReg, end_of_input_address(), offset);
+ __ Lhu(current_character(), MemOperand(kScratchReg));
+ }
}
}
diff --git a/deps/v8/src/regexp/riscv64/regexp-macro-assembler-riscv64.h b/deps/v8/src/regexp/riscv64/regexp-macro-assembler-riscv64.h
index 121569849a..7613b47b3e 100644
--- a/deps/v8/src/regexp/riscv64/regexp-macro-assembler-riscv64.h
+++ b/deps/v8/src/regexp/riscv64/regexp-macro-assembler-riscv64.h
@@ -83,8 +83,9 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerRISCV
void WriteCurrentPositionToRegister(int reg, int cp_offset) override;
void ClearRegisters(int reg_from, int reg_to) override;
void WriteStackPointerToRegister(int reg) override;
+#ifdef RISCV_HAS_NO_UNALIGNED
bool CanReadUnaligned() const override;
-
+#endif
// Called from RegExp if the stack-guard is triggered.
// If the code object is relocated, the return address is fixed before
// returning.
diff --git a/deps/v8/src/regexp/s390/regexp-macro-assembler-s390.cc b/deps/v8/src/regexp/s390/regexp-macro-assembler-s390.cc
index 3b80858f0e..bf22b69222 100644
--- a/deps/v8/src/regexp/s390/regexp-macro-assembler-s390.cc
+++ b/deps/v8/src/regexp/s390/regexp-macro-assembler-s390.cc
@@ -708,13 +708,13 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) {
FrameScope scope(masm_.get(), StackFrame::MANUAL);
// Ensure register assigments are consistent with callee save mask
- DCHECK(r6.bit() & kRegExpCalleeSaved);
- DCHECK(code_pointer().bit() & kRegExpCalleeSaved);
- DCHECK(current_input_offset().bit() & kRegExpCalleeSaved);
- DCHECK(current_character().bit() & kRegExpCalleeSaved);
- DCHECK(backtrack_stackpointer().bit() & kRegExpCalleeSaved);
- DCHECK(end_of_input_address().bit() & kRegExpCalleeSaved);
- DCHECK(frame_pointer().bit() & kRegExpCalleeSaved);
+ DCHECK(kRegExpCalleeSaved.has(r6));
+ DCHECK(kRegExpCalleeSaved.has(code_pointer()));
+ DCHECK(kRegExpCalleeSaved.has(current_input_offset()));
+ DCHECK(kRegExpCalleeSaved.has(current_character()));
+ DCHECK(kRegExpCalleeSaved.has(backtrack_stackpointer()));
+ DCHECK(kRegExpCalleeSaved.has(end_of_input_address()));
+ DCHECK(kRegExpCalleeSaved.has(frame_pointer()));
// zLinux ABI
// Incoming parameters:
diff --git a/deps/v8/src/regexp/s390/regexp-macro-assembler-s390.h b/deps/v8/src/regexp/s390/regexp-macro-assembler-s390.h
index bb9ac110f7..645b01faa5 100644
--- a/deps/v8/src/regexp/s390/regexp-macro-assembler-s390.h
+++ b/deps/v8/src/regexp/s390/regexp-macro-assembler-s390.h
@@ -215,8 +215,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerS390
};
// Set of non-volatile registers saved/restored by generated regexp code.
-const RegList kRegExpCalleeSaved =
- 1 << 6 | 1 << 7 | 1 << 8 | 1 << 9 | 1 << 10 | 1 << 11 | 1 << 13;
+const RegList kRegExpCalleeSaved = {r6, r7, r8, r9, r10, fp, r13};
} // namespace internal
} // namespace v8