Title: [249668] trunk
Revision
249668
Author
ysuz...@apple.com
Date
2019-09-09 14:38:17 -0700 (Mon, 09 Sep 2019)

Log Message

[JSC] Use metadata table to iterate specific bytecode metadata instead of propertyAccessInstructions vector
https://bugs.webkit.org/show_bug.cgi?id=201613

Reviewed by Mark Lam.

We do not need to maintain propertyAccessInstructions vector to access metadata tied to a specific bytecode opcode
since we have MetadataTable::forEach<Op> feature. This removes propertyAccessInstructions entirely, and fixes the
issue that `op_create_promise` missed propertyAccessInstructions registration (a name "propertyAccessInstructions" is
misleading, it is like "instructions-requires-llint-finalize").

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::propagateTransitions):
(JSC::CodeBlock::finalizeLLIntInlineCaches):
* bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedCodeBlock::applyModification):
(JSC::UnlinkedCodeBlock::shrinkToFit):
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedCodeBlock::addPropertyAccessInstruction): Deleted.
(JSC::UnlinkedCodeBlock::numberOfPropertyAccessInstructions const): Deleted.
(JSC::UnlinkedCodeBlock::propertyAccessInstructions const): Deleted.
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitResolveScope):
(JSC::BytecodeGenerator::emitGetFromScope):
(JSC::BytecodeGenerator::emitPutToScope):
(JSC::BytecodeGenerator::emitGetById):
(JSC::BytecodeGenerator::emitDirectGetById):
(JSC::BytecodeGenerator::emitPutById):
(JSC::BytecodeGenerator::emitDirectPutById):
(JSC::BytecodeGenerator::emitCreateThis):
(JSC::BytecodeGenerator::emitToThis):
* runtime/CachedTypes.cpp:
(JSC::CachedCodeBlock<CodeBlockType>::decode const):
(JSC::CachedCodeBlock<CodeBlockType>::encode):

Modified Paths

Added Paths

Diff

Added: trunk/JSTests/stress/create-promise-finalize.js (0 => 249668)


--- trunk/JSTests/stress/create-promise-finalize.js	                        (rev 0)
+++ trunk/JSTests/stress/create-promise-finalize.js	2019-09-09 21:38:17 UTC (rev 249668)
@@ -0,0 +1,9 @@
+function foo() {
+    class P extends Promise {}
+    new P(()=>{});
+}
+
+foo();
+drainMicrotasks();
+gc();
+foo();

Modified: trunk/Source/_javascript_Core/ChangeLog (249667 => 249668)


