diff options
Diffstat (limited to 'deps/v8/src/regexp')
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 |