summaryrefslogtreecommitdiff
path: root/deps/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc')
-rw-r--r--deps/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc135
1 files changed, 78 insertions, 57 deletions
diff --git a/deps/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc b/deps/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc
index 2e462ba748..fe1b0f6e04 100644
--- a/deps/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc
+++ b/deps/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc
@@ -22,7 +22,7 @@ namespace internal {
* This assembler uses the following register assignment convention:
* - w19 : Used to temporarely store a value before a call to C code.
* See CheckNotBackReferenceIgnoreCase.
- * - x20 : Pointer to the current Code object,
+ * - x20 : Pointer to the current InstructionStream object,
* it includes the heap object tag.
* - w21 : Current position in input, as negative offset from
* the end of the string. Please notice that this is
@@ -64,14 +64,16 @@ namespace internal {
* - fp[8] lr Return from the RegExp code.
* - fp[0] fp Old frame pointer.
* ^^^^^^^^^ fp ^^^^^^^^^
- * - fp[-8] direct_call 1 => Direct call from JavaScript code.
+ * - fp[-8] frame marker
+ * - fp[-16] isolate
+ * - fp[-24] direct_call 1 => Direct call from JavaScript code.
* 0 => Call through the runtime system.
- * - fp[-16] output_size Output may fit multiple sets of matches.
- * - fp[-24] input Handle containing the input string.
- * - fp[-32] success_counter
+ * - fp[-32] output_size Output may fit multiple sets of matches.
+ * - fp[-40] input Handle containing the input string.
+ * - fp[-48] success_counter
* ^^^^^^^^^^^^^ From here and downwards we store 32 bit values ^^^^^^^^^^^^^
- * - fp[-40] register N Capture registers initialized with
- * - fp[-44] register N + 1 non_position_value.
+ * - fp[-56] register N Capture registers initialized with
+ * - fp[-60] register N + 1 non_position_value.
* ... The first kNumCachedRegisters (N) registers
* ... are cached in x0 to x7.
* ... Only positions must be stored in the first
@@ -102,15 +104,13 @@ namespace internal {
#define __ ACCESS_MASM(masm_)
-const int RegExpMacroAssemblerARM64::kRegExpCodeSize;
-
RegExpMacroAssemblerARM64::RegExpMacroAssemblerARM64(Isolate* isolate,
Zone* zone, Mode mode,
int registers_to_save)
: NativeRegExpMacroAssembler(isolate, zone),
masm_(std::make_unique<MacroAssembler>(
isolate, CodeObjectRequired::kYes,
- NewAssemblerBuffer(kRegExpCodeSize))),
+ NewAssemblerBuffer(kInitialBufferSize))),
no_root_array_scope_(masm_.get()),
mode_(mode),
num_registers_(registers_to_save),
@@ -194,9 +194,9 @@ void RegExpMacroAssemblerARM64::Backtrack() {
Label next;
UseScratchRegisterScope temps(masm_.get());
Register scratch = temps.AcquireW();
- __ Ldr(scratch, MemOperand(frame_pointer(), kBacktrackCount));
+ __ Ldr(scratch, MemOperand(frame_pointer(), kBacktrackCountOffset));
__ Add(scratch, scratch, 1);
- __ Str(scratch, MemOperand(frame_pointer(), kBacktrackCount));
+ __ Str(scratch, MemOperand(frame_pointer(), kBacktrackCountOffset));
__ Cmp(scratch, Operand(backtrack_limit()));
__ B(ne, &next);
@@ -437,7 +437,7 @@ void RegExpMacroAssemblerARM64::CheckNotBackReferenceIgnoreCase(
unicode
? ExternalReference::re_case_insensitive_compare_unicode()
: ExternalReference::re_case_insensitive_compare_non_unicode();
- __ CallCFunction(function, argument_count);
+ CallCFunctionFromIrregexpCode(function, argument_count);
}
// Check if function returned non-zero for success or zero for failure.
@@ -593,8 +593,8 @@ void RegExpMacroAssemblerARM64::CallIsCharacterInRangeArray(
{
// We have a frame (set up in GetCode), but the assembler doesn't know.
FrameScope scope(masm_.get(), StackFrame::MANUAL);
- __ CallCFunction(ExternalReference::re_is_character_in_range_array(),
- kNumArguments);
+ CallCFunctionFromIrregexpCode(
+ ExternalReference::re_is_character_in_range_array(), kNumArguments);
}
__ Mov(code_pointer(), Operand(masm_->CodeObject()));
@@ -768,7 +768,7 @@ void RegExpMacroAssemblerARM64::PushRegExpBasePointer(Register stack_pointer,
__ Mov(scratch, ref);
__ Ldr(scratch, MemOperand(scratch));
__ Sub(scratch, stack_pointer, scratch);
- __ Str(scratch, MemOperand(frame_pointer(), kRegExpStackBasePointer));
+ __ Str(scratch, MemOperand(frame_pointer(), kRegExpStackBasePointerOffset));
}
void RegExpMacroAssemblerARM64::PopRegExpBasePointer(Register stack_pointer_out,
@@ -776,7 +776,7 @@ void RegExpMacroAssemblerARM64::PopRegExpBasePointer(Register stack_pointer_out,
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ Ldr(stack_pointer_out,
- MemOperand(frame_pointer(), kRegExpStackBasePointer));
+ MemOperand(frame_pointer(), kRegExpStackBasePointerOffset));
__ Mov(scratch, ref);
__ Ldr(scratch, MemOperand(scratch));
__ Add(stack_pointer_out, stack_pointer_out, scratch);
@@ -807,18 +807,22 @@ Handle<HeapObject> RegExpMacroAssemblerARM64::GetCode(Handle<String> source) {
// code is generated.
FrameScope scope(masm_.get(), StackFrame::MANUAL);
- // Push registers on the stack, only push the argument registers that we need.
- CPURegList argument_registers(x0, x5, x6, x7);
-
- CPURegList registers_to_retain = kCalleeSaved;
+ // Stack frame setup.
+ // Push callee-saved registers.
+ const CPURegList registers_to_retain = kCalleeSaved;
DCHECK_EQ(registers_to_retain.Count(), kNumCalleeSavedRegisters);
-
__ PushCPURegList(registers_to_retain);
- __ Push<TurboAssembler::kSignLR>(lr, fp);
- __ PushCPURegList(argument_registers);
-
- // Set frame pointer in place.
- __ Add(frame_pointer(), sp, argument_registers.Count() * kSystemPointerSize);
+ static_assert(kFrameTypeOffset == kFramePointerOffset - kSystemPointerSize);
+ __ EnterFrame(StackFrame::IRREGEXP);
+ // Only push the argument registers that we need.
+ static_assert(kIsolateOffset ==
+ kFrameTypeOffset - kPaddingAfterFrameType - kSystemPointerSize);
+ static_assert(kDirectCallOffset == kIsolateOffset - kSystemPointerSize);
+ static_assert(kNumOutputRegistersOffset ==
+ kDirectCallOffset - kSystemPointerSize);
+ static_assert(kInputStringOffset ==
+ kNumOutputRegistersOffset - kSystemPointerSize);
+ __ PushCPURegList(CPURegList{x0, x5, x6, x7});
// Initialize callee-saved registers.
__ Mov(start_offset(), w1);
@@ -887,9 +891,9 @@ Handle<HeapObject> RegExpMacroAssemblerARM64::GetCode(Handle<String> source) {
// Allocate space on stack.
__ Claim(num_wreg_to_allocate, kWRegSize);
- // Initialize success_counter and kBacktrackCount with 0.
- __ Str(wzr, MemOperand(frame_pointer(), kSuccessCounter));
- __ Str(wzr, MemOperand(frame_pointer(), kBacktrackCount));
+ // Initialize success_counter and kBacktrackCountOffset with 0.
+ __ Str(wzr, MemOperand(frame_pointer(), kSuccessfulCapturesOffset));
+ __ Str(wzr, MemOperand(frame_pointer(), kBacktrackCountOffset));
// Find negative length (offset of start relative to end).
__ Sub(x10, input_start(), input_end());
@@ -1004,7 +1008,7 @@ Handle<HeapObject> RegExpMacroAssemblerARM64::GetCode(Handle<String> source) {
// There are always an even number of capture registers. A couple of
// registers determine one match with two offsets.
DCHECK_EQ(0, num_registers_left_on_stack % 2);
- __ Add(base, frame_pointer(), kFirstCaptureOnStack);
+ __ Add(base, frame_pointer(), kFirstCaptureOnStackOffset);
// We can unroll the loop here, we should not unroll for less than 2
// registers.
@@ -1068,13 +1072,16 @@ Handle<HeapObject> RegExpMacroAssemblerARM64::GetCode(Handle<String> source) {
// Restart matching if the regular expression is flagged as global.
// Increment success counter.
- __ Ldr(success_counter, MemOperand(frame_pointer(), kSuccessCounter));
+ __ Ldr(success_counter,
+ MemOperand(frame_pointer(), kSuccessfulCapturesOffset));
__ Add(success_counter, success_counter, 1);
- __ Str(success_counter, MemOperand(frame_pointer(), kSuccessCounter));
+ __ Str(success_counter,
+ MemOperand(frame_pointer(), kSuccessfulCapturesOffset));
// Capture results have been stored, so the number of remaining global
// output registers is reduced by the number of stored captures.
- __ Ldr(output_size, MemOperand(frame_pointer(), kOutputSize));
+ __ Ldr(output_size,
+ MemOperand(frame_pointer(), kNumOutputRegistersOffset));
__ Sub(output_size, output_size, num_saved_registers_);
// Check whether we have enough room for another set of capture results.
__ Cmp(output_size, num_saved_registers_);
@@ -1083,7 +1090,8 @@ Handle<HeapObject> RegExpMacroAssemblerARM64::GetCode(Handle<String> source) {
// The output pointer is already set to the next field in the output
// array.
// Update output size on the frame before we restart matching.
- __ Str(output_size, MemOperand(frame_pointer(), kOutputSize));
+ __ Str(output_size,
+ MemOperand(frame_pointer(), kNumOutputRegistersOffset));
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
@@ -1114,7 +1122,7 @@ Handle<HeapObject> RegExpMacroAssemblerARM64::GetCode(Handle<String> source) {
// Exit and return w0.
__ Bind(&exit_label_);
if (global()) {
- __ Ldr(w0, MemOperand(frame_pointer(), kSuccessCounter));
+ __ Ldr(w0, MemOperand(frame_pointer(), kSuccessfulCapturesOffset));
}
}
@@ -1123,13 +1131,8 @@ Handle<HeapObject> RegExpMacroAssemblerARM64::GetCode(Handle<String> source) {
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), x11);
- // Set stack pointer back to first register to retain.
- __ Mov(sp, fp);
- __ Pop<TurboAssembler::kAuthLR>(fp, lr);
-
- // Restore registers.
+ __ LeaveFrame(StackFrame::IRREGEXP);
__ PopCPURegList(registers_to_retain);
-
__ Ret();
Label exit_with_exception;
@@ -1163,7 +1166,8 @@ Handle<HeapObject> RegExpMacroAssemblerARM64::GetCode(Handle<String> source) {
// Call GrowStack(isolate).
static constexpr int kNumArguments = 1;
__ Mov(x0, ExternalReference::isolate_address(isolate()));
- __ CallCFunction(ExternalReference::re_grow_stack(), kNumArguments);
+ CallCFunctionFromIrregexpCode(ExternalReference::re_grow_stack(),
+ kNumArguments);
// If return nullptr, we have failed to grow the stack, and must exit with
// a stack-overflow exception. Returning from the regexp code restores the
// stack (sp <- fp) so we don't need to drop the link register from it
@@ -1244,7 +1248,7 @@ void RegExpMacroAssemblerARM64::PopRegister(int register_index) {
void RegExpMacroAssemblerARM64::PushBacktrack(Label* label) {
if (label->is_bound()) {
int target = label->pos();
- __ Mov(w10, target + Code::kHeaderSize - kHeapObjectTag);
+ __ Mov(w10, target + InstructionStream::kHeaderSize - kHeapObjectTag);
} else {
__ Adr(x10, label, MacroAssembler::kAdrFar);
__ Sub(x10, x10, code_pointer());
@@ -1391,8 +1395,8 @@ void RegExpMacroAssemblerARM64::ClearRegisters(int reg_from, int reg_to) {
// We should not unroll the loop for less than 2 registers.
static_assert(kNumRegistersToUnroll > 2);
// We position the base pointer to (reg_from + 1).
- int base_offset = kFirstRegisterOnStack -
- kWRegSize - (kWRegSize * reg_from);
+ int base_offset =
+ kFirstRegisterOnStackOffset - kWRegSize - (kWRegSize * reg_from);
if (num_registers > kNumRegistersToUnroll) {
Register base = x10;
__ Add(base, frame_pointer(), base_offset);
@@ -1429,12 +1433,14 @@ static T* frame_entry_address(Address re_frame, int frame_offset) {
int RegExpMacroAssemblerARM64::CheckStackGuardState(
Address* return_address, Address raw_code, Address re_frame,
int start_index, const byte** input_start, const byte** input_end) {
- Code re_code = Code::cast(Object(raw_code));
+ InstructionStream re_code = InstructionStream::cast(Object(raw_code));
return NativeRegExpMacroAssembler::CheckStackGuardState(
- frame_entry<Isolate*>(re_frame, kIsolate), start_index,
- static_cast<RegExp::CallOrigin>(frame_entry<int>(re_frame, kDirectCall)),
- return_address, re_code, frame_entry_address<Address>(re_frame, kInput),
- input_start, input_end);
+ frame_entry<Isolate*>(re_frame, kIsolateOffset), start_index,
+ static_cast<RegExp::CallOrigin>(
+ frame_entry<int>(re_frame, kDirectCallOffset)),
+ return_address, re_code,
+ frame_entry_address<Address>(re_frame, kInputStringOffset), input_start,
+ input_end);
}
@@ -1477,7 +1483,7 @@ void RegExpMacroAssemblerARM64::CallCheckStackGuardState(Register scratch) {
__ Mov(w3, start_offset());
// RegExp code frame pointer.
__ Mov(x2, frame_pointer());
- // Code of self.
+ // InstructionStream of self.
__ Mov(x1, Operand(masm_->CodeObject()));
// We need to pass a pointer to the return address as first argument.
@@ -1498,7 +1504,7 @@ void RegExpMacroAssemblerARM64::CallCheckStackGuardState(Register scratch) {
__ Drop(xreg_to_claim);
- // Reload the Code pointer.
+ // Reload the InstructionStream pointer.
__ Mov(code_pointer(), Operand(masm_->CodeObject()));
}
@@ -1537,6 +1543,21 @@ void RegExpMacroAssemblerARM64::CompareAndBranchOrBacktrack(Register reg,
}
}
+void RegExpMacroAssemblerARM64::CallCFunctionFromIrregexpCode(
+ ExternalReference function, int num_arguments) {
+ // Irregexp code must not set fast_c_call_caller_fp and fast_c_call_caller_pc
+ // since
+ //
+ // 1. it may itself have been called using CallCFunction and nested calls are
+ // unsupported, and
+ // 2. it may itself have been called directly from C where the frame pointer
+ // might not be set (-fomit-frame-pointer), and thus frame iteration would
+ // fail.
+ //
+ // See also: crbug.com/v8/12670#c17.
+ __ CallCFunction(function, num_arguments,
+ MacroAssembler::SetIsolateDataSlots::kNo);
+}
void RegExpMacroAssemblerARM64::CheckPreemption() {
// Check for preemption.
@@ -1655,14 +1676,14 @@ void RegExpMacroAssemblerARM64::CallIf(Label* to, Condition condition) {
void RegExpMacroAssemblerARM64::RestoreLinkRegister() {
// TODO(v8:10026): Remove when we stop compacting for code objects that are
// active on the call stack.
- __ Pop<TurboAssembler::kAuthLR>(padreg, lr);
+ __ Pop<MacroAssembler::kAuthLR>(padreg, lr);
__ Add(lr, lr, Operand(masm_->CodeObject()));
}
void RegExpMacroAssemblerARM64::SaveLinkRegister() {
__ Sub(lr, lr, Operand(masm_->CodeObject()));
- __ Push<TurboAssembler::kSignLR>(lr, padreg);
+ __ Push<MacroAssembler::kSignLR>(lr, padreg);
}
@@ -1673,7 +1694,7 @@ MemOperand RegExpMacroAssemblerARM64::register_location(int register_index) {
num_registers_ = register_index + 1;
}
register_index -= kNumCachedRegisters;
- int offset = kFirstRegisterOnStack - register_index * kWRegSize;
+ int offset = kFirstRegisterOnStackOffset - register_index * kWRegSize;
return MemOperand(frame_pointer(), offset);
}
@@ -1684,7 +1705,7 @@ MemOperand RegExpMacroAssemblerARM64::capture_location(int register_index,
DCHECK_LE(kNumCachedRegisters, register_index);
DCHECK_EQ(register_index % 2, 0);
register_index -= kNumCachedRegisters;
- int offset = kFirstCaptureOnStack - register_index * kWRegSize;
+ int offset = kFirstCaptureOnStackOffset - register_index * kWRegSize;
// capture_location is used with Stp instructions to load/store 2 registers.
// The immediate field in the encoding is limited to 7 bits (signed).
if (is_int7(offset)) {