--- trunk/Source/_javascript_Core/ChangeLog	2019-09-09 21:20:59 UTC (rev 249667)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-09-09 21:38:17 UTC (rev 249668)
@@ -1,3 +1,39 @@
+2019-09-09  Yusuke Suzuki  <ysuz...@apple.com>
+
+        [JSC] Use metadata table to iterate specific bytecode metadata instead of propertyAccessInstructions vector
+        https://bugs.webkit.org/show_bug.cgi?id=201613
+
+        Reviewed by Mark Lam.
+
+        We do not need to maintain propertyAccessInstructions vector to access metadata tied to a specific bytecode opcode
+        since we have MetadataTable::forEach<Op> feature. This removes propertyAccessInstructions entirely, and fixes the
+        issue that `op_create_promise` missed propertyAccessInstructions registration (a name "propertyAccessInstructions" is
+        misleading, it is like "instructions-requires-llint-finalize").
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::propagateTransitions):
+        (JSC::CodeBlock::finalizeLLIntInlineCaches):
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedCodeBlock::applyModification):
+        (JSC::UnlinkedCodeBlock::shrinkToFit):
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedCodeBlock::addPropertyAccessInstruction): Deleted.
+        (JSC::UnlinkedCodeBlock::numberOfPropertyAccessInstructions const): Deleted.
+        (JSC::UnlinkedCodeBlock::propertyAccessInstructions const): Deleted.
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitResolveScope):
+        (JSC::BytecodeGenerator::emitGetFromScope):
+        (JSC::BytecodeGenerator::emitPutToScope):
+        (JSC::BytecodeGenerator::emitGetById):
+        (JSC::BytecodeGenerator::emitDirectGetById):
+        (JSC::BytecodeGenerator::emitPutById):
+        (JSC::BytecodeGenerator::emitDirectPutById):
+        (JSC::BytecodeGenerator::emitCreateThis):
+        (JSC::BytecodeGenerator::emitToThis):
+        * runtime/CachedTypes.cpp:
+        (JSC::CachedCodeBlock<CodeBlockType>::decode const):
+        (JSC::CachedCodeBlock<CodeBlockType>::encode):
+
 2019-09-07  Keith Miller  <keith_mil...@apple.com>
 
         OSR entry into wasm misses some contexts

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (249667 => 249668)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2019-09-09 21:20:59 UTC (rev 249667)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2019-09-09 21:38:17 UTC (rev 249668)
@@ -1088,16 +1088,12 @@
     VM& vm = *m_vm;
 
     if (jitType() == JITType::InterpreterThunk) {
-        const Vector<InstructionStream::Offset>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions();
-        const InstructionStream& instructionStream = instructions();
-        for (size_t i = 0; i < propertyAccessInstructions.size(); ++i) {
-            auto instruction = instructionStream.at(propertyAccessInstructions[i]);
-            if (instruction->is<OpPutById>()) {
-                auto& metadata = instruction->as<OpPutById>().metadata(this);
+        if (m_metadata) {
+            m_metadata->forEach<OpPutById>([&] (auto& metadata) {
                 StructureID oldStructureID = metadata.m_oldStructureID;
                 StructureID newStructureID = metadata.m_newStructureID;
                 if (!oldStructureID || !newStructureID)
-                    continue;
+                    return;
                 Structure* oldStructure =
                     vm.heap.structureIDTable().get(oldStructureID);
                 Structure* newStructure =
@@ -1104,8 +1100,7 @@
                     vm.heap.structureIDTable().get(newStructureID);
                 if (vm.heap.isMarked(oldStructure))
                     visitor.appendUnbarriered(newStructure);
-                continue;
-            }
+            });
         }
     }
 
@@ -1206,50 +1201,33 @@
 void CodeBlock::finalizeLLIntInlineCaches()
 {
     VM& vm = *m_vm;
-    const Vector<InstructionStream::Offset>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions();
 
-    auto handleGetPutFromScope = [&] (auto& metadata) {
-        GetPutInfo getPutInfo = metadata.m_getPutInfo;
-        if (getPutInfo.resolveType() == GlobalVar || getPutInfo.resolveType() == GlobalVarWithVarInjectionChecks 
-            || getPutInfo.resolveType() == LocalClosureVar || getPutInfo.resolveType() == GlobalLexicalVar || getPutInfo.resolveType() == GlobalLexicalVarWithVarInjectionChecks)
-            return;
-        WriteBarrierBase<Structure>& structure = metadata.m_structure;
-        if (!structure || vm.heap.isMarked(structure.get()))
-            return;
-        if (Options::verboseOSR())
-            dataLogF("Clearing scope access with structure %p.\n", structure.get());
-        structure.clear();
-    };
+    if (m_metadata) {
+        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=166418
+        // We need to add optimizations for op_resolve_scope_for_hoisting_func_decl_in_eval to do link time scope resolution.
 
-    const InstructionStream& instructionStream = instructions();
-    for (size_t size = propertyAccessInstructions.size(), i = 0; i < size; ++i) {
-        const auto curInstruction = instructionStream.at(propertyAccessInstructions[i]);
-        switch (curInstruction->opcodeID()) {
-        case op_get_by_id: {
-            auto& metadata = curInstruction->as<OpGetById>().metadata(this);
+        m_metadata->forEach<OpGetById>([&] (auto& metadata) {
             if (metadata.m_modeMetadata.mode != GetByIdMode::Default)
-                break;
+                return;
             StructureID oldStructureID = metadata.m_modeMetadata.defaultMode.structureID;
             if (!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID)))
-                break;
+                return;
             if (Options::verboseOSR())
                 dataLogF("Clearing LLInt property access.\n");
             LLIntPrototypeLoadAdaptiveStructureWatchpoint::clearLLIntGetByIdCache(metadata);
-            break;
-        }
-        case op_get_by_id_direct: {
-            auto& metadata = curInstruction->as<OpGetByIdDirect>().metadata(this);
+        });
+
+        m_metadata->forEach<OpGetByIdDirect>([&] (auto& metadata) {
             StructureID oldStructureID = metadata.m_structureID;
             if (!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID)))
-                break;
+                return;
             if (Options::verboseOSR())
                 dataLogF("Clearing LLInt property access.\n");
             metadata.m_structureID = 0;
             metadata.m_offset = 0;
-            break;
-        }
-        case op_put_by_id: {
-            auto& metadata = curInstruction->as<OpPutById>().metadata(this);
+        });
+
+        m_metadata->forEach<OpPutById>([&] (auto& metadata) {
             StructureID oldStructureID = metadata.m_oldStructureID;
             StructureID newStructureID = metadata.m_newStructureID;
             StructureChain* chain = metadata.m_structureChain.get();
@@ -1256,7 +1234,7 @@
             if ((!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID)))
                 && (!newStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(newStructureID)))
                 && (!chain || vm.heap.isMarked(chain)))
-                break;
+                return;
             if (Options::verboseOSR())
                 dataLogF("Clearing LLInt put transition.\n");
             metadata.m_oldStructureID = 0;
@@ -1263,16 +1241,11 @@
             metadata.m_offset = 0;
             metadata.m_newStructureID = 0;
             metadata.m_structureChain.clear();
-            break;
-        }
-        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=166418
-        // We need to add optimizations for op_resolve_scope_for_hoisting_func_decl_in_eval to do link time scope resolution.
-        case op_resolve_scope_for_hoisting_func_decl_in_eval:
-            break;
-        case op_to_this: {
-            auto& metadata = curInstruction->as<OpToThis>().metadata(this);
+        });
+
+        m_metadata->forEach<OpToThis>([&] (auto& metadata) {
             if (!metadata.m_cachedStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(metadata.m_cachedStructureID)))
-                break;
+                return;
             if (Options::verboseOSR()) {
                 Structure* structure = vm.heap.structureIDTable().get(metadata.m_cachedStructureID);
                 dataLogF("Clearing LLInt to_this with structure %p.\n", structure);
@@ -1279,57 +1252,53 @@
             }
             metadata.m_cachedStructureID = 0;
             metadata.m_toThisStatus = merge(metadata.m_toThisStatus, ToThisClearedByGC);
-            break;
-        }
-        case op_create_this: {
-            auto& metadata = curInstruction->as<OpCreateThis>().metadata(this);
+        });
+
+        auto handleCreateBytecode = [&] (auto& metadata, ASCIILiteral name) {
             auto& cacheWriteBarrier = metadata.m_cachedCallee;
             if (!cacheWriteBarrier || cacheWriteBarrier.unvalidatedGet() == JSCell::seenMultipleCalleeObjects())
-                break;
+                return;
             JSCell* cachedFunction = cacheWriteBarrier.get();
             if (vm.heap.isMarked(cachedFunction))
-                break;
-            if (Options::verboseOSR())
-                dataLogF("Clearing LLInt create_this with cached callee %p.\n", cachedFunction);
+                return;
+            dataLogLnIf(Options::verboseOSR(), "Clearing LLInt ", name, " with cached callee ", RawPointer(cachedFunction), ".");
             cacheWriteBarrier.clear();
-            break;
-        }
-        case op_create_promise: {
-            auto& metadata = curInstruction->as<OpCreatePromise>().metadata(this);
-            auto& cacheWriteBarrier = metadata.m_cachedCallee;
-            if (!cacheWriteBarrier || cacheWriteBarrier.unvalidatedGet() == JSCell::seenMultipleCalleeObjects())
-                break;
-            JSCell* cachedFunction = cacheWriteBarrier.get();
-            if (vm.heap.isMarked(cachedFunction))
-                break;
-            if (Options::verboseOSR())
-                dataLogF("Clearing LLInt create_promise with cached callee %p.\n", cachedFunction);
-            cacheWriteBarrier.clear();
-            break;
-        }
-        case op_resolve_scope: {
+        };
+
+        m_metadata->forEach<OpCreateThis>([&] (auto& metadata) {
+            handleCreateBytecode(metadata, "op_create_this"_s);
+        });
+        m_metadata->forEach<OpCreatePromise>([&] (auto& metadata) {
+            handleCreateBytecode(metadata, "op_create_promise"_s);
+        });
+
+        m_metadata->forEach<OpResolveScope>([&] (auto& metadata) {
             // Right now this isn't strictly necessary. Any symbol tables that this will refer to
             // are for outer functions, and we refer to those functions strongly, and they refer
             // to the symbol table strongly. But it's nice to be on the safe side.
-            auto& metadata = curInstruction->as<OpResolveScope>().metadata(this);
             WriteBarrierBase<SymbolTable>& symbolTable = metadata.m_symbolTable;
             if (!symbolTable || vm.heap.isMarked(symbolTable.get()))
-                break;
+                return;
             if (Options::verboseOSR())
                 dataLogF("Clearing dead symbolTable %p.\n", symbolTable.get());
             symbolTable.clear();
-            break;
-        }
-        case op_get_from_scope:
-            handleGetPutFromScope(curInstruction->as<OpGetFromScope>().metadata(this));
-            break;
-        case op_put_to_scope:
-            handleGetPutFromScope(curInstruction->as<OpPutToScope>().metadata(this));
-            break;
-        default:
-            OpcodeID opcodeID = curInstruction->opcodeID();
-            ASSERT_WITH_MESSAGE_UNUSED(opcodeID, false, "Unhandled opcode in CodeBlock::finalizeUnconditionally, %s(%d) at bc %u", opcodeNames[opcodeID], opcodeID, propertyAccessInstructions[i]);
-        }
+        });
+
+        auto handleGetPutFromScope = [&] (auto& metadata) {
+            GetPutInfo getPutInfo = metadata.m_getPutInfo;
+            if (getPutInfo.resolveType() == GlobalVar || getPutInfo.resolveType() == GlobalVarWithVarInjectionChecks
+                || getPutInfo.resolveType() == LocalClosureVar || getPutInfo.resolveType() == GlobalLexicalVar || getPutInfo.resolveType() == GlobalLexicalVarWithVarInjectionChecks)
+                return;
+            WriteBarrierBase<Structure>& structure = metadata.m_structure;
+            if (!structure || vm.heap.isMarked(structure.get()))
+                return;
+            if (Options::verboseOSR())
+                dataLogF("Clearing scope access with structure %p.\n", structure.get());
+            structure.clear();
+        };
+
+        m_metadata->forEach<OpGetFromScope>(handleGetPutFromScope);
+        m_metadata->forEach<OpPutToScope>(handleGetPutFromScope);
     }
 
     // We can't just remove all the sets when we clear the caches since we might have created a watchpoint set

Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp (249667 => 249668)


--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp	2019-09-09 21:20:59 UTC (rev 249667)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp	2019-09-09 21:38:17 UTC (rev 249668)
@@ -363,9 +363,6 @@
         }
     }
 
-    for (size_t i = 0; i < m_propertyAccessInstructions.size(); ++i)
-        m_propertyAccessInstructions[i] = rewriter.adjustAbsoluteOffset(m_propertyAccessInstructions[i]);
-
     for (size_t i = 0; i < m_expressionInfo.size(); ++i)
         m_expressionInfo[i].instructionOffset = rewriter.adjustAbsoluteOffset(m_expressionInfo[i].instructionOffset);
 
@@ -382,7 +379,6 @@
     auto locker = holdLock(cellLock());
     
     m_jumpTargets.shrinkToFit();
-    m_propertyAccessInstructions.shrinkToFit();
     m_identifiers.shrinkToFit();
     m_constantRegisters.shrinkToFit();
     m_constantsSourceCodeRepresentation.shrinkToFit();

Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h (249667 => 249668)


--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h	2019-09-09 21:20:59 UTC (rev 249667)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h	2019-09-09 21:38:17 UTC (rev 249668)
@@ -277,14 +277,6 @@
     VirtualRegister thisRegister() const { return m_thisRegister; }
     VirtualRegister scopeRegister() const { return m_scopeRegister; }
 
