Skip to content

Commit d8448d0

Browse files
committed
[JSC] Add NewRegExpUntyped DFG node
https://bugs.webkit.org/show_bug.cgi?id=289416 rdar://146577257 Reviewed by Yijia Huang. This patch adds NewRegExpUntyped, which offers good type information for `new RegExp(..., ...)` constructor call. This is great since it offers good structure information in AI, and subsequent TryGetById will be removed in most of cases. We also fix Regexp => RegExp throughout JSC code. * Source/JavaScriptCore/JavaScriptCore.order: * Source/JavaScriptCore/bytecode/BytecodeList.rb: * Source/JavaScriptCore/bytecode/BytecodeUseDef.cpp: (JSC::computeUsesForBytecodeIndexImpl): (JSC::computeDefsForBytecodeIndexImpl): * Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitNewRegExp): * Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): * Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::handleConstantFunction): (JSC::DFG::ByteCodeParser::parseBlock): * Source/JavaScriptCore/dfg/DFGClobberize.h: (JSC::DFG::clobberize): * Source/JavaScriptCore/dfg/DFGClobbersExitState.cpp: (JSC::DFG::clobbersExitState): * Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp: (JSC::DFG::ConstantFoldingPhase::foldConstants): * Source/JavaScriptCore/dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * Source/JavaScriptCore/dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): * Source/JavaScriptCore/dfg/DFGMayExit.cpp: * Source/JavaScriptCore/dfg/DFGNode.h: (JSC::DFG::Node::convertToNewRegExp): (JSC::DFG::Node::convertToPhantomNewRegExp): (JSC::DFG::Node::hasCellOperand): (JSC::DFG::Node::hasStructure): (JSC::DFG::Node::isPhantomAllocation): (JSC::DFG::Node::convertToPhantomNewRegexp): Deleted. * Source/JavaScriptCore/dfg/DFGNodeType.h: * Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp: * Source/JavaScriptCore/dfg/DFGOperations.cpp: (JSC::DFG::JSC_DEFINE_JIT_OPERATION): * Source/JavaScriptCore/dfg/DFGOperations.h: * Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp: * Source/JavaScriptCore/dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute): * Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp: * Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h: * Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.cpp: * Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp: (JSC::DFG::StrengthReductionPhase::handleNode): * Source/JavaScriptCore/dfg/DFGValidate.cpp: * Source/JavaScriptCore/ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileNewRegExpUntyped): (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq): * Source/JavaScriptCore/ftl/FTLOperations.cpp: (JSC::FTL::JSC_DEFINE_NOEXCEPT_JIT_OPERATION): * Source/JavaScriptCore/jit/JIT.cpp: (JSC::JIT::privateCompileMainPass): * Source/JavaScriptCore/jit/JIT.h: * Source/JavaScriptCore/jit/JITOpcodes.cpp: (JSC::JIT::emit_op_new_reg_exp): (JSC::JIT::emit_op_new_regexp): Deleted. * Source/JavaScriptCore/jit/JITOperations.cpp: (JSC::JSC_DEFINE_JIT_OPERATION): * Source/JavaScriptCore/jit/JITOperations.h: * Source/JavaScriptCore/llint/LLIntSlowPaths.cpp: (JSC::LLInt::LLINT_SLOW_PATH_DECL): * Source/JavaScriptCore/llint/LLIntSlowPaths.h: * Source/JavaScriptCore/llint/LowLevelInterpreter.asm: * Source/JavaScriptCore/runtime/RegExpCache.cpp: (JSC::RegExpCache::lookup): (JSC::RegExpCache::lookupOrCreate): (JSC::RegExpCache::finalize): (JSC::RegExpCache::deleteAllCode): * Source/JavaScriptCore/runtime/RegExpCache.h: * Source/JavaScriptCore/runtime/RegExpConstructor.cpp: (JSC::constructRegExp): Canonical link: https://commits.webkit.org/292259@main
1 parent ec5c28c commit d8448d0

40 files changed

Lines changed: 296 additions & 87 deletions

