Bug 1847017 part 1 - Change stubs to load RegExpStatics and match result shape at runtime. r=iain

This will let us share the code across realms.

Differential Revision: https://phabricator.services.mozilla.com/D185910
This commit is contained in:
Jan de Mooij 2023-08-11 10:41:58 +00:00
Родитель 6675b4391f
Коммит 4138695bc8
3 изменённых файлов: 34 добавлений и 21 удалений

Просмотреть файл

@ -6726,6 +6726,15 @@ static bool HasOptimizableLastIndexSlot(RegExpObject* regexp, JSContext* cx) {
// Returns the RegExp stub used by the optimized code path for this intrinsic.
// We store a pointer to this in the IC stub to ensure GC doesn't discard it.
static JitCode* GetOrCreateRegExpStub(JSContext* cx, InlinableNative native) {
// The stubs assume the global has non-null RegExpStatics and match result
// shape.
if (!GlobalObject::getRegExpStatics(cx, cx->global()) ||
!cx->global()->regExpRealm().getOrCreateMatchResultShape(cx)) {
MOZ_ASSERT(cx->isThrowingOutOfMemory() || cx->isThrowingOverRecursed());
cx->clearPendingException();
return nullptr;
}
JitCode* code;
switch (native) {
case InlinableNative::IntrinsicRegExpBuiltinExecForTest:

Просмотреть файл

@ -1916,10 +1916,10 @@ static void UpdateRegExpStatics(MacroAssembler& masm, Register regexp,
//
// inputOutputDataStartOffset is the offset relative to the frame pointer
// register. This offset is negative for the RegExpExecTest stub.
static bool PrepareAndExecuteRegExp(JSContext* cx, MacroAssembler& masm,
Register regexp, Register input,
Register lastIndex, Register temp1,
Register temp2, Register temp3,
static bool PrepareAndExecuteRegExp(MacroAssembler& masm, Register regexp,
Register input, Register lastIndex,
Register temp1, Register temp2,
Register temp3,
int32_t inputOutputDataStartOffset,
gc::Heap initialStringHeap, Label* notFound,
Label* failure) {
@ -2140,11 +2140,10 @@ static bool PrepareAndExecuteRegExp(JSContext* cx, MacroAssembler& masm,
masm.branch32(Assembler::Equal, temp1, Imm32(RegExpRunStatus_Error), failure);
// Lazily update the RegExpStatics.
RegExpStatics* res = GlobalObject::getRegExpStatics(cx, cx->global());
if (!res) {
return false;
}
masm.movePtr(ImmPtr(res), temp1);
size_t offset = GlobalObjectData::offsetOfRegExpRealm() +
RegExpRealm::offsetOfRegExpStatics();
masm.loadGlobalObjectData(temp1);
masm.loadPtr(Address(temp1, offset), temp1);
UpdateRegExpStatics(masm, regexp, input, lastIndex, temp1, temp2, temp3,
initialStringHeap, volatileRegs);
@ -2444,12 +2443,6 @@ static JitCode* GenerateRegExpMatchStubShared(JSContext* cx,
Address flagsSlot(regexp, RegExpObject::offsetOfFlags());
Address lastIndexSlot(regexp, RegExpObject::offsetOfLastIndex());
SharedShape* shape =
cx->global()->regExpRealm().getOrCreateMatchResultShape(cx);
if (!shape) {
return nullptr;
}
TempAllocator temp(&cx->tempLifoAlloc());
JitContext jcx(cx);
StackMacroAssembler masm(cx, temp);
@ -2471,7 +2464,7 @@ static JitCode* GenerateRegExpMatchStubShared(JSContext* cx,
int32_t inputOutputDataStartOffset = 2 * sizeof(void*);
Label notFound, oolEntry;
if (!PrepareAndExecuteRegExp(cx, masm, regexp, input, lastIndex, temp1, temp2,
if (!PrepareAndExecuteRegExp(masm, regexp, input, lastIndex, temp1, temp2,
temp3, inputOutputDataStartOffset,
initialStringHeap, &notFound, &oolEntry)) {
return nullptr;
@ -2505,7 +2498,10 @@ static JitCode* GenerateRegExpMatchStubShared(JSContext* cx,
// Load the array length in temp2 and the shape in temp3.
Label allocated;
masm.load32(pairCountAddress, temp2);
masm.movePtr(ImmGCPtr(shape), temp3);
size_t offset = GlobalObjectData::offsetOfRegExpRealm() +
RegExpRealm::offsetOfNormalMatchResultShape();
masm.loadGlobalObjectData(temp3);
masm.loadPtr(Address(temp3, offset), temp3);
auto emitAllocObject = [&](size_t elementCapacity) {
gc::AllocKind kind = GuessArrayGCKind(elementCapacity);
@ -2983,7 +2979,7 @@ JitCode* JitRealm::generateRegExpSearcherStub(JSContext* cx) {
int32_t inputOutputDataStartOffset = 2 * sizeof(void*);
Label notFound, oolEntry;
if (!PrepareAndExecuteRegExp(cx, masm, regexp, input, lastIndex, temp1, temp2,
if (!PrepareAndExecuteRegExp(masm, regexp, input, lastIndex, temp1, temp2,
temp3, inputOutputDataStartOffset,
initialStringHeap, &notFound, &oolEntry)) {
return nullptr;
@ -3193,7 +3189,7 @@ JitCode* JitRealm::generateRegExpExecTestStub(JSContext* cx) {
static_assert(inputOutputDataStartOffset >= -256);
Label notFound, oolEntry;
if (!PrepareAndExecuteRegExp(cx, masm, regexp, input, lastIndex, temp1, temp2,
if (!PrepareAndExecuteRegExp(masm, regexp, input, lastIndex, temp1, temp2,
temp3, inputOutputDataStartOffset,
initialStringHeap, &notFound, &oolEntry)) {
return nullptr;

Просмотреть файл

@ -417,12 +417,20 @@ class RegExpRealm {
optimizableRegExpInstanceShape_ = shape;
}
static size_t offsetOfOptimizableRegExpPrototypeShape() {
static constexpr size_t offsetOfOptimizableRegExpPrototypeShape() {
return offsetof(RegExpRealm, optimizableRegExpPrototypeShape_);
}
static size_t offsetOfOptimizableRegExpInstanceShape() {
static constexpr size_t offsetOfOptimizableRegExpInstanceShape() {
return offsetof(RegExpRealm, optimizableRegExpInstanceShape_);
}
static constexpr size_t offsetOfRegExpStatics() {
return offsetof(RegExpRealm, regExpStatics);
}
static constexpr size_t offsetOfNormalMatchResultShape() {
static_assert(sizeof(HeapPtr<SharedShape*>) == sizeof(uintptr_t));
return offsetof(RegExpRealm, matchResultShapes_) +
ResultShapeKind::Normal * sizeof(uintptr_t);
}
};
RegExpRunStatus ExecuteRegExpAtomRaw(RegExpShared* re, JSLinearString* input,