-    void addPropertyAccessInstruction(InstructionStream::Offset propertyAccessInstruction)
-    {
-        m_propertyAccessInstructions.append(propertyAccessInstruction);
-    }
-
-    size_t numberOfPropertyAccessInstructions() const { return m_propertyAccessInstructions.size(); }
-    const Vector<InstructionStream::Offset>& propertyAccessInstructions() const { return m_propertyAccessInstructions; }
-
     bool hasRareData() const { return m_rareData.get(); }
 
     int lineNumberForBytecodeOffset(unsigned bytecodeOffset);
@@ -459,9 +451,6 @@
     DFG::ExitProfile m_exitProfile;
 #endif
 
-
-    Vector<InstructionStream::Offset> m_propertyAccessInstructions;
-
     // Constant Pools
     Vector<Identifier> m_identifiers;
     Vector<WriteBarrier<Unknown>> m_constantRegisters;

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (249667 => 249668)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2019-09-09 21:20:59 UTC (rev 249667)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2019-09-09 21:38:17 UTC (rev 249668)
@@ -2496,7 +2496,6 @@
         
         dst = tempDestination(dst);
         OpResolveScope::emit(this, kill(dst), scopeRegister(), addConstant(variable.ident()), resolveType(), localScopeDepth());
-        m_codeBlock->addPropertyAccessInstruction(m_lastInstruction.offset());
         return dst;
     }
     
@@ -2525,7 +2524,6 @@
             GetPutInfo(resolveMode, variable.offset().isScope() ? LocalClosureVar : resolveType(), InitializationMode::NotInitialization),
             localScopeDepth(),
             variable.offset().isScope() ? variable.offset().scopeOffset().offset() : 0);
-        m_codeBlock->addPropertyAccessInstruction(m_lastInstruction.offset());
         return dst;
     } }
     
@@ -2558,7 +2556,6 @@
             symbolTableOrScopeDepth = SymbolTableOrScopeDepth::scopeDepth(localScopeDepth());
         }
         OpPutToScope::emit(this, scope, addConstant(variable.ident()), value, getPutInfo, symbolTableOrScopeDepth, !!offset ? offset.offset() : 0);
-        m_codeBlock->addPropertyAccessInstruction(m_lastInstruction.offset());
         return value;
     } }
     
@@ -2609,7 +2606,6 @@
     ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with get_by_val.");
 
     OpGetById::emit(this, kill(dst), base, addConstant(property));
-    m_codeBlock->addPropertyAccessInstruction(m_lastInstruction.offset());
     return dst;
 }
 
@@ -2626,7 +2622,6 @@
     ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with get_by_val_direct.");
 
     OpGetByIdDirect::emit(this, kill(dst), base, addConstant(property));
-    m_codeBlock->addPropertyAccessInstruction(m_lastInstruction.offset());
     return dst;
 }
 
@@ -2639,8 +2634,6 @@
     m_staticPropertyAnalyzer.putById(base, propertyIndex);
 
     OpPutById::emit(this, base, propertyIndex, value, PutByIdNone); // is not direct
-    m_codeBlock->addPropertyAccessInstruction(m_lastInstruction.offset());
-
     return value;
 }
 
@@ -2665,7 +2658,6 @@
 
     PutByIdFlags type = (putType == PropertyNode::KnownDirect || property != m_vm.propertyNames->underscoreProto) ? PutByIdIsDirect : PutByIdNone;
     OpPutById::emit(this, base, propertyIndex, value, type);
-    m_codeBlock->addPropertyAccessInstruction(m_lastInstruction.offset());
     return value;
 }
 
@@ -2851,8 +2843,6 @@
 {
     OpCreateThis::emit(this, dst, dst, 0);
     m_staticPropertyAnalyzer.createThis(dst, m_lastInstruction);
-
-    m_codeBlock->addPropertyAccessInstruction(m_lastInstruction.offset());
     return dst;
 }
 
@@ -5134,7 +5124,6 @@
 void BytecodeGenerator::emitToThis()
 {
     OpToThis::emit(this, kill(&m_thisRegister));
-    m_codeBlock->addPropertyAccessInstruction(m_lastInstruction.offset());
 }
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/CachedTypes.cpp (249667 => 249668)


--- trunk/Source/_javascript_Core/runtime/CachedTypes.cpp	2019-09-09 21:20:59 UTC (rev 249667)
+++ trunk/Source/_javascript_Core/runtime/CachedTypes.cpp	2019-09-09 21:38:17 UTC (rev 249668)
@@ -1838,7 +1838,6 @@
 
     CachedPtr<CachedInstructionStream> m_instructions;
     CachedVector<InstructionStream::Offset> m_jumpTargets;
-    CachedVector<InstructionStream::Offset> m_propertyAccessInstructions;
     CachedVector<CachedJSValue> m_constantRegisters;
     CachedVector<SourceCodeRepresentation> m_constantsSourceCodeRepresentation;
     CachedVector<ExpressionRangeInfo> m_expressionInfo;
@@ -2043,7 +2042,6 @@
     for (unsigned i = LinkTimeConstantCount; i--;)
         codeBlock.m_linkTimeConstants[i] = m_linkTimeConstants[i];
 
-    m_propertyAccessInstructions.decode(decoder, codeBlock.m_propertyAccessInstructions);
     m_constantRegisters.decode(decoder, codeBlock.m_constantRegisters, &codeBlock);
     m_constantsSourceCodeRepresentation.decode(decoder, codeBlock.m_constantsSourceCodeRepresentation);
     m_expressionInfo.decode(decoder, codeBlock.m_expressionInfo);
@@ -2219,7 +2217,6 @@
     m_sourceMappingURLDirective.encode(encoder, codeBlock.m_sourceURLDirective.impl());
 
     m_instructions.encode(encoder, codeBlock.m_instructions.get());
-    m_propertyAccessInstructions.encode(encoder, codeBlock.m_propertyAccessInstructions);
     m_constantRegisters.encode(encoder, codeBlock.m_constantRegisters);
     m_constantsSourceCodeRepresentation.encode(encoder, codeBlock.m_constantsSourceCodeRepresentation);
     m_expressionInfo.encode(encoder, codeBlock.m_expressionInfo);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to