Source/JavaScriptCore/JavaScriptCore.order

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1998,8 +1998,8 @@ __ZN3JSC10PrefixNode7emitDotERNS_17BytecodeGeneratorEPNS_10RegisterIDE
19981998
__ZN3JSC7JSValue13equalSlowCaseEPNS_9ExecStateES0_S0_
19991999
__ZN3WTF9HashTableIPN3JSC8JSObjectES3_NS_17IdentityExtractorENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES8_E16lookupForWritingINS_22IdentityHashTranslatorIS6_EES3_EENSt3__14pairIPS3_bEERKT0_
20002000
__ZN3JSC8JSString8getIndexEPNS_9ExecStateEj
2001-
__ZN3JSC3JIT18emit_op_new_regexpEPNS_11InstructionE
2002-
_cti_op_new_regexp
2001+
__ZN3JSC3JIT18emit_op_new_reg_expEPNS_11InstructionE
2002+
_cti_op_new_reg_exp
20032003
__ZN3JSC3JIT24emitArrayStorageGetByValEPNS_11InstructionERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE13PatchableJumpE
20042004
__ZN3JSC3JIT10emit_op_eqEPNS_11InstructionE
20052005
__ZN3JSC3JIT14emit_op_bitxorEPNS_11InstructionE
@@ -2325,7 +2325,7 @@ __ZN3JSC3DFG10BasicBlockD2Ev
23252325
__ZN3WTF9HashTableIPN3JSC9CodeBlockES3_NS_17IdentityExtractorENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES8_E3addINS_22IdentityHashTranslatorIS6_EES3_S3_EENS_18HashTableAddResultINS_17HashTableIteratorIS3_S3_S4_S6_S8_S8_EEEERKT0_RKT1_
23262326
__ZN3JSC3DFG15prepareOSREntryEPNS_9ExecStateEPNS_9CodeBlockEj
23272327
__ZN3JSC9CodeBlock12optimizeSoonEv
2328-
_operationNewRegexp
2328+
_operationNewRegExp
23292329
_operationRegExpTest
23302330
__ZN3JSC9CodeBlock20updateAllPredictionsENS_19OperationInProgressE
23312331
__ZN3JSC3DFG14ByteCodeParser22parseResolveOperationsEjjPN3WTF6VectorINS_16ResolveOperationELm0ENS2_15CrashOnOverflowEEEPNS_18PutToBaseOperationEPPNS0_4NodeESC_
@@ -4833,7 +4833,7 @@ _llint_slow_path_new_object
48334833
_llint_slow_path_new_array
48344834
_llint_slow_path_new_array_with_size
48354835
_llint_slow_path_new_array_buffer
4836-
_llint_slow_path_new_regexp
4836+
_llint_slow_path_new_reg_exp
48374837
_llint_slow_path_not
48384838
_llint_slow_path_eq
48394839
_llint_slow_path_neq
@@ -4992,7 +4992,7 @@ _llint_throw_during_call_trampoline
49924992
_llint_op_new_array
49934993
_llint_op_new_array_with_size
49944994
_llint_op_new_array_buffer
4995-
_llint_op_new_regexp
4995+
_llint_op_new_reg_exp
49964996
_llint_op_less
49974997
_llint_op_lesseq
49984998
_llint_op_greater

Source/JavaScriptCore/bytecode/BytecodeList.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1263,7 +1263,7 @@
12631263
argument: VirtualRegister,
12641264
}
12651265

