Unreviewed, roll out r240220 due to date-format-xparb regression
authoryusukesuzuki@slowstart.org <yusukesuzuki@slowstart.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 22 Jan 2019 05:28:35 +0000 (05:28 +0000)
committeryusukesuzuki@slowstart.org <yusukesuzuki@slowstart.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 22 Jan 2019 05:28:35 +0000 (05:28 +0000)
https://bugs.webkit.org/show_bug.cgi?id=193603

JSTests:

* stress/let-lexical-binding-shadow-existing-global-property-ftl.js:
* stress/scope-operation-cache-global-property-before-deleting.js: Removed.
* stress/scope-operation-cache-global-property-bump-counter.js: Removed.
* stress/scope-operation-cache-global-property-even-if-it-fails.js: Removed.

Source/JavaScriptCore:

* bytecode/BytecodeList.rb:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::notifyLexicalBindingShadowing):
(JSC::CodeBlock::notifyLexicalBindingUpdate): Deleted.
* bytecode/CodeBlock.h:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGDesiredGlobalProperties.cpp:
(JSC::DFG::DesiredGlobalProperties::isStillValidOnMainThread):
* dfg/DFGDesiredGlobalProperties.h:
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::watchGlobalProperty): Deleted.
* dfg/DFGGraph.h:
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::isStillValidOnMainThread):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_resolve_scope):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emit_op_resolve_scope):
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
(JSC::CommonSlowPaths::tryCachePutToScopeGlobal):
(JSC::CommonSlowPaths::tryCacheGetFromScopeGlobal):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::notifyLexicalBindingShadowing):
(JSC::JSGlobalObject::getReferencedPropertyWatchpointSet):
(JSC::JSGlobalObject::ensureReferencedPropertyWatchpointSet):
(JSC::JSGlobalObject::bumpGlobalLexicalBindingEpoch): Deleted.
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::globalLexicalBindingEpoch const): Deleted.
(JSC::JSGlobalObject::globalLexicalBindingEpochOffset): Deleted.
(JSC::JSGlobalObject::addressOfGlobalLexicalBindingEpoch): Deleted.
* runtime/Options.cpp:
(JSC::Options::initialize):
(JSC::Options::setOptions):
(JSC::Options::setOptionWithoutAlias):
(JSC::correctOptions): Deleted.
* runtime/Options.h:
* runtime/ProgramExecutable.cpp:
(JSC::ProgramExecutable::initializeGlobalProperties):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240248 268f45cc-cd09-0410-ab3c-d52691b4dbfc

26 files changed:
JSTests/ChangeLog
JSTests/stress/let-lexical-binding-shadow-existing-global-property-ftl.js
JSTests/stress/scope-operation-cache-global-property-before-deleting.js [deleted file]
JSTests/stress/scope-operation-cache-global-property-bump-counter.js [deleted file]
JSTests/stress/scope-operation-cache-global-property-even-if-it-fails.js [deleted file]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/BytecodeList.rb
Source/JavaScriptCore/bytecode/CodeBlock.cpp
Source/JavaScriptCore/bytecode/CodeBlock.h
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Source/JavaScriptCore/dfg/DFGDesiredGlobalProperties.cpp
Source/JavaScriptCore/dfg/DFGDesiredGlobalProperties.h
Source/JavaScriptCore/dfg/DFGGraph.cpp
Source/JavaScriptCore/dfg/DFGGraph.h
Source/JavaScriptCore/dfg/DFGPlan.cpp
Source/JavaScriptCore/jit/JITPropertyAccess.cpp
Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
Source/JavaScriptCore/runtime/CommonSlowPaths.h
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.h
Source/JavaScriptCore/runtime/Options.cpp
Source/JavaScriptCore/runtime/Options.h
Source/JavaScriptCore/runtime/ProgramExecutable.cpp

index 286670b..707563c 100644 (file)
@@ -1,3 +1,13 @@
+2019-01-21  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        Unreviewed, roll out r240220 due to date-format-xparb regression
+        https://bugs.webkit.org/show_bug.cgi?id=193603
+
+        * stress/let-lexical-binding-shadow-existing-global-property-ftl.js:
+        * stress/scope-operation-cache-global-property-before-deleting.js: Removed.
+        * stress/scope-operation-cache-global-property-bump-counter.js: Removed.
+        * stress/scope-operation-cache-global-property-even-if-it-fails.js: Removed.
+
 2019-01-21  Caio Lima  <ticaiolima@gmail.com>
 
         DoesGC rule is wrong for nodes with BigIntUse
index b47b72c..20b4322 100644 (file)
@@ -40,7 +40,6 @@ for (var i = 0; i < 1e6; ++i)
     shouldBe(get(), 3);
 
 foo();
-shouldBe(globalThis.bar, 4);
 shouldBe(bar, 4);
 shouldBe(get(), 4);
 
diff --git a/JSTests/stress/scope-operation-cache-global-property-before-deleting.js b/JSTests/stress/scope-operation-cache-global-property-before-deleting.js
deleted file mode 100644 (file)
index ca9fe0d..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-function shouldThrow(func, errorMessage) {
-    var errorThrown = false;
-    var error = null;
-    try {
-        func();
-    } catch (e) {
-        errorThrown = true;
-        error = e;
-    }
-    if (!errorThrown)
-        throw new Error('not thrown');
-    if (String(error) !== errorMessage)
-        throw new Error(`bad error: ${String(error)}`);
-}
-noInline(shouldThrow);
-
-function bar()
-{
-    foo = 42;
-}
-
-bar();
-bar();
-delete globalThis.foo;
-$.evalScript(`const foo = 50`);
-
-shouldThrow(() => bar(), `TypeError: Attempted to assign to readonly property.`);
diff --git a/JSTests/stress/scope-operation-cache-global-property-bump-counter.js b/JSTests/stress/scope-operation-cache-global-property-bump-counter.js
deleted file mode 100644 (file)
index d1dcdd0..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-//@ runDefault("--thresholdForGlobalLexicalBindingEpoch=2")
-
-function shouldBe(actual, expected) {
-    if (actual !== expected)
-        throw new Error('bad value: ' + actual);
-}
-noInline(shouldBe);
-
-foo1 = 1;
-foo2 = 2;
-function get1() {
-    return foo1;
-}
-noInline(get1);
-
-function get2() {
-    return foo2;
-}
-noInline(get2);
-
-function get1If(condition) {
-    if (condition)
-        return foo1;
-    return -1;
-}
-noInline(get1If);
-
-function get2If(condition) {
-    if (condition)
-        return foo2;
-    return -1;
-}
-noInline(get2If);
-
-for (var i = 0; i < 1e5; ++i) {
-    shouldBe(get1(), 1);
-    shouldBe(get2(), 2);
-    shouldBe(get1(), 1);
-    shouldBe(get2(), 2);
-    shouldBe(get1If(true), 1);
-    shouldBe(get2If(true), 2);
-    shouldBe(get1If(false), -1);
-    shouldBe(get2If(false), -1);
-}
-
-$.evalScript(`const foo1 = 41;`);
-$.evalScript(`const foo2 = 42;`);
-
-for (var i = 0; i < 1e3; ++i) {
-    shouldBe(get1(), 41);
-    shouldBe(get2(), 42);
-    shouldBe(get1(), 41);
-    shouldBe(get2(), 42);
-    shouldBe(get1If(false), -1);
-    shouldBe(get2If(false), -1);
-}
-shouldBe(get1If(true), 41);
-shouldBe(get2If(true), 42);
diff --git a/JSTests/stress/scope-operation-cache-global-property-even-if-it-fails.js b/JSTests/stress/scope-operation-cache-global-property-even-if-it-fails.js
deleted file mode 100644 (file)
index 51dac81..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-function shouldThrow(func, errorMessage) {
-    var errorThrown = false;
-    var error = null;
-    try {
-        func();
-    } catch (e) {
-        errorThrown = true;
-        error = e;
-    }
-    if (!errorThrown)
-        throw new Error('not thrown');
-    if (String(error) !== errorMessage)
-        throw new Error(`bad error: ${String(error)}`);
-}
-noInline(shouldThrow);
-
-function foo() {
-    bar = 4;
-}
-Object.preventExtensions(this);
-foo();
-$.evalScript('const bar = 3;');
-shouldThrow(() => foo(), `TypeError: Attempted to assign to readonly property.`);
index 34e1d93..2a79df4 100644 (file)
@@ -1,5 +1,54 @@
 2019-01-21  Yusuke Suzuki  <ysuzuki@apple.com>
 
