Changeset 283874 in webkit
- Timestamp:
- Oct 10, 2021 1:49:45 AM (9 months ago)
- Location:
- trunk
- Files:
-
- 1 added
- 16 edited
-
JSTests/ChangeLog (modified) (1 diff)
-
JSTests/stress/regexp-recompile.js (added)
-
JSTests/test262/expectations.yaml (modified) (1 diff)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h (modified) (1 diff)
-
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/ftl/FTLOperations.cpp (modified) (1 diff)
-
Source/JavaScriptCore/jit/JITOperations.cpp (modified) (1 diff)
-
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSGlobalObject.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSGlobalObject.h (modified) (3 diffs)
-
Source/JavaScriptCore/runtime/RegExpConstructor.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/runtime/RegExpObject.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/RegExpObject.h (modified) (8 diffs)
-
Source/JavaScriptCore/runtime/RegExpPrototype.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r283852 r283874 1 2021-10-09 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Refine RegExp#compile based on regexp-legacy-features proposal 4 https://bugs.webkit.org/show_bug.cgi?id=231486 5 6 Reviewed by Alexey Shvayka. 7 8 * stress/regexp-recompile.js: Added. 9 (shouldBe): 10 (recompile): 11 (target): 12 * test262/expectations.yaml: 13 1 14 2021-10-08 Tadeu Zagallo <tzagallo@apple.com> 2 15 -
trunk/JSTests/test262/expectations.yaml
r283705 r283874 6 6 default: "SyntaxError: Unexpected token '}'. Expected a parameter pattern or a ')' in parameter list." 7 7 strict mode: "SyntaxError: Unexpected token '}'. Expected a parameter pattern or a ')' in parameter list." 8 test/annexB/built-ins/RegExp/prototype/compile/this-cross-realm-instance.js:9 default: 'Test262Error: `RegExp.prototype.compile.call(otherRealm_regexp)` throws TypeError Expected a TypeError to be thrown but no exception was thrown at all'10 strict mode: 'Test262Error: `RegExp.prototype.compile.call(otherRealm_regexp)` throws TypeError Expected a TypeError to be thrown but no exception was thrown at all'11 test/annexB/built-ins/RegExp/prototype/compile/this-subclass-instance.js:12 default: 'Test262Error: `subclass_regexp.compile()` throws TypeError Expected a TypeError to be thrown but no exception was thrown at all'13 strict mode: 'Test262Error: `subclass_regexp.compile()` throws TypeError Expected a TypeError to be thrown but no exception was thrown at all'14 8 test/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-block.js: 15 9 default: 'Test262Error: An initialized binding is not created prior to evaluation Expected a ReferenceError to be thrown but no exception was thrown at all' -
trunk/Source/JavaScriptCore/ChangeLog
r283862 r283874 1 2021-10-09 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Refine RegExp#compile based on regexp-legacy-features proposal 4 https://bugs.webkit.org/show_bug.cgi?id=231486 5 6 Reviewed by Alexey Shvayka. 7 8 This patch refines RegExp#compile based regexp-legacy-features proposal[1]. 9 We add legacyFeaturesDisabledFlag flag to RegExpObject so that we can 10 detect [[LegacyFeaturesEnabled]]. 11 12 We also add regExpRecompiledWatchpoint to JSGlobalObject. We have strength 13 reduction in DFG / FTL, but we should recompile DFG / FTL code when RegExp 14 is recompiled. Since it is rare, instead of having this watchpoint per 15 RegExpObject, we hold it in JSGlobalObject. 16 17 [1]: https://github.com/tc39/proposal-regexp-legacy-features 18 19 * dfg/DFGSpeculativeJIT.cpp: 20 (JSC::DFG::SpeculativeJIT::compileNewRegexp): 21 (JSC::DFG::SpeculativeJIT::compileSetRegExpObjectLastIndex): 22 * dfg/DFGStrengthReductionPhase.cpp: 23 (JSC::DFG::StrengthReductionPhase::handleNode): 24 * ftl/FTLAbstractHeapRepository.h: 25 * ftl/FTLLowerDFGToB3.cpp: 26 (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq): 27 * ftl/FTLOperations.cpp: 28 (JSC::FTL::JSC_DEFINE_JIT_OPERATION): 29 * jit/JITOperations.cpp: 30 (JSC::JSC_DEFINE_JIT_OPERATION): 31 * llint/LLIntSlowPaths.cpp: 32 (JSC::LLInt::LLINT_SLOW_PATH_DECL): 33 * runtime/JSGlobalObject.cpp: 34 (JSC::JSGlobalObject::JSGlobalObject): 35 * runtime/JSGlobalObject.h: 36 (JSC::JSGlobalObject::regExpRecompiledWatchpoint): 37 (JSC::JSGlobalObject::isRegExpRecompiled const): 38 * runtime/RegExpConstructor.cpp: 39 (JSC::areLegacyFeaturesEnabled): 40 (JSC::regExpCreate): 41 (JSC::constructRegExp): 42 * runtime/RegExpObject.cpp: 43 (JSC::RegExpObject::RegExpObject): 44 * runtime/RegExpObject.h: 45 * runtime/RegExpPrototype.cpp: 46 (JSC::JSC_DEFINE_HOST_FUNCTION): 47 1 48 2021-10-08 Saam Barati <sbarati@apple.com> 2 49 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r283556 r283874 11224 11224 m_jit.storePtr( 11225 11225 TrustedImmPtr(node->cellOperand()), 11226 CCallHelpers::Address(resultGPR, RegExpObject::offsetOfRegExpAnd LastIndexIsNotWritableFlag()));11226 CCallHelpers::Address(resultGPR, RegExpObject::offsetOfRegExpAndFlags())); 11227 11227 m_jit.storeValue(lastIndexRegs, CCallHelpers::Address(resultGPR, RegExpObject::offsetOfLastIndex())); 11228 11228 m_jit.mutatorFence(vm()); … … 12774 12774 m_jit.branchTestPtr( 12775 12775 JITCompiler::NonZero, 12776 JITCompiler::Address(regExpGPR, RegExpObject::offsetOfRegExpAnd LastIndexIsNotWritableFlag()),12776 JITCompiler::Address(regExpGPR, RegExpObject::offsetOfRegExpAndFlags()), 12777 12777 JITCompiler::TrustedImm32(RegExpObject::lastIndexIsNotWritableFlag))); 12778 12778 } -
trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp
r283300 r283874 503 503 regExpObjectNode = m_node->child2().node(); 504 504 if (RegExpObject* regExpObject = regExpObjectNode->dynamicCastConstant<RegExpObject*>(vm())) { 505 JSGlobalObject* globalObject = regExpObject->globalObject(vm()); 506 if (globalObject->isRegExpRecompiled()) { 507 if (verbose) 508 dataLog("Giving up because RegExp recompile happens.\n"); 509 break; 510 } 511 m_graph.watchpoints().addLazily(globalObject->regExpRecompiledWatchpoint()); 505 512 regExp = regExpObject->regExp(); 506 513 regExpObjectNodeIsConstant = true; 507 } else if (regExpObjectNode->op() == NewRegexp) 514 } else if (regExpObjectNode->op() == NewRegexp) { 515 JSGlobalObject* globalObject = m_graph.globalObjectFor(regExpObjectNode->origin.semantic); 516 if (globalObject->isRegExpRecompiled()) { 517 if (verbose) 518 dataLog("Giving up because RegExp recompile happens.\n"); 519 break; 520 } 521 m_graph.watchpoints().addLazily(globalObject->regExpRecompiledWatchpoint()); 508 522 regExp = regExpObjectNode->castOperand<RegExp*>(); 509 else {523 } else { 510 524 if (verbose) 511 525 dataLog("Giving up because the regexp is unknown.\n"); … … 836 850 Node* regExpObjectNode = m_node->child2().node(); 837 851 RegExp* regExp; 838 if (RegExpObject* regExpObject = regExpObjectNode->dynamicCastConstant<RegExpObject*>(vm())) 852 if (RegExpObject* regExpObject = regExpObjectNode->dynamicCastConstant<RegExpObject*>(vm())) { 853 JSGlobalObject* globalObject = regExpObject->globalObject(vm()); 854 if (globalObject->isRegExpRecompiled()) { 855 if (verbose) 856 dataLog("Giving up because RegExp recompile happens.\n"); 857 break; 858 } 859 m_graph.watchpoints().addLazily(globalObject->regExpRecompiledWatchpoint()); 839 860 regExp = regExpObject->regExp(); 840 else if (regExpObjectNode->op() == NewRegexp) 861 } else if (regExpObjectNode->op() == NewRegexp) { 862 JSGlobalObject* globalObject = m_graph.globalObjectFor(regExpObjectNode->origin.semantic); 863 if (globalObject->isRegExpRecompiled()) { 864 if (verbose) 865 dataLog("Giving up because RegExp recompile happens.\n"); 866 break; 867 } 868 m_graph.watchpoints().addLazily(globalObject->regExpRecompiledWatchpoint()); 841 869 regExp = regExpObjectNode->castOperand<RegExp*>(); 842 else {870 } else { 843 871 if (verbose) 844 872 dataLog("Giving up because the regexp is unknown.\n"); -
trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h
r283556 r283874 124 124 macro(JSSymbolTableObject_symbolTable, JSSymbolTableObject::offsetOfSymbolTable()) \ 125 125 macro(NativeExecutable_asString, NativeExecutable::offsetOfAsString()) \ 126 macro(RegExpObject_regExpAnd LastIndexIsNotWritableFlag, RegExpObject::offsetOfRegExpAndLastIndexIsNotWritableFlag()) \126 macro(RegExpObject_regExpAndFlags, RegExpObject::offsetOfRegExpAndFlags()) \ 127 127 macro(RegExpObject_lastIndex, RegExpObject::offsetOfLastIndex()) \ 128 128 macro(ShadowChicken_Packet_callee, OBJECT_OFFSETOF(ShadowChicken::Packet, callee)) \ -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r283556 r283874 14291 14291 auto structure = m_graph.registerStructure(globalObject->regExpStructure()); 14292 14292 LValue fastResultValue = allocateObject<RegExpObject>(structure, m_out.intPtrZero, slowCase); 14293 m_out.storePtr(frozenPointer(regexp), fastResultValue, m_heaps.RegExpObject_regExpAnd LastIndexIsNotWritableFlag);14293 m_out.storePtr(frozenPointer(regexp), fastResultValue, m_heaps.RegExpObject_regExpAndFlags); 14294 14294 m_out.store64(lastIndex, fastResultValue, m_heaps.RegExpObject_lastIndex); 14295 14295 mutatorFence(); … … 14378 14378 ExoticObjectMode, noValue(), nullptr, 14379 14379 m_out.testNonZeroPtr( 14380 m_out.loadPtr(regExp, m_heaps.RegExpObject_regExpAnd LastIndexIsNotWritableFlag),14380 m_out.loadPtr(regExp, m_heaps.RegExpObject_regExpAndFlags), 14381 14381 m_out.constIntPtr(RegExpObject::lastIndexIsNotWritableFlag))); 14382 14382 -
trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp
r278875 r283874 690 690 CodeBlock* codeBlock = baselineCodeBlockForOriginAndBaselineCodeBlock(materialization->origin(), callFrame->codeBlock()->baselineAlternative()); 691 691 Structure* structure = codeBlock->globalObject()->regExpStructure(); 692 return RegExpObject::create(vm, structure, regExp); 692 static constexpr bool areLegacyFeaturesEnabled = true; 693 return RegExpObject::create(vm, structure, regExp, areLegacyFeaturesEnabled); 693 694 } 694 695 -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r283139 r283874 1891 1891 RegExp* regexp = static_cast<RegExp*>(regexpPtr); 1892 1892 ASSERT(regexp->isValid()); 1893 return RegExpObject::create(vm, globalObject->regExpStructure(), regexp); 1893 static constexpr bool areLegacyFeaturesEnabled = true; 1894 return RegExpObject::create(vm, globalObject->regExpStructure(), regexp, areLegacyFeaturesEnabled); 1894 1895 } 1895 1896 -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r283556 r283874 613 613 RegExp* regExp = jsCast<RegExp*>(getOperand(callFrame, bytecode.m_regexp)); 614 614 ASSERT(regExp->isValid()); 615 LLINT_RETURN(RegExpObject::create(vm, globalObject->regExpStructure(), regExp)); 615 static constexpr bool areLegacyFeaturesEnabled = true; 616 LLINT_RETURN(RegExpObject::create(vm, globalObject->regExpStructure(), regExp, areLegacyFeaturesEnabled)); 616 617 } 617 618 -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r283852 r283874 609 609 , m_varInjectionWatchpoint(WatchpointSet::create(IsWatched)) 610 610 , m_varReadOnlyWatchpoint(WatchpointSet::create(IsWatched)) 611 , m_regExpRecompiledWatchpoint(WatchpointSet::create(IsWatched)) 611 612 , m_weakRandom(Options::forceWeakRandomSeed() ? Options::forcedWeakRandomSeed() : static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0))) 612 613 , m_arrayIteratorProtocolWatchpointSet(IsWatched) -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h
r283852 r283874 488 488 RefPtr<WatchpointSet> m_varInjectionWatchpoint; 489 489 RefPtr<WatchpointSet> m_varReadOnlyWatchpoint; 490 RefPtr<WatchpointSet> m_regExpRecompiledWatchpoint; 490 491 491 492 std::unique_ptr<JSGlobalObjectRareData> m_rareData; … … 1026 1027 WatchpointSet* varInjectionWatchpoint() { return m_varInjectionWatchpoint.get(); } 1027 1028 WatchpointSet* varReadOnlyWatchpoint() { return m_varReadOnlyWatchpoint.get(); } 1029 WatchpointSet* regExpRecompiledWatchpoint() { return m_regExpRecompiledWatchpoint.get(); } 1028 1030 1029 1031 bool isHavingABadTime() const … … 1037 1039 bool arrayPrototypeChainIsSane(); 1038 1040 bool stringPrototypeChainIsSane(); 1041 1042 bool isRegExpRecompiled() const 1043 { 1044 return m_regExpRecompiledWatchpoint->hasBeenInvalidated(); 1045 } 1039 1046 1040 1047 void setProfileGroup(unsigned value) { createRareDataIfNeeded(); m_rareData->profileGroup = value; } -
trunk/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
r280489 r283874 188 188 } 189 189 190 static inline bool areLegacyFeaturesEnabled(JSGlobalObject* globalObject, JSValue newTarget) 191 { 192 if (!newTarget) 193 return true; 194 return newTarget == globalObject->regExpConstructor(); 195 } 196 190 197 inline Structure* getRegExpStructure(JSGlobalObject* globalObject, JSValue newTarget) 191 198 { … … 233 240 Structure* structure = getRegExpStructure(globalObject, newTarget); 234 241 RETURN_IF_EXCEPTION(scope, nullptr); 235 return RegExpObject::create(vm, structure, regExp );242 return RegExpObject::create(vm, structure, regExp, areLegacyFeaturesEnabled(globalObject, newTarget)); 236 243 } 237 244 … … 272 279 } 273 280 274 return RegExpObject::create(vm, structure, regExp );281 return RegExpObject::create(vm, structure, regExp, areLegacyFeaturesEnabled(globalObject, newTarget)); 275 282 } 276 283 -
trunk/Source/JavaScriptCore/runtime/RegExpObject.cpp
r278589 r283874 33 33 static JSC_DECLARE_CUSTOM_SETTER(regExpObjectSetLastIndexNonStrict); 34 34 35 RegExpObject::RegExpObject(VM& vm, Structure* structure, RegExp* regExp )35 RegExpObject::RegExpObject(VM& vm, Structure* structure, RegExp* regExp, bool areLegacyFeaturesEnabled) 36 36 : JSNonFinalObject(vm, structure) 37 , m_regExpAnd LastIndexIsNotWritableFlag(bitwise_cast<uintptr_t>(regExp)) // lastIndexIsNotWritableFlag is not set.37 , m_regExpAndFlags(bitwise_cast<uintptr_t>(regExp) | (areLegacyFeaturesEnabled ? 0 : legacyFeaturesDisabledFlag)) // lastIndexIsNotWritableFlag is not set. 38 38 { 39 39 m_lastIndex.setWithoutWriteBarrier(jsNumber(0)); -
trunk/Source/JavaScriptCore/runtime/RegExpObject.h
r278589 r283874 40 40 } 41 41 42 static constexpr uintptr_t lastIndexIsNotWritableFlag = 1; 42 static constexpr uintptr_t lastIndexIsNotWritableFlag = 0b01; 43 static constexpr uintptr_t legacyFeaturesDisabledFlag = 0b10; 44 static constexpr uintptr_t flagsMask = lastIndexIsNotWritableFlag | legacyFeaturesDisabledFlag; 45 static constexpr uintptr_t regExpMask = ~flagsMask; 43 46 44 static RegExpObject* create(VM& vm, Structure* structure, RegExp* regExp )47 static RegExpObject* create(VM& vm, Structure* structure, RegExp* regExp, bool areLegacyFeaturesEnabled = true) 45 48 { 46 RegExpObject* object = new (NotNull, allocateCell<RegExpObject>(vm.heap)) RegExpObject(vm, structure, regExp );49 RegExpObject* object = new (NotNull, allocateCell<RegExpObject>(vm.heap)) RegExpObject(vm, structure, regExp, areLegacyFeaturesEnabled); 47 50 object->finishCreation(vm); 48 51 return object; … … 51 54 static RegExpObject* create(VM& vm, Structure* structure, RegExp* regExp, JSValue lastIndex) 52 55 { 53 auto* object = create(vm, structure, regExp); 56 static constexpr bool areLegacyFeaturesEnabled = true; 57 auto* object = create(vm, structure, regExp, areLegacyFeaturesEnabled); 54 58 object->m_lastIndex.set(vm, object, lastIndex); 55 59 return object; … … 58 62 void setRegExp(VM& vm, RegExp* regExp) 59 63 { 60 uintptr_t result = (m_regExpAnd LastIndexIsNotWritableFlag & lastIndexIsNotWritableFlag) | bitwise_cast<uintptr_t>(regExp);61 m_regExpAnd LastIndexIsNotWritableFlag= result;64 uintptr_t result = (m_regExpAndFlags & flagsMask) | bitwise_cast<uintptr_t>(regExp); 65 m_regExpAndFlags = result; 62 66 vm.heap.writeBarrier(this, regExp); 63 67 } … … 65 69 RegExp* regExp() const 66 70 { 67 return bitwise_cast<RegExp*>(m_regExpAnd LastIndexIsNotWritableFlag & (~lastIndexIsNotWritableFlag));71 return bitwise_cast<RegExp*>(m_regExpAndFlags & regExpMask); 68 72 } 69 73 … … 113 117 } 114 118 115 static ptrdiff_t offsetOfRegExpAnd LastIndexIsNotWritableFlag()119 static ptrdiff_t offsetOfRegExpAndFlags() 116 120 { 117 return OBJECT_OFFSETOF(RegExpObject, m_regExpAnd LastIndexIsNotWritableFlag);121 return OBJECT_OFFSETOF(RegExpObject, m_regExpAndFlags); 118 122 } 119 123 … … 129 133 } 130 134 135 bool areLegacyFeaturesEnabled() const { return !(m_regExpAndFlags & legacyFeaturesDisabledFlag); } 136 131 137 private: 132 JS_EXPORT_PRIVATE RegExpObject(VM&, Structure*, RegExp* );138 JS_EXPORT_PRIVATE RegExpObject(VM&, Structure*, RegExp*, bool areLegacyFeaturesEnabled); 133 139 JS_EXPORT_PRIVATE void finishCreation(VM&); 134 140 … … 137 143 bool lastIndexIsWritable() const 138 144 { 139 return !(m_regExpAnd LastIndexIsNotWritableFlag& lastIndexIsNotWritableFlag);145 return !(m_regExpAndFlags & lastIndexIsNotWritableFlag); 140 146 } 141 147 142 148 void setLastIndexIsNotWritable() 143 149 { 144 m_regExpAnd LastIndexIsNotWritableFlag = (m_regExpAndLastIndexIsNotWritableFlag| lastIndexIsNotWritableFlag);150 m_regExpAndFlags = (m_regExpAndFlags | lastIndexIsNotWritableFlag); 145 151 } 146 152 … … 151 157 MatchResult matchInline(JSGlobalObject*, JSString*); 152 158 153 uintptr_t m_regExpAnd LastIndexIsNotWritableFlag{ 0 };159 uintptr_t m_regExpAndFlags { 0 }; 154 160 WriteBarrier<Unknown> m_lastIndex; 155 161 }; -
trunk/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
r279976 r283874 133 133 return throwVMTypeError(globalObject, scope); 134 134 135 if (thisRegExp->globalObject(vm) != globalObject) 136 return throwVMTypeError(globalObject, scope, "RegExp.prototype.compile function's Realm must be the same to |this| RegExp object"_s); 137 138 if (!thisRegExp->areLegacyFeaturesEnabled()) 139 return throwVMTypeError(globalObject, scope, "|this| RegExp object's legacy features are not enabled"_s); 140 135 141 RegExp* regExp; 136 142 JSValue arg0 = callFrame->argument(0); … … 155 161 if (!regExp->isValid()) 156 162 return throwVMError(globalObject, scope, regExp->errorToThrow(globalObject)); 163 164 globalObject->regExpRecompiledWatchpoint()->fireAll(vm, "RegExp is recompiled"); 157 165 158 166 thisRegExp->setRegExp(vm, regExp);
Note: See TracChangeset
for help on using the changeset viewer.