1266-
op :new_regexp,
1266+
op :new_reg_exp,
12671267
args: {
12681268
dst: VirtualRegister,
12691269
regexp: VirtualRegister,

Source/JavaScriptCore/bytecode/BytecodeUseDef.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ void computeUsesForBytecodeIndexImpl(const JSInstruction* instruction, Checkpoin
8181
RELEASE_ASSERT_NOT_REACHED();
8282

8383
// No uses.
84-
case op_new_regexp:
84+
case op_new_reg_exp:
8585
case op_debug:
8686
case op_loop_hint:
8787
case op_jmp:
@@ -474,7 +474,7 @@ void computeDefsForBytecodeIndexImpl(unsigned numVars, const JSInstruction* inst
474474
DEFS(OpNewArrayBuffer, dst)
475475
DEFS(OpNewArrayWithSize, dst)
476476
DEFS(OpNewArrayWithSpecies, dst)
477-
DEFS(OpNewRegexp, dst)
477+
DEFS(OpNewRegExp, dst)
478478
DEFS(OpNewFunc, dst)
479479
DEFS(OpNewFuncExp, dst)
480480
DEFS(OpNewGeneratorFunc, dst)

Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3434,7 +3434,7 @@ RegisterID* BytecodeGenerator::emitNewArrayWithSpecies(RegisterID* dst, Register
34343434

34353435
RegisterID* BytecodeGenerator::emitNewRegExp(RegisterID* dst, RegExp* regExp)
34363436
{
3437-
OpNewRegexp::emit(this, dst, addConstantValue(regExp));
3437+
OpNewRegExp::emit(this, dst, addConstantValue(regExp));
34383438
return dst;
34393439
}
34403440

Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3423,6 +3423,12 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
34233423
break;
34243424
}
34253425

3426+
case NewRegExpUntyped: {
3427+
ASSERT(node->structure()->classInfoForCells() == RegExpObject::info());
3428+
setForNode(node, node->structure());
3429+
break;
3430+
}
3431+
34263432
case NewSymbol: {
34273433
if (node->child1() && node->child1().useKind() != StringUse)
34283434
clobberWorld();
@@ -3566,7 +3572,7 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
35663572
setForNode(node, node->structure());
35673573
break;
35683574

3569-
case NewRegexp:
3575+
case NewRegExp:
35703576
setForNode(node, m_graph.globalObjectFor(node->origin.semantic)->regExpStructure());
35713577
break;
35723578

@@ -3801,7 +3807,7 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
38013807
case PhantomNewArrayWithSpread:
38023808
case PhantomNewArrayBuffer:
38033809
case PhantomNewInternalFieldObject:
3804-
case PhantomNewRegexp:
3810+
case PhantomNewRegExp:
38053811
case BottomValue: {
38063812
clearForNode(node);
38073813
break;

Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
#include "PrivateFieldPutKind.h"
8484
#include "PutByIdFlags.h"
8585
#include "PutByStatus.h"
86+
#include "RegExpConstructor.h"
8687
#include "RegExpPrototype.h"
8788
#include "SetConstructor.h"
8889
#include "SetPrivateBrandStatus.h"
@@ -5035,6 +5036,27 @@ bool ByteCodeParser::handleConstantFunction(
50355036
return true;
50365037
}
50375038

5039+
if (function->classInfo() == RegExpConstructor::info()) {
5040+
Node* newTargetNode = get(virtualRegisterForArgumentIncludingThis(0, registerOffset));
5041+
// We cannot handle the case where new.target != callee (i.e. a construct from a super call) because we
5042+
// don't know what the prototype of the constructed object will be.
5043+
// FIXME: If we have inlined super calls up to the call site, however, we should be able to figure out the structure. https://bugs.webkit.org/show_bug.cgi?id=152700
5044+
if (newTargetNode != callTargetNode)
5045+
return false;
5046+
5047+
auto* structure = function->globalObject()->regExpStructure();
5048+
if (structure) {
5049+
if (argumentCountIncludingThis >= 3) {
5050+
insertChecks();
5051+
auto* content = get(virtualRegisterForArgumentIncludingThis(1, registerOffset));
5052+
auto* flags = get(virtualRegisterForArgumentIncludingThis(2, registerOffset));
5053+
Node* resultNode = addToGraph(NewRegExpUntyped, OpInfo(m_graph.registerStructure(structure)), content, flags);
5054+
set(result, resultNode);
5055+
return true;
5056+
}
5057+
}
5058+
}
5059+
50385060
if (function->classInfo() == MapConstructor::info() && kind == CodeForConstruct) {
50395061
Node* newTargetNode = get(virtualRegisterForArgumentIncludingThis(0, registerOffset));
50405062
// We cannot handle the case where new.target != callee (i.e. a construct from a super call) because we
@@ -6888,12 +6910,12 @@ void ByteCodeParser::parseBlock(unsigned limit)
68886910
NEXT_OPCODE(op_new_array_buffer);
68896911
}
68906912

6891-
case op_new_regexp: {
6892-
auto bytecode = currentInstruction->as<OpNewRegexp>();
6913+
case op_new_reg_exp: {
6914+
auto bytecode = currentInstruction->as<OpNewRegExp>();
68936915
ASSERT(bytecode.m_regexp.isConstant());
68946916
FrozenValue* frozenRegExp = m_graph.freezeStrong(m_inlineStackTop->m_codeBlock->getConstant(bytecode.m_regexp));
6895-
set(bytecode.m_dst, addToGraph(NewRegexp, OpInfo(frozenRegExp), jsConstant(jsNumber(0))));
6896-
NEXT_OPCODE(op_new_regexp);
6917+
set(bytecode.m_dst, addToGraph(NewRegExp, OpInfo(frozenRegExp), jsConstant(jsNumber(0))));
6918+
NEXT_OPCODE(op_new_reg_exp);
68976919
}
68986920

68996921
case op_get_rest_length: {

Source/JavaScriptCore/dfg/DFGClobberize.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1957,11 +1957,21 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu
19571957
clobberTop();
19581958
return;
19591959

1960+
case NewRegExpUntyped:
1961+
if (node->child1().useKind() == StringUse && node->child2().useKind() == StringUse) {
1962+
// SyntaxError may happen.
1963+
read(World);
1964+
write(SideState);
1965+
write(HeapObjectCount);
1966+
} else
1967+
clobberTop();
1968+
return;
1969+
19601970
case NewObject:
19611971
case NewGenerator:
19621972
case NewAsyncGenerator:
19631973
case NewInternalFieldObject:
1964-
case NewRegexp:
1974+
case NewRegExp:
19651975
case NewStringObject:
19661976
case NewMap:
19671977
case NewSet:
@@ -1975,7 +1985,7 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu
19751985
case MaterializeNewInternalFieldObject:
19761986
case PhantomCreateActivation:
19771987
case MaterializeCreateActivation:
1978-
case PhantomNewRegexp:
1988+
case PhantomNewRegExp:
19791989
read(HeapObjectCount);
19801990
write(HeapObjectCount);
19811991
return;

Source/JavaScriptCore/dfg/DFGClobbersExitState.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ bool clobbersExitState(Graph& graph, Node* node)
5959
case NewGenerator:
6060
case NewAsyncGenerator:
6161
case NewInternalFieldObject:
62-
case NewRegexp:
62+
case NewRegExp:
6363
case NewMap:
6464
case NewSet:
6565
case NewStringObject:
@@ -74,7 +74,7 @@ bool clobbersExitState(Graph& graph, Node* node)
7474
case MaterializeNewInternalFieldObject:
7575
case PhantomCreateActivation:
7676
case MaterializeCreateActivation:
77-
case PhantomNewRegexp:
77+
case PhantomNewRegExp:
7878
case CountExecution:
7979
case SuperSamplerBegin:
8080
case SuperSamplerEnd:
@@ -95,6 +95,9 @@ bool clobbersExitState(Graph& graph, Node* node)
9595
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=148440
9696
return false;
9797

98+
case NewRegExpUntyped:
99+
return !(node->child1().useKind() == StringUse && node->child2().useKind() == StringUse);
100+
98101
case CreateActivation:
99102
// Like above, but with the activation allocation caveat.
100103
return node->castOperand<SymbolTable*>()->singleton().isStillValid();

Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1632,7 +1632,7 @@ class ConstantFoldingPhase : public Phase {
16321632
case PhantomSpread:
16331633
case PhantomNewArrayWithSpread:
16341634
case PhantomNewArrayBuffer:
1635-
case PhantomNewRegexp:
1635+
case PhantomNewRegExp:
16361636
case BottomValue:
16371637
alreadyHandled = true;
16381638
break;

Source/JavaScriptCore/dfg/DFGDoesGC.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ bool doesGC(Graph& graph, Node* node)
237237
case PhantomNewArrayBuffer:
238238
case PhantomSpread:
239239
case PhantomClonedArguments:
240-
case PhantomNewRegexp:
240+
case PhantomNewRegExp:
241241
case GetMyArgumentByVal:
242242
case GetMyArgumentByValOutOfBounds:
243243
case ForwardVarargs:
@@ -413,7 +413,8 @@ bool doesGC(Graph& graph, Node* node)
413413
case NewArrayWithSpecies:
414414
case NewArrayWithSizeAndStructure:
415415
case NewArrayBuffer:
416-
case NewRegexp:
416+
case NewRegExp:
417+
case NewRegExpUntyped:
417418
case NewStringObject:
418419
case NewMap:
419420
case NewSet:

0 commit comments

Comments
 (0)