+        Unreviewed, roll out r240220 due to date-format-xparb regression
+        https://bugs.webkit.org/show_bug.cgi?id=193603
+
+        * bytecode/BytecodeList.rb:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::notifyLexicalBindingShadowing):
+        (JSC::CodeBlock::notifyLexicalBindingUpdate): Deleted.
+        * bytecode/CodeBlock.h:
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGDesiredGlobalProperties.cpp:
+        (JSC::DFG::DesiredGlobalProperties::isStillValidOnMainThread):
+        * dfg/DFGDesiredGlobalProperties.h:
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::watchGlobalProperty): Deleted.
+        * dfg/DFGGraph.h:
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::isStillValidOnMainThread):
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emit_op_resolve_scope):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emit_op_resolve_scope):
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        (JSC::CommonSlowPaths::tryCachePutToScopeGlobal):
+        (JSC::CommonSlowPaths::tryCacheGetFromScopeGlobal):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::notifyLexicalBindingShadowing):
+        (JSC::JSGlobalObject::getReferencedPropertyWatchpointSet):
+        (JSC::JSGlobalObject::ensureReferencedPropertyWatchpointSet):
+        (JSC::JSGlobalObject::bumpGlobalLexicalBindingEpoch): Deleted.
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::globalLexicalBindingEpoch const): Deleted.
+        (JSC::JSGlobalObject::globalLexicalBindingEpochOffset): Deleted.
+        (JSC::JSGlobalObject::addressOfGlobalLexicalBindingEpoch): Deleted.
+        * runtime/Options.cpp:
+        (JSC::Options::initialize):
+        (JSC::Options::setOptions):
+        (JSC::Options::setOptionWithoutAlias):
+        (JSC::correctOptions): Deleted.
+        * runtime/Options.h:
+        * runtime/ProgramExecutable.cpp:
+        (JSC::ProgramExecutable::initializeGlobalProperties):
+
+2019-01-21  Yusuke Suzuki  <ysuzuki@apple.com>
+
         [JSC] StrictModeTypeErrorFunction is no longer used
         https://bugs.webkit.org/show_bug.cgi?id=193662
 
index 115bd3b..bb5f126 100644 (file)
@@ -833,11 +833,8 @@ op :resolve_scope,
     },
     metadata: {
         resolveType: ResolveType, # offset 4
-        _0: { # offset 5
-            localScopeDepth: unsigned,
-            globalLexicalBindingEpoch: unsigned,
-        },
-        _1: { # offset 6
+        localScopeDepth: unsigned, # offset 5
+        _: { # offset 6
              # written during linking
              lexicalEnvironment: WriteBarrierBase[JSCell], # lexicalEnvironment && type == ModuleVar
              symbolTable: WriteBarrierBase[SymbolTable], # lexicalEnvironment && type != ModuleVar
index 68d3d2d..0c63456 100644 (file)
@@ -2668,22 +2668,17 @@ void CodeBlock::tallyFrequentExitSites()
 }
 #endif // ENABLE(DFG_JIT)
 
-void CodeBlock::notifyLexicalBindingUpdate()
+void CodeBlock::notifyLexicalBindingShadowing(VM& vm, const IdentifierSet& set)
 {
     // FIXME: Currently, module code do not query to JSGlobalLexicalEnvironment. So this case should be removed once it is fixed.
     // https://bugs.webkit.org/show_bug.cgi?id=193347
     if (scriptMode() == JSParserScriptMode::Module)
         return;
     JSGlobalObject* globalObject = m_globalObject.get();
-    JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsCast<JSGlobalLexicalEnvironment*>(globalObject->globalScope());
-    SymbolTable* symbolTable = globalLexicalEnvironment->symbolTable();
 
-    ConcurrentJSLocker locker(m_lock);
+    auto scope = DECLARE_THROW_SCOPE(vm);
 
-    auto isShadowed = [&] (UniquedStringImpl* uid) {
-        ConcurrentJSLocker locker(symbolTable->m_lock);
-        return symbolTable->contains(locker, uid);
-    };
+    ConcurrentJSLocker locker(m_lock);
 
     for (const auto& instruction : *m_instructions) {
         OpcodeID opcodeID = instruction->opcodeID();
@@ -2694,13 +2689,72 @@ void CodeBlock::notifyLexicalBindingUpdate()
             ResolveType originalResolveType = metadata.m_resolveType;
             if (originalResolveType == GlobalProperty || originalResolveType == GlobalPropertyWithVarInjectionChecks) {
                 const Identifier& ident = identifier(bytecode.m_var);
-                if (isShadowed(ident.impl()))
-                    metadata.m_globalLexicalBindingEpoch = 0;
-                else
-                    metadata.m_globalLexicalBindingEpoch = globalObject->globalLexicalBindingEpoch();
+                if (set.contains(ident.impl())) {
+                    // We pass JSGlobalLexicalScope as a start point of the scope chain.
+                    // It should immediately find the lexical binding because that's the reason why we perform this rewriting now.
+                    ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), bytecode.m_localScopeDepth, globalObject->globalScope(), ident, Get, bytecode.m_resolveType, InitializationMode::NotInitialization);
+                    scope.releaseAssertNoException();
+                    ASSERT(op.type == GlobalLexicalVarWithVarInjectionChecks || op.type == GlobalLexicalVar);
+                    metadata.m_resolveType = needsVarInjectionChecks(originalResolveType) ? GlobalLexicalVarWithVarInjectionChecks : GlobalLexicalVar;
+                    metadata.m_localScopeDepth = 0;
+                    ASSERT(!op.lexicalEnvironment);
+                    JSScope* constantScope = JSScope::constantScopeForCodeBlock(metadata.m_resolveType, this);
+                    ASSERT(constantScope == globalObject->globalScope());
+                    metadata.m_constantScope.set(vm, this, constantScope);
+                    dataLogLnIf(CodeBlockInternal::verbose, "Rewrite op_resolve_scope from ", originalResolveType, " to ", metadata.m_resolveType);
+                }
             }
             break;
         }
+
+        case op_get_from_scope: {
+            auto bytecode = instruction->as<OpGetFromScope>();
+            auto& metadata = bytecode.metadata(this);
+            ResolveType originalResolveType = metadata.m_getPutInfo.resolveType();
+            if (originalResolveType == GlobalProperty || originalResolveType == GlobalPropertyWithVarInjectionChecks) {
+                const Identifier& ident = identifier(bytecode.m_var);
+                if (set.contains(ident.impl())) {
+                    // We pass JSGlobalLexicalScope as a start point of the scope chain.
+                    // It should immediately find the lexical binding because that's the reason why we perform this rewriting now.
+                    ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), bytecode.m_localScopeDepth, globalObject->globalScope(), ident, Get, bytecode.m_getPutInfo.resolveType(), InitializationMode::NotInitialization);
+                    scope.releaseAssertNoException();
+                    ASSERT(op.type == GlobalLexicalVarWithVarInjectionChecks || op.type == GlobalLexicalVar);
+                    metadata.m_getPutInfo = GetPutInfo(bytecode.m_getPutInfo.resolveMode(), needsVarInjectionChecks(originalResolveType) ? GlobalLexicalVarWithVarInjectionChecks : GlobalLexicalVar, bytecode.m_getPutInfo.initializationMode());
+                    metadata.m_watchpointSet = op.watchpointSet;
+                    metadata.m_operand = op.operand;
+                    dataLogLnIf(CodeBlockInternal::verbose, "Rewrite op_get_from_scope from ", originalResolveType, " to ", metadata.m_getPutInfo.resolveType());
+                }
+            }
+            break;
+        }
+
+        case op_put_to_scope: {
+            auto bytecode = instruction->as<OpPutToScope>();
+            auto& metadata = bytecode.metadata(this);
+            ResolveType originalResolveType = metadata.m_getPutInfo.resolveType();
+            if (originalResolveType == GlobalProperty || originalResolveType == GlobalPropertyWithVarInjectionChecks) {
+                const Identifier& ident = identifier(bytecode.m_var);
+                if (set.contains(ident.impl())) {
+                    // We pass JSGlobalLexicalScope as a start point of the scope chain.
+                    // It should immediately find the lexical binding because that's the reason why we perform this rewriting now.
+                    ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), bytecode.m_symbolTableOrScopeDepth, globalObject->globalScope(), ident, Put, bytecode.m_getPutInfo.resolveType(), bytecode.m_getPutInfo.initializationMode());
+                    scope.releaseAssertNoException();
+                    ASSERT(op.type == GlobalLexicalVarWithVarInjectionChecks || op.type == GlobalLexicalVar || op.type == Dynamic);
+
+                    ResolveType resolveType = op.type;
+                    metadata.m_watchpointSet = nullptr;
+                    if (resolveType == GlobalLexicalVarWithVarInjectionChecks || resolveType == GlobalLexicalVar) {
+                        resolveType = needsVarInjectionChecks(originalResolveType) ? GlobalLexicalVarWithVarInjectionChecks : GlobalLexicalVar;
+                        metadata.m_watchpointSet = op.watchpointSet;
+                    }
+                    metadata.m_getPutInfo = GetPutInfo(bytecode.m_getPutInfo.resolveMode(), resolveType, bytecode.m_getPutInfo.initializationMode());
+                    metadata.m_operand = op.operand;
+                    dataLogLnIf(CodeBlockInternal::verbose, "Rewrite op_put_to_scope from ", originalResolveType, " to ", metadata.m_getPutInfo.resolveType());
+                }
+            }
+            break;
+        }
+
         default:
             break;
         }
index 94e6bd2..a6926fd 100644 (file)
@@ -195,7 +195,7 @@ public:
     void visitChildren(SlotVisitor&);
     void finalizeUnconditionally(VM&);
 
-    void notifyLexicalBindingUpdate();
+    void notifyLexicalBindingShadowing(VM&, const IdentifierSet&);
 
     void dumpSource();
     void dumpSource(PrintStream&);
index 78ca65f..92e80d6 100644 (file)
@@ -6182,10 +6182,9 @@ void ByteCodeParser::parseBlock(unsigned limit)
             // https://bugs.webkit.org/show_bug.cgi?id=193347
             if (m_inlineStackTop->m_codeBlock->scriptMode() != JSParserScriptMode::Module) {
                 if (resolveType == GlobalProperty || resolveType == GlobalPropertyWithVarInjectionChecks) {
-                    JSGlobalObject* globalObject = m_inlineStackTop->m_codeBlock->globalObject();
                     unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[bytecode.m_var];
-                    if (!m_graph.watchGlobalProperty(globalObject, identifierNumber))
-                        addToGraph(ForceOSRExit);
+                    JSGlobalObject* globalObject = m_inlineStackTop->m_codeBlock->globalObject();
+                    m_graph.globalProperties().addLazily(DesiredGlobalProperty(globalObject, identifierNumber));
                 }
             }
 
@@ -6297,10 +6296,8 @@ void ByteCodeParser::parseBlock(unsigned limit)
             case GlobalPropertyWithVarInjectionChecks: {
                 // FIXME: Currently, module code do not query to JSGlobalLexicalEnvironment. So this case should be removed once it is fixed.
                 // https://bugs.webkit.org/show_bug.cgi?id=193347
-                if (m_inlineStackTop->m_codeBlock->scriptMode() != JSParserScriptMode::Module) {
-                    if (!m_graph.watchGlobalProperty(globalObject, identifierNumber))
-                        addToGraph(ForceOSRExit);
-                }
+                if (m_inlineStackTop->m_codeBlock->scriptMode() != JSParserScriptMode::Module)
+                    m_graph.globalProperties().addLazily(DesiredGlobalProperty(globalObject, identifierNumber));
 
                 SpeculatedType prediction = getPrediction();
 
@@ -6474,10 +6471,8 @@ void ByteCodeParser::parseBlock(unsigned limit)
             case GlobalPropertyWithVarInjectionChecks: {
                 // FIXME: Currently, module code do not query to JSGlobalLexicalEnvironment. So this case should be removed once it is fixed.
                 // https://bugs.webkit.org/show_bug.cgi?id=193347
-                if (m_inlineStackTop->m_codeBlock->scriptMode() != JSParserScriptMode::Module) {
-                    if (!m_graph.watchGlobalProperty(globalObject, identifierNumber))
-                        addToGraph(ForceOSRExit);
-                }
+                if (m_inlineStackTop->m_codeBlock->scriptMode() != JSParserScriptMode::Module)
+                    m_graph.globalProperties().addLazily(DesiredGlobalProperty(globalObject, identifierNumber));
 
                 PutByIdStatus status;
                 if (uid)
index ba6841d..8f7b9ce 100644 (file)
 
 namespace JSC { namespace DFG {
 
-bool DesiredGlobalProperties::isStillValidOnMainThread(VM& vm, DesiredIdentifiers& identifiers)
+bool DesiredGlobalProperties::isStillValidOnMainThread(DesiredIdentifiers& identifiers)
 {
-    bool isStillValid = true;
     for (const auto& property : m_set) {
         auto* uid = identifiers.at(property.identifierNumber());
-        JSGlobalObject* globalObject = property.globalObject();
-        {
-            SymbolTable* symbolTable = globalObject->globalLexicalEnvironment()->symbolTable();
-            ConcurrentJSLocker locker(symbolTable->m_lock);
-            if (!symbolTable->contains(locker, uid))
-                continue;
+        if (auto* watchpointSet = property.globalObject()->getReferencedPropertyWatchpointSet(uid)) {
+            if (!watchpointSet->isStillValid())
+                return false;
         }
-        // Set invalidated WatchpointSet here to prevent further compile-and-fail loop.
-        property.globalObject()->ensureReferencedPropertyWatchpointSet(uid).fireAll(vm, "Lexical binding shadows an existing global property");
-        isStillValid = false;
     }
-    return isStillValid;
+    return true;
 }
 
 void DesiredGlobalProperties::reallyAdd(CodeBlock* codeBlock, DesiredIdentifiers& identifiers, CommonData& common)
index 69bd36d..e340a59 100644 (file)
@@ -47,7 +47,7 @@ public:
         m_set.add(WTFMove(property));
     }
 
-    bool isStillValidOnMainThread(VM&, DesiredIdentifiers&);
+    bool isStillValidOnMainThread(DesiredIdentifiers&);
 
     void reallyAdd(CodeBlock*, DesiredIdentifiers&, CommonData&);
 
index 5a60afb..83cc1d4 100644 (file)
@@ -1058,20 +1058,6 @@ bool Graph::isSafeToLoad(JSObject* base, PropertyOffset offset)
     return m_safeToLoad.contains(std::make_pair(base, offset));
 }
 
-bool Graph::watchGlobalProperty(JSGlobalObject* globalObject, unsigned identifierNumber)
-{
-    UniquedStringImpl* uid = identifiers()[identifierNumber];
-    // If we already have a WatchpointSet, and it is already invalidated, it means that this scope operation must be changed from GlobalProperty to GlobalLexicalVar,
-    // but we still have stale metadata here since we have not yet executed this bytecode operation since the invalidation. Just emitting ForceOSRExit to update the
-    // metadata when it reaches to this code.
-    if (auto* watchpoint = globalObject->getReferencedPropertyWatchpointSet(uid)) {
-        if (!watchpoint->isStillValid())
-            return false;
-    }
-    globalProperties().addLazily(DesiredGlobalProperty(globalObject, identifierNumber));
-    return true;
-}
-
 FullBytecodeLiveness& Graph::livenessFor(CodeBlock* codeBlock)
 {
     HashMap<CodeBlock*, std::unique_ptr<FullBytecodeLiveness>>::iterator iter = m_bytecodeLiveness.find(codeBlock);
index 151f573..ee2e267 100644 (file)
@@ -793,8 +793,6 @@ public:
     bool watchCondition(const ObjectPropertyCondition&);
     bool watchConditions(const ObjectPropertyConditionSet&);
 
-    bool watchGlobalProperty(JSGlobalObject*, unsigned identifierNumber);
-
     // Checks if it's known that loading from the given object at the given offset is fine. This is
     // computed by tracking which conditions we track with watchCondition().
     bool isSafeToLoad(JSObject* base, PropertyOffset);
index c5e899b..e77723f 100644 (file)
@@ -573,7 +573,7 @@ void Plan::notifyReady()
 
 bool Plan::isStillValidOnMainThread()
 {
-    return m_globalProperties.isStillValidOnMainThread(*m_vm, m_identifiers);
+    return m_globalProperties.isStillValidOnMainThread(m_identifiers);
 }
 
 CompilationResult Plan::finalizeWithoutNotifyingCallback()
index 2f4f32e..92f37ec 100644 (file)
@@ -766,17 +766,7 @@ void JIT::emit_op_resolve_scope(const Instruction* currentInstruction)
     auto emitCode = [&] (ResolveType resolveType) {
         switch (resolveType) {
         case GlobalProperty:
-        case GlobalPropertyWithVarInjectionChecks: {
-            JSScope* constantScope = JSScope::constantScopeForCodeBlock(resolveType, m_codeBlock);
-            RELEASE_ASSERT(constantScope);
-            emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
-            load32(&metadata.m_globalLexicalBindingEpoch, regT1);
-            addSlowCase(branch32(NotEqual, AbsoluteAddress(m_codeBlock->globalObject()->addressOfGlobalLexicalBindingEpoch()), regT1));
-            move(TrustedImmPtr(constantScope), regT0);
-            emitPutVirtualRegister(dst);
-            break;
-        }
-
+        case GlobalPropertyWithVarInjectionChecks:
         case GlobalVar:
         case GlobalVarWithVarInjectionChecks:
         case GlobalLexicalVar:
@@ -809,17 +799,11 @@ void JIT::emit_op_resolve_scope(const Instruction* currentInstruction)
     switch (resolveType) {
     case GlobalProperty:
     case GlobalPropertyWithVarInjectionChecks: {
-        JumpList skipToEnd;
-        load32(&metadata.m_resolveType, regT0);
-
-        Jump notGlobalProperty = branch32(NotEqual, regT0, TrustedImm32(resolveType));
-        emitCode(resolveType);
-        skipToEnd.append(jump());
-
-        notGlobalProperty.link(this);
-        emitCode(needsVarInjectionChecks(resolveType) ? GlobalLexicalVarWithVarInjectionChecks : GlobalLexicalVar);
-
-        skipToEnd.link(this);
+        // Since these GlobalProperty can be changed to GlobalLexicalVar, we should load the value from metadata.
+        JSScope** constantScopeSlot = metadata.m_constantScope.slot();
+        emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
+        loadPtr(constantScopeSlot, regT0);
+        emitPutVirtualRegister(dst);
         break;
     }
     case UnresolvedProperty:
index e2da115..33d6ae4 100644 (file)
@@ -769,18 +769,7 @@ void JIT::emit_op_resolve_scope(const Instruction* currentInstruction)
     auto emitCode = [&] (ResolveType resolveType) {
         switch (resolveType) {
         case GlobalProperty:
-        case GlobalPropertyWithVarInjectionChecks: {
-            JSScope* constantScope = JSScope::constantScopeForCodeBlock(resolveType, m_codeBlock);
-            RELEASE_ASSERT(constantScope);
-            emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
-            load32(&metadata.m_globalLexicalBindingEpoch, regT1);
-            addSlowCase(branch32(NotEqual, AbsoluteAddress(m_codeBlock->globalObject()->addressOfGlobalLexicalBindingEpoch()), regT1));
-            move(TrustedImm32(JSValue::CellTag), regT1);
-            move(TrustedImmPtr(constantScope), regT0);
-            emitStore(dst, regT1, regT0);
-            break;
-        }
-
+        case GlobalPropertyWithVarInjectionChecks:
         case GlobalVar:
         case GlobalVarWithVarInjectionChecks: 
         case GlobalLexicalVar:
@@ -814,17 +803,12 @@ void JIT::emit_op_resolve_scope(const Instruction* currentInstruction)
     switch (resolveType) {
     case GlobalProperty:
     case GlobalPropertyWithVarInjectionChecks: {
-        JumpList skipToEnd;
-        load32(&metadata.m_resolveType, regT0);
-
-        Jump notGlobalProperty = branch32(NotEqual, regT0, TrustedImm32(resolveType));
-        emitCode(resolveType);
-        skipToEnd.append(jump());
-
-        notGlobalProperty.link(this);
-        emitCode(needsVarInjectionChecks(resolveType) ? GlobalLexicalVarWithVarInjectionChecks : GlobalLexicalVar);
-
-        skipToEnd.link(this);
+        // Since these GlobalProperty can be changed to GlobalLexicalVar, we should load the value from metadata.
+        JSScope** constantScopeSlot = metadata.m_constantScope.slot();
+        emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
+        move(TrustedImm32(JSValue::CellTag), regT1);
+        loadPtr(constantScopeSlot, regT0);
+        emitStore(dst, regT1, regT0);
         break;
     }
     case UnresolvedProperty:
index c443b48..6f7deab 100644 (file)
@@ -2092,20 +2092,11 @@ end
 
 llintOpWithMetadata(op_resolve_scope, OpResolveScope, macro (size, get, dispatch, metadata, return)
 
-    macro getConstantScope(dst)
-        loadp OpResolveScope::Metadata::m_constantScope[t5], dst
-    end
-
-    macro returnConstantScope()
-        getConstantScope(t0)
+    macro getConstantScope()
+        loadp OpResolveScope::Metadata::m_constantScope[t5],  t0
         return(CellTag, t0)
     end
 
-    macro globalLexicalBindingEpochCheck(slowPath, globalObject, scratch)
-        loadi OpResolveScope::Metadata::m_globalLexicalBindingEpoch[globalObject], scratch
-        bineq JSGlobalObject::m_globalLexicalBindingEpoch[globalObject], scratch, slowPath
-    end
-
     macro resolveScope()
         loadi OpResolveScope::Metadata::m_localScopeDepth[t5], t2
         get(m_scope, t0)
@@ -2126,17 +2117,15 @@ llintOpWithMetadata(op_resolve_scope, OpResolveScope, macro (size, get, dispatch
 
 #rGlobalProperty:
     bineq t0, GlobalProperty, .rGlobalVar
-    getConstantScope(t0)
-    globalLexicalBindingEpochCheck(.rDynamic, t0, t2)
-    return(CellTag, t0)
+    getConstantScope()
 
 .rGlobalVar:
     bineq t0, GlobalVar, .rGlobalLexicalVar
-    returnConstantScope()
+    getConstantScope()
 
 .rGlobalLexicalVar:
     bineq t0, GlobalLexicalVar, .rClosureVar
-    returnConstantScope()
+    getConstantScope()
 
 .rClosureVar:
     bineq t0, ClosureVar, .rModuleVar
@@ -2144,24 +2133,22 @@ llintOpWithMetadata(op_resolve_scope, OpResolveScope, macro (size, get, dispatch
 
 .rModuleVar:
     bineq t0, ModuleVar, .rGlobalPropertyWithVarInjectionChecks
-    returnConstantScope()
+    getConstantScope()
 
 .rGlobalPropertyWithVarInjectionChecks:
     bineq t0, GlobalPropertyWithVarInjectionChecks, .rGlobalVarWithVarInjectionChecks
     varInjectionCheck(.rDynamic)
-    getConstantScope(t0)
-    globalLexicalBindingEpochCheck(.rDynamic, t0, t2)
-    return(CellTag, t0)
+    getConstantScope()
 
 .rGlobalVarWithVarInjectionChecks:
     bineq t0, GlobalVarWithVarInjectionChecks, .rGlobalLexicalVarWithVarInjectionChecks
     varInjectionCheck(.rDynamic)
-    returnConstantScope()
+    getConstantScope()
 
 .rGlobalLexicalVarWithVarInjectionChecks:
     bineq t0, GlobalLexicalVarWithVarInjectionChecks, .rClosureVarWithVarInjectionChecks
     varInjectionCheck(.rDynamic)
-    returnConstantScope()
+    getConstantScope()
 
 .rClosureVarWithVarInjectionChecks:
     bineq t0, ClosureVarWithVarInjectionChecks, .rDynamic
index bd7d02c..4e37a09 100644 (file)
@@ -2150,20 +2150,11 @@ end
 llintOpWithMetadata(op_resolve_scope, OpResolveScope, macro (size, get, dispatch, metadata, return)
     metadata(t5, t0)
 
-    macro getConstantScope(dst)
-        loadp OpResolveScope::Metadata::m_constantScope[t5], dst
-    end
-
-    macro returnConstantScope()
-        getConstantScope(t0)
+    macro getConstantScope()
+        loadp OpResolveScope::Metadata::m_constantScope[t5],  t0
         return(t0)
     end
 
-    macro globalLexicalBindingEpochCheck(slowPath, globalObject, scratch)
-        loadi OpResolveScope::Metadata::m_globalLexicalBindingEpoch[globalObject], scratch
-        bineq JSGlobalObject::m_globalLexicalBindingEpoch[globalObject], scratch, slowPath
-    end
-
     macro resolveScope()
         loadi OpResolveScope::Metadata::m_localScopeDepth[t5], t2
         get(m_scope, t0)
@@ -2183,17 +2174,15 @@ llintOpWithMetadata(op_resolve_scope, OpResolveScope, macro (size, get, dispatch
 
 #rGlobalProperty:
     bineq t0, GlobalProperty, .rGlobalVar
-    getConstantScope(t0)
-    globalLexicalBindingEpochCheck(.rDynamic, t0, t2)
-    return(t0)
+    getConstantScope()
 
 .rGlobalVar:
     bineq t0, GlobalVar, .rGlobalLexicalVar
-    returnConstantScope()
+    getConstantScope()
 
 .rGlobalLexicalVar:
     bineq t0, GlobalLexicalVar, .rClosureVar
-    returnConstantScope()
+    getConstantScope()
 
 .rClosureVar:
     bineq t0, ClosureVar, .rModuleVar
@@ -2201,24 +2190,22 @@ llintOpWithMetadata(op_resolve_scope, OpResolveScope, macro (size, get, dispatch
 
 .rModuleVar:
     bineq t0, ModuleVar, .rGlobalPropertyWithVarInjectionChecks
-    returnConstantScope()
+    getConstantScope()
 
 .rGlobalPropertyWithVarInjectionChecks:
     bineq t0, GlobalPropertyWithVarInjectionChecks, .rGlobalVarWithVarInjectionChecks
     varInjectionCheck(.rDynamic, t2)
-    getConstantScope(t0)
-    globalLexicalBindingEpochCheck(.rDynamic, t0, t2)
-    return(t0)
+    getConstantScope()
 
 .rGlobalVarWithVarInjectionChecks:
     bineq t0, GlobalVarWithVarInjectionChecks, .rGlobalLexicalVarWithVarInjectionChecks
     varInjectionCheck(.rDynamic, t2)
-    returnConstantScope()
+    getConstantScope()
 
 .rGlobalLexicalVarWithVarInjectionChecks:
     bineq t0, GlobalLexicalVarWithVarInjectionChecks, .rClosureVarWithVarInjectionChecks
     varInjectionCheck(.rDynamic, t2)
-    returnConstantScope()
+    getConstantScope()
 
 .rClosureVarWithVarInjectionChecks:
     bineq t0, ClosureVarWithVarInjectionChecks, .rDynamic
@@ -2269,7 +2256,7 @@ llintOpWithMetadata(op_get_from_scope, OpGetFromScope, macro (size, get, dispatc
 
 #gGlobalProperty:
     bineq t0, GlobalProperty, .gGlobalVar
-    loadWithStructureCheck(OpGetFromScope, get, .gDynamic) # This structure check includes lexical binding epoch check since when the epoch is changed, scope will be changed too.
+    loadWithStructureCheck(OpGetFromScope, get, .gDynamic)
     getProperty()
 
 .gGlobalVar:
@@ -2290,7 +2277,7 @@ llintOpWithMetadata(op_get_from_scope, OpGetFromScope, macro (size, get, dispatc
 
 .gGlobalPropertyWithVarInjectionChecks:
     bineq t0, GlobalPropertyWithVarInjectionChecks, .gGlobalVarWithVarInjectionChecks
-    loadWithStructureCheck(OpGetFromScope, get, .gDynamic) # This structure check includes lexical binding epoch check since when the epoch is changed, scope will be changed too.
+    loadWithStructureCheck(OpGetFromScope, get, .gDynamic)
     getProperty()
 
 .gGlobalVarWithVarInjectionChecks:
@@ -2377,7 +2364,7 @@ llintOpWithMetadata(op_put_to_scope, OpPutToScope, macro (size, get, dispatch, m
 
 .pGlobalProperty:
     bineq t0, GlobalProperty, .pGlobalVar
-    loadWithStructureCheck(OpPutToScope, get, .pDynamic) # This structure check includes lexical binding epoch check since when the epoch is changed, scope will be changed too.
+    loadWithStructureCheck(OpPutToScope, get, .pDynamic)
     putProperty()
     writeBarrierOnOperands(size, get, m_scope, m_value)
     dispatch()
@@ -2404,7 +2391,7 @@ llintOpWithMetadata(op_put_to_scope, OpPutToScope, macro (size, get, dispatch, m
 
 .pGlobalPropertyWithVarInjectionChecks:
     bineq t0, GlobalPropertyWithVarInjectionChecks, .pGlobalVarWithVarInjectionChecks
-    loadWithStructureCheck(OpPutToScope, get, .pDynamic) # This structure check includes lexical binding epoch check since when the epoch is changed, scope will be changed too.
+    loadWithStructureCheck(OpPutToScope, get, .pDynamic)
     putProperty()
     writeBarrierOnOperands(size, get, m_scope, m_value)
     dispatch()
index bbbadab..b880458 100644 (file)
@@ -1067,31 +1067,29 @@ SLOW_PATH_DECL(slow_path_resolve_scope)
     // ModuleVar does not keep the scope register value alive in DFG.
     ASSERT(resolveType != ModuleVar);
 
-    switch (resolveType) {
-    case GlobalProperty:
-    case GlobalPropertyWithVarInjectionChecks:
-    case UnresolvedProperty:
-    case UnresolvedPropertyWithVarInjectionChecks: {
+    if (resolveType == UnresolvedProperty || resolveType == UnresolvedPropertyWithVarInjectionChecks) {
         if (resolvedScope->isGlobalObject()) {
             JSGlobalObject* globalObject = jsCast<JSGlobalObject*>(resolvedScope);
             bool hasProperty = globalObject->hasProperty(exec, ident);
             CHECK_EXCEPTION();
             if (hasProperty) {
                 ConcurrentJSLocker locker(exec->codeBlock()->m_lock);
-                metadata.m_resolveType = needsVarInjectionChecks(resolveType) ? GlobalPropertyWithVarInjectionChecks : GlobalProperty;
+                if (resolveType == UnresolvedProperty)
+                    metadata.m_resolveType = GlobalProperty;
+                else
+                    metadata.m_resolveType = GlobalPropertyWithVarInjectionChecks;
+
                 metadata.m_globalObject = globalObject;
-                metadata.m_globalLexicalBindingEpoch = globalObject->globalLexicalBindingEpoch();
             }
         } else if (resolvedScope->isGlobalLexicalEnvironment()) {
             JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsCast<JSGlobalLexicalEnvironment*>(resolvedScope);
             ConcurrentJSLocker locker(exec->codeBlock()->m_lock);
-            metadata.m_resolveType = needsVarInjectionChecks(resolveType) ? GlobalLexicalVarWithVarInjectionChecks : GlobalLexicalVar;
+            if (resolveType == UnresolvedProperty)
+                metadata.m_resolveType = GlobalLexicalVar;
+            else
+                metadata.m_resolveType = GlobalLexicalVarWithVarInjectionChecks;
             metadata.m_globalLexicalEnvironment = globalLexicalEnvironment;
         }
-        break;
-    }
-    default:
-        break;
     }
 
     RETURN(resolvedScope);
index 7eeaf70..130a0c8 100644 (file)
@@ -124,39 +124,28 @@ inline void tryCachePutToScopeGlobal(
     // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
     auto& metadata = bytecode.metadata(exec);
     ResolveType resolveType = metadata.m_getPutInfo.resolveType();
+    if (resolveType != GlobalProperty && resolveType != GlobalPropertyWithVarInjectionChecks 
+        && resolveType != UnresolvedProperty && resolveType != UnresolvedPropertyWithVarInjectionChecks)
+        return;
 
-    switch (resolveType) {
-    case UnresolvedProperty:
-    case UnresolvedPropertyWithVarInjectionChecks: {
+    if (resolveType == UnresolvedProperty || resolveType == UnresolvedPropertyWithVarInjectionChecks) {
         if (scope->isGlobalObject()) {
-            ResolveType newResolveType = needsVarInjectionChecks(resolveType) ? GlobalPropertyWithVarInjectionChecks : GlobalProperty;
-            resolveType = newResolveType; // Allow below caching mechanism to kick in.
+            ResolveType newResolveType = resolveType == UnresolvedProperty ? GlobalProperty : GlobalPropertyWithVarInjectionChecks;
+            resolveType = newResolveType;
             ConcurrentJSLocker locker(codeBlock->m_lock);
             metadata.m_getPutInfo = GetPutInfo(metadata.m_getPutInfo.resolveMode(), newResolveType, metadata.m_getPutInfo.initializationMode());
-            break;
-        }
-        FALLTHROUGH;
-    }
-    case GlobalProperty:
-    case GlobalPropertyWithVarInjectionChecks: {
-         // Global Lexical Binding Epoch is changed. Update op_get_from_scope from GlobalProperty to GlobalLexicalVar.
-        if (scope->isGlobalLexicalEnvironment()) {
+        } else if (scope->isGlobalLexicalEnvironment()) {
             JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsCast<JSGlobalLexicalEnvironment*>(scope);
-            ResolveType newResolveType = needsVarInjectionChecks(resolveType) ? GlobalLexicalVarWithVarInjectionChecks : GlobalLexicalVar;
+            ResolveType newResolveType = resolveType == UnresolvedProperty ? GlobalLexicalVar : GlobalLexicalVarWithVarInjectionChecks;
             metadata.m_getPutInfo = GetPutInfo(metadata.m_getPutInfo.resolveMode(), newResolveType, metadata.m_getPutInfo.initializationMode());
             SymbolTableEntry entry = globalLexicalEnvironment->symbolTable()->get(ident.impl());
             ASSERT(!entry.isNull());
             ConcurrentJSLocker locker(codeBlock->m_lock);
             metadata.m_watchpointSet = entry.watchpointSet();
             metadata.m_operand = reinterpret_cast<uintptr_t>(globalLexicalEnvironment->variableAt(entry.scopeOffset()).slot());
-            return;
         }
-        break;
-    }
-    default:
-        return;
     }
-
+    
     if (resolveType == GlobalProperty || resolveType == GlobalPropertyWithVarInjectionChecks) {
         VM& vm = exec->vm();
         JSGlobalObject* globalObject = codeBlock->globalObject();
@@ -187,36 +176,22 @@ inline void tryCacheGetFromScopeGlobal(
     auto& metadata = bytecode.metadata(exec);
     ResolveType resolveType = metadata.m_getPutInfo.resolveType();
 
-    switch (resolveType) {
-    case UnresolvedProperty:
-    case UnresolvedPropertyWithVarInjectionChecks: {
+    if (resolveType == UnresolvedProperty || resolveType == UnresolvedPropertyWithVarInjectionChecks) {
         if (scope->isGlobalObject()) {
-            ResolveType newResolveType = needsVarInjectionChecks(resolveType) ? GlobalPropertyWithVarInjectionChecks : GlobalProperty;
+            ResolveType newResolveType = resolveType == UnresolvedProperty ? GlobalProperty : GlobalPropertyWithVarInjectionChecks;
             resolveType = newResolveType; // Allow below caching mechanism to kick in.
             ConcurrentJSLocker locker(exec->codeBlock()->m_lock);
             metadata.m_getPutInfo = GetPutInfo(metadata.m_getPutInfo.resolveMode(), newResolveType, metadata.m_getPutInfo.initializationMode());
-            break;
-        }
-        FALLTHROUGH;
-    }
-    case GlobalProperty:
-    case GlobalPropertyWithVarInjectionChecks: {
-         // Global Lexical Binding Epoch is changed. Update op_get_from_scope from GlobalProperty to GlobalLexicalVar.
-        if (scope->isGlobalLexicalEnvironment()) {
+        } else if (scope->isGlobalLexicalEnvironment()) {
             JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsCast<JSGlobalLexicalEnvironment*>(scope);
-            ResolveType newResolveType = needsVarInjectionChecks(resolveType) ? GlobalLexicalVarWithVarInjectionChecks : GlobalLexicalVar;
+            ResolveType newResolveType = resolveType == UnresolvedProperty ? GlobalLexicalVar : GlobalLexicalVarWithVarInjectionChecks;
             SymbolTableEntry entry = globalLexicalEnvironment->symbolTable()->get(ident.impl());
             ASSERT(!entry.isNull());
             ConcurrentJSLocker locker(exec->codeBlock()->m_lock);
             metadata.m_getPutInfo = GetPutInfo(metadata.m_getPutInfo.resolveMode(), newResolveType, metadata.m_getPutInfo.initializationMode());
             metadata.m_watchpointSet = entry.watchpointSet();
             metadata.m_operand = reinterpret_cast<uintptr_t>(globalLexicalEnvironment->variableAt(entry.scopeOffset()).slot());
-            return;
         }
-        break;
-    }
-    default:
-        return;
     }
 
     // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
index 1a61f9d..3b02753 100644 (file)
@@ -1857,17 +1857,20 @@ const HashSet<String>& JSGlobalObject::intlPluralRulesAvailableLocales()
 }
 #endif // ENABLE(INTL)
 
-void JSGlobalObject::bumpGlobalLexicalBindingEpoch(VM& vm)
+void JSGlobalObject::notifyLexicalBindingShadowing(VM& vm, const IdentifierSet& set)
 {
-    if (++m_globalLexicalBindingEpoch == Options::thresholdForGlobalLexicalBindingEpoch()) {
-        // Since the epoch overflows, we should rewrite all the CodeBlock to adjust to the newly started generation.
-        m_globalLexicalBindingEpoch = 1;
-        vm.heap.codeBlockSet().iterate([&] (CodeBlock* codeBlock) {
-            if (codeBlock->globalObject() != this)
-                return;
-            codeBlock->notifyLexicalBindingUpdate();
-        });
-    }
+    auto scope = DECLARE_THROW_SCOPE(vm);
+#if ENABLE(DFG_JIT)
+    for (const auto& key : set)
+        ensureReferencedPropertyWatchpointSet(key.get()).fireAll(vm, "Lexical binding shadows the existing global properties");
+#endif
+    vm.heap.codeBlockSet().iterate([&] (CodeBlock* codeBlock) {
+        if (codeBlock->globalObject() != this)
+            return;
+        codeBlock->notifyLexicalBindingShadowing(vm, set);
+        scope.assertNoException();
+    });
+    scope.release();
 }
 
 void JSGlobalObject::queueMicrotask(Ref<Microtask>&& task)
@@ -1893,13 +1896,11 @@ bool JSGlobalObject::hasInteractiveDebugger() const
 #if ENABLE(DFG_JIT)
 WatchpointSet* JSGlobalObject::getReferencedPropertyWatchpointSet(UniquedStringImpl* uid)
 {
-    ConcurrentJSLocker locker(m_referencedGlobalPropertyWatchpointSetsLock);
     return m_referencedGlobalPropertyWatchpointSets.get(uid);
 }
 
 WatchpointSet& JSGlobalObject::ensureReferencedPropertyWatchpointSet(UniquedStringImpl* uid)
 {
-    ConcurrentJSLocker locker(m_referencedGlobalPropertyWatchpointSetsLock);
     return m_referencedGlobalPropertyWatchpointSets.ensure(uid, [] {
         return WatchpointSet::create(IsWatched);
     }).iterator->value.get();
index b1d96ad..0cacb76 100644 (file)
@@ -486,12 +486,10 @@ public:
 #if ENABLE(DFG_JIT)
     using ReferencedGlobalPropertyWatchpointSets = HashMap<RefPtr<UniquedStringImpl>, Ref<WatchpointSet>, IdentifierRepHash>;
     ReferencedGlobalPropertyWatchpointSets m_referencedGlobalPropertyWatchpointSets;
-    ConcurrentJSLock m_referencedGlobalPropertyWatchpointSetsLock;
 #endif
 
     bool m_evalEnabled { true };
     bool m_webAssemblyEnabled { true };
-    unsigned m_globalLexicalBindingEpoch { 1 };
     String m_evalDisabledErrorMessage;
     String m_webAssemblyDisabledErrorMessage;
     RuntimeFlags m_runtimeFlags;
@@ -753,10 +751,7 @@ public:
     const HashSet<String>& intlPluralRulesAvailableLocales();
 #endif // ENABLE(INTL)
 
-    void bumpGlobalLexicalBindingEpoch(VM&);
-    unsigned globalLexicalBindingEpoch() const { return m_globalLexicalBindingEpoch; }
-    static ptrdiff_t globalLexicalBindingEpochOffset() { return OBJECT_OFFSETOF(JSGlobalObject, m_globalLexicalBindingEpoch); }
-    unsigned* addressOfGlobalLexicalBindingEpoch() { return &m_globalLexicalBindingEpoch; }
+    void notifyLexicalBindingShadowing(VM&, const IdentifierSet&);
 
     void setConsoleClient(ConsoleClient* consoleClient) { m_consoleClient = consoleClient; }
     ConsoleClient* consoleClient() const { return m_consoleClient; }
index 9fc34fb..66cec3a 100644 (file)
@@ -376,13 +376,6 @@ static void overrideDefaults()
 #endif
 }
 
-static void correctOptions()
-{
-    unsigned thresholdForGlobalLexicalBindingEpoch = Options::thresholdForGlobalLexicalBindingEpoch();
-    if (thresholdForGlobalLexicalBindingEpoch == 0 || thresholdForGlobalLexicalBindingEpoch == 1)
-        Options::thresholdForGlobalLexicalBindingEpoch() = UINT_MAX;
-}
-
 static void recomputeDependentOptions()
 {
 #if !defined(NDEBUG)
@@ -573,8 +566,6 @@ void Options::initialize()
 #if 0
                 ; // Deconfuse editors that do auto indentation
 #endif
-
-            correctOptions();
     
             recomputeDependentOptions();
 
@@ -708,8 +699,6 @@ bool Options::setOptions(const char* optionsStr)
         }
     }
 
-    correctOptions();
-
     recomputeDependentOptions();
 
     dumpOptionsIfNeeded();
@@ -746,7 +735,6 @@ bool Options::setOptionWithoutAlias(const char* arg)
         bool success = parse(valueStr, value);                     \
         if (success) {                                             \
             name_() = value;                                       \
-            correctOptions();                                      \
             recomputeDependentOptions();                           \
             return true;                                           \
         }                                                          \
index 4c9f6b6..48f6e62 100644 (file)
@@ -508,7 +508,8 @@ constexpr bool enableWebAssemblyStreamingApi = false;
     v(bool, traceLLIntExecution, false, Configurable, nullptr) \
     v(bool, traceLLIntSlowPath, false, Configurable, nullptr) \
     v(bool, traceBaselineJITExecution, false, Normal, nullptr) \
-    v(unsigned, thresholdForGlobalLexicalBindingEpoch, UINT_MAX, Normal, "Threshold for global lexical binding epoch. If the epoch reaches to this value, CodeBlock metadata for scope operations will be revised globally. It needs to be greater than 1.") \
+    v(optionString, diskCachePath, nullptr, Restricted, "") \
+    v(bool, forceDiskCache, false, Restricted, "") \
 
 
 enum OptionEquivalence {
index 1a3f092..1c21967 100644 (file)
@@ -107,6 +107,7 @@ JSObject* ProgramExecutable::initializeGlobalProperties(VM& vm, CallFrame* callF
     JSGlobalLexicalEnvironment* globalLexicalEnvironment = globalObject->globalLexicalEnvironment();
     const VariableEnvironment& variableDeclarations = unlinkedCodeBlock->variableDeclarations();
     const VariableEnvironment& lexicalDeclarations = unlinkedCodeBlock->lexicalDeclarations();
+    IdentifierSet shadowedProperties;
     // The ES6 spec says that no vars/global properties/let/const can be duplicated in the global scope.
     // This carried out section 15.1.8 of the ES6 spec: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-globaldeclarationinstantiation
     {
@@ -130,9 +131,11 @@ JSObject* ProgramExecutable::initializeGlobalProperties(VM& vm, CallFrame* callF
                 // Lexical bindings can shadow global properties if the given property's attribute is configurable.
                 // https://tc39.github.io/ecma262/#sec-globaldeclarationinstantiation step 5-c, `hasRestrictedGlobal` becomes false
                 // However we may emit GlobalProperty look up in bytecodes already and it may cache the value for the global scope.
-                // To make it invalid,
-                // 1. In LLInt and Baseline, we bump the global lexical binding epoch and it works.
+                // To make it invalid, we iterate all the CodeBlocks and rewrite the instruction to convert GlobalProperty to GlobalLexicalVar.
+                // 1. In LLInt, we always check metadata's resolveType. So rewritten instruction just works.
+                // 2. In Baseline JIT, we check metadata's resolveType in GlobalProperty case so that we can notice once it is changed.
                 // 3. In DFG and FTL, we watch the watchpoint and jettison once it is fired.
+                shadowedProperties.add(entry.key.get());
                 break;
             case GlobalPropertyLookUpStatus::NotFound:
                 break;
@@ -203,18 +206,12 @@ JSObject* ProgramExecutable::initializeGlobalProperties(VM& vm, CallFrame* callF
             RELEASE_ASSERT(offsetForAssert == offset);
         }
     }
-    if (lexicalDeclarations.size()) {
-#if ENABLE(DFG_JIT)
-        for (auto& entry : lexicalDeclarations) {
-            // If WatchpointSet exists, just fire it. Since DFG WatchpointSet addition is also done on the main thread, we can sync them.
-            // So that we do not create WatchpointSet here. DFG will create if necessary on the main thread.
-            // And it will only create not-invalidated watchpoint set if the global lexical environment binding doesn't exist, which is why this code works.
-            if (auto* watchpointSet = globalObject->getReferencedPropertyWatchpointSet(entry.key.get()))
-                watchpointSet->fireAll(vm, "Lexical binding shadows an existing global property");
-        }
-#endif
-        globalObject->bumpGlobalLexicalBindingEpoch(vm);
+
+    if (!shadowedProperties.isEmpty()) {
+        globalObject->notifyLexicalBindingShadowing(vm, WTFMove(shadowedProperties));
+        throwScope.assertNoException();
     }
+
     return nullptr;
 }