зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
6675b4391f
Коммит
4138695bc8
|
@ -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, ¬Found, &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, ¬Found, &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, ¬Found, &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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче