Commit 019fa2b5 authored by Patrick Thier's avatar Patrick Thier Committed by Commit Bot

[regexp] Minor performance improvements and cleanups

Instead of checking code flags to decide if the irregexp code object is
an off-heap trampoline, we now directly load the builtin index offset
and treat the code as on-heap if the offset is -1.

In addition the regexp stack now has its own external reference for top
of stack address. This prevents calculating the top of stack address
using the base address and size at every invocation.

Bug: chromium:999993
Change-Id: I23649e8b410a56276f26846b0b12ad29310c3db7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1782565Reviewed-by: 's avatarPeter Marshall <petermarshall@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Patrick Thier <pthier@google.com>
Cr-Commit-Position: refs/heads/master@{#63548}
parent 00ef19d8
......@@ -46,14 +46,11 @@ TNode<RawPtrT> RegExpBuiltinsAssembler::LoadCodeObjectEntry(TNode<Code> code) {
TVARIABLE(RawPtrT, var_result);
Label if_code_is_off_heap(this), out(this);
TNode<Int32T> builtin_index = UncheckedCast<Int32T>(
LoadObjectField(code, Code::kBuiltinIndexOffset, MachineType::Int32()));
{
// TODO(pthier): A potential optimization for the future is to make this
// decision based on the builtin index instead of flags, and avoid the
// additional load below.
TNode<Int32T> code_flags = UncheckedCast<Int32T>(
LoadObjectField(code, Code::kFlagsOffset, MachineType::Int32()));
GotoIf(IsSetWord32(code_flags, Code::IsOffHeapTrampoline::kMask),
&if_code_is_off_heap);
GotoIfNot(Word32Equal(builtin_index, Int32Constant(Builtins::kNoBuiltinId)),
&if_code_is_off_heap);
var_result = ReinterpretCast<RawPtrT>(
IntPtrAdd(BitcastTaggedToWord(code),
IntPtrConstant(Code::kHeaderSize - kHeapObjectTag)));
......@@ -62,8 +59,6 @@ TNode<RawPtrT> RegExpBuiltinsAssembler::LoadCodeObjectEntry(TNode<Code> code) {
BIND(&if_code_is_off_heap);
{
TNode<Int32T> builtin_index = UncheckedCast<Int32T>(
LoadObjectField(code, Code::kBuiltinIndexOffset, MachineType::Int32()));
TNode<IntPtrT> builtin_entry_offset_from_isolate_root =
IntPtrAdd(IntPtrConstant(IsolateData::builtin_entry_table_offset()),
ChangeInt32ToIntPtr(Word32Shl(
......@@ -390,9 +385,8 @@ TNode<HeapObject> RegExpBuiltinsAssembler::RegExpExecInternal(
// External constants.
TNode<ExternalReference> isolate_address =
ExternalConstant(ExternalReference::isolate_address(isolate()));
TNode<ExternalReference> regexp_stack_memory_address_address =
ExternalConstant(
ExternalReference::address_of_regexp_stack_memory_address(isolate()));
TNode<ExternalReference> regexp_stack_memory_top_address = ExternalConstant(
ExternalReference::address_of_regexp_stack_memory_top_address(isolate()));
TNode<ExternalReference> regexp_stack_memory_size_address = ExternalConstant(
ExternalReference::address_of_regexp_stack_memory_size(isolate()));
TNode<ExternalReference> static_offsets_vector_address = ExternalConstant(
......@@ -588,18 +582,11 @@ TNode<HeapObject> RegExpBuiltinsAssembler::RegExpExecInternal(
// Argument 6: Start (high end) of backtracking stack memory area. This
// argument is ignored in the interpreter.
// TODO(pthier): We should consider creating a dedicated external reference
// for top of regexp stack instead of calculating it here for every
// execution.
TNode<RawPtrT> stack_start = UncheckedCast<RawPtrT>(
Load(MachineType::Pointer(), regexp_stack_memory_address_address));
TNode<IntPtrT> stack_size = UncheckedCast<IntPtrT>(
Load(MachineType::IntPtr(), regexp_stack_memory_size_address));
TNode<RawPtrT> stack_end =
ReinterpretCast<RawPtrT>(IntPtrAdd(stack_start, stack_size));
TNode<RawPtrT> stack_top = UncheckedCast<RawPtrT>(
Load(MachineType::Pointer(), regexp_stack_memory_top_address));
MachineType arg6_type = type_ptr;
TNode<RawPtrT> arg6 = stack_end;
TNode<RawPtrT> arg6 = stack_top;
// Argument 7: Indicate that this is a direct call from JavaScript.
MachineType arg7_type = type_int32;
......
......@@ -505,14 +505,14 @@ ExternalReference ExternalReference::address_of_static_offsets_vector(
reinterpret_cast<Address>(isolate->jsregexp_static_offsets_vector()));
}
ExternalReference ExternalReference::address_of_regexp_stack_limit(
ExternalReference ExternalReference::address_of_regexp_stack_limit_address(
Isolate* isolate) {
return ExternalReference(isolate->regexp_stack()->limit_address());
return ExternalReference(isolate->regexp_stack()->limit_address_address());
}
ExternalReference ExternalReference::address_of_regexp_stack_memory_address(
Isolate* isolate) {
return ExternalReference(isolate->regexp_stack()->memory_address());
return ExternalReference(isolate->regexp_stack()->memory_address_address());
}
ExternalReference ExternalReference::address_of_regexp_stack_memory_size(
......@@ -520,6 +520,12 @@ ExternalReference ExternalReference::address_of_regexp_stack_memory_size(
return ExternalReference(isolate->regexp_stack()->memory_size_address());
}
ExternalReference ExternalReference::address_of_regexp_stack_memory_top_address(
Isolate* isolate) {
return ExternalReference(
isolate->regexp_stack()->memory_top_address_address());
}
FUNCTION_REFERENCE_WITH_TYPE(ieee754_acos_function, base::ieee754::acos,
BUILTIN_FP_CALL)
FUNCTION_REFERENCE_WITH_TYPE(ieee754_acosh_function, base::ieee754::acosh,
......
......@@ -73,9 +73,13 @@ class StatsCounter;
V(fast_c_call_caller_pc_address, \
"IsolateData::fast_c_call_caller_pc_address") \
V(stack_is_iterable_address, "IsolateData::stack_is_iterable_address") \
V(address_of_regexp_stack_limit, "RegExpStack::limit_address()") \
V(address_of_regexp_stack_memory_address, "RegExpStack::memory_address()") \
V(address_of_regexp_stack_memory_size, "RegExpStack::memory_size()") \
V(address_of_regexp_stack_limit_address, \
"RegExpStack::limit_address_address()") \
V(address_of_regexp_stack_memory_address, \
"RegExpStack::memory_address_address()") \
V(address_of_regexp_stack_memory_size, "RegExpStack::memory_size_address()") \
V(address_of_regexp_stack_memory_top_address, \
"RegExpStack::memory_top_address_address()") \
V(address_of_static_offsets_vector, "OffsetsVector::static_offsets_vector") \
V(re_case_insensitive_compare_uc16, \
"NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16()") \
......
......@@ -1210,7 +1210,7 @@ void RegExpMacroAssemblerARM::CheckPreemption() {
void RegExpMacroAssemblerARM::CheckStackLimit() {
ExternalReference stack_limit =
ExternalReference::address_of_regexp_stack_limit(isolate());
ExternalReference::address_of_regexp_stack_limit_address(isolate());
__ mov(r0, Operand(stack_limit));
__ ldr(r0, MemOperand(r0));
__ cmp(backtrack_stackpointer(), Operand(r0));
......
......@@ -1466,7 +1466,7 @@ void RegExpMacroAssemblerARM64::CheckPreemption() {
void RegExpMacroAssemblerARM64::CheckStackLimit() {
ExternalReference stack_limit =
ExternalReference::address_of_regexp_stack_limit(isolate());
ExternalReference::address_of_regexp_stack_limit_address(isolate());
__ Mov(x10, stack_limit);
__ Ldr(x10, MemOperand(x10));
__ Cmp(backtrack_stackpointer(), x10);
......
......@@ -1233,7 +1233,7 @@ void RegExpMacroAssemblerIA32::CheckPreemption() {
void RegExpMacroAssemblerIA32::CheckStackLimit() {
Label no_stack_overflow;
ExternalReference stack_limit =
ExternalReference::address_of_regexp_stack_limit(isolate());
ExternalReference::address_of_regexp_stack_limit_address(isolate());
__ cmp(backtrack_stackpointer(), StaticVariable(stack_limit));
__ j(above, &no_stack_overflow);
......
......@@ -1281,7 +1281,8 @@ void RegExpMacroAssemblerMIPS::CheckPreemption() {
void RegExpMacroAssemblerMIPS::CheckStackLimit() {
ExternalReference stack_limit =
ExternalReference::address_of_regexp_stack_limit(masm_->isolate());
ExternalReference::address_of_regexp_stack_limit_address(
masm_->isolate());
__ li(a0, Operand(stack_limit));
__ lw(a0, MemOperand(a0));
......
......@@ -1319,7 +1319,8 @@ void RegExpMacroAssemblerMIPS::CheckPreemption() {
void RegExpMacroAssemblerMIPS::CheckStackLimit() {
ExternalReference stack_limit =
ExternalReference::address_of_regexp_stack_limit(masm_->isolate());
ExternalReference::address_of_regexp_stack_limit_address(
masm_->isolate());
__ li(a0, Operand(stack_limit));
__ Ld(a0, MemOperand(a0));
......
......@@ -1281,7 +1281,7 @@ void RegExpMacroAssemblerPPC::CheckPreemption() {
void RegExpMacroAssemblerPPC::CheckStackLimit() {
ExternalReference stack_limit =
ExternalReference::address_of_regexp_stack_limit(isolate());
ExternalReference::address_of_regexp_stack_limit_address(isolate());
__ mov(r3, Operand(stack_limit));
__ LoadP(r3, MemOperand(r3));
__ cmpl(backtrack_stackpointer(), r3);
......
......@@ -516,7 +516,6 @@ class RegExpCompiler {
const char* const error_message = nullptr;
Object code;
Object bytecode;
int num_registers = 0;
};
......
......@@ -72,12 +72,12 @@ Address RegExpStack::EnsureCapacity(size_t size) {
DeleteArray(thread_local_.memory_);
}
thread_local_.memory_ = new_memory;
thread_local_.memory_top_ = new_memory + size;
thread_local_.memory_size_ = size;
thread_local_.limit_ = reinterpret_cast<Address>(new_memory) +
kStackLimitSlack * kSystemPointerSize;
}
return reinterpret_cast<Address>(thread_local_.memory_) +
thread_local_.memory_size_;
return reinterpret_cast<Address>(thread_local_.memory_top_);
}
......
......@@ -46,8 +46,9 @@ class RegExpStack {
// Gives the top of the memory used as stack.
Address stack_base() {
DCHECK_NE(0, thread_local_.memory_size_);
return reinterpret_cast<Address>(thread_local_.memory_) +
thread_local_.memory_size_;
DCHECK_EQ(thread_local_.memory_top_,
thread_local_.memory_ + thread_local_.memory_size_);
return reinterpret_cast<Address>(thread_local_.memory_top_);
}
// The total size of the memory allocated for the stack.
......@@ -58,7 +59,7 @@ class RegExpStack {
// There is only a limited number of locations below the stack limit,
// so users of the stack should check the stack limit during any
// sequence of pushes longer that this.
Address* limit_address() { return &(thread_local_.limit_); }
Address* limit_address_address() { return &(thread_local_.limit_); }
// Ensures that there is a memory area with at least the specified size.
// If passing zero, the default/minimum size buffer is allocated.
......@@ -89,12 +90,15 @@ class RegExpStack {
// Structure holding the allocated memory, size and limit.
struct ThreadLocal {
ThreadLocal() { Clear(); }
// If memory_size_ > 0 then memory_ must be non-nullptr.
// If memory_size_ > 0 then memory_ and memory_top_ must be non-nullptr
// and memory_top_ = memory_ + memory_size_
byte* memory_;
byte* memory_top_;
size_t memory_size_;
Address limit_;
void Clear() {
memory_ = nullptr;
memory_top_ = nullptr;
memory_size_ = 0;
limit_ = kMemoryTop;
}
......@@ -102,7 +106,7 @@ class RegExpStack {
};
// Address of allocated memory.
Address memory_address() {
Address memory_address_address() {
return reinterpret_cast<Address>(&thread_local_.memory_);
}
......@@ -111,6 +115,11 @@ class RegExpStack {
return reinterpret_cast<Address>(&thread_local_.memory_size_);
}
// Address of top of memory used as stack.
Address memory_top_address_address() {
return reinterpret_cast<Address>(&thread_local_.memory_top_);
}
// Resets the buffer if it has grown beyond the default/minimum size.
// After this, the buffer is either the default size, or it is empty, so
// you have to call EnsureCapacity before using it again.
......
......@@ -1222,7 +1222,7 @@ void RegExpMacroAssemblerS390::CheckPreemption() {
void RegExpMacroAssemblerS390::CheckStackLimit() {
ExternalReference stack_limit =
ExternalReference::address_of_regexp_stack_limit(isolate());
ExternalReference::address_of_regexp_stack_limit_address(isolate());
__ mov(r2, Operand(stack_limit));
__ CmpLogicalP(backtrack_stackpointer(), MemOperand(r2));
SafeCall(&stack_overflow_label_, le);
......
......@@ -1336,7 +1336,7 @@ void RegExpMacroAssemblerX64::CheckPreemption() {
void RegExpMacroAssemblerX64::CheckStackLimit() {
Label no_stack_overflow;
ExternalReference stack_limit =
ExternalReference::address_of_regexp_stack_limit(isolate());
ExternalReference::address_of_regexp_stack_limit_address(isolate());
__ load_rax(stack_limit);
__ cmpq(backtrack_stackpointer(), rax);
__ j(above, &no_stack_overflow);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment