WebKit Bugzilla
Attachment 343340 Details for
Bug 186928
: We should call visitChildren on Base not the exact typename
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for landing
bug-186928-20180622103328.patch (text/plain), 18.56 KB, created by
Keith Miller
on 2018-06-22 10:33:28 PDT
(
hide
)
Description:
Patch for landing
Filename:
MIME Type:
Creator:
Keith Miller
Created:
2018-06-22 10:33:28 PDT
Size:
18.56 KB
patch
obsolete
>Subversion Revision: 233048 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 206d4b5ed9d34264b85bea87f27841993303da50..2b6194695672c59fd86d9c9afbe6c8b3aa97e676 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,58 @@ >+2018-06-22 Keith Miller <keith_miller@apple.com> >+ >+ We should call visitChildren on Base not the exact typename >+ https://bugs.webkit.org/show_bug.cgi?id=186928 >+ >+ Reviewed by Mark Lam. >+ >+ A lot of places were not properly calling visitChildren on their >+ superclass. For most of them it didn't matter because they had >+ immortal structures. If code changed in the future this might >+ break things however. >+ >+ Also, block off more of the MethodTable for GetterSetter objects. >+ >+ * bytecode/CodeBlock.cpp: >+ (JSC::CodeBlock::visitChildren): >+ * bytecode/ExecutableToCodeBlockEdge.cpp: >+ (JSC::ExecutableToCodeBlockEdge::visitChildren): >+ * debugger/DebuggerScope.cpp: >+ (JSC::DebuggerScope::visitChildren): >+ * runtime/EvalExecutable.cpp: >+ (JSC::EvalExecutable::visitChildren): >+ * runtime/FunctionExecutable.cpp: >+ (JSC::FunctionExecutable::visitChildren): >+ * runtime/FunctionRareData.cpp: >+ (JSC::FunctionRareData::visitChildren): >+ * runtime/GenericArgumentsInlines.h: >+ (JSC::GenericArguments<Type>::visitChildren): >+ * runtime/GetterSetter.cpp: >+ (JSC::GetterSetter::visitChildren): >+ * runtime/GetterSetter.h: >+ * runtime/InferredType.cpp: >+ (JSC::InferredType::visitChildren): >+ * runtime/InferredTypeTable.cpp: >+ (JSC::InferredTypeTable::visitChildren): >+ * runtime/InferredValue.cpp: >+ (JSC::InferredValue::visitChildren): >+ * runtime/JSArrayBufferView.cpp: >+ (JSC::JSArrayBufferView::visitChildren): >+ * runtime/JSGenericTypedArrayViewInlines.h: >+ (JSC::JSGenericTypedArrayView<Adaptor>::visitChildren): >+ * runtime/ModuleProgramExecutable.cpp: >+ (JSC::ModuleProgramExecutable::visitChildren): >+ * runtime/ProgramExecutable.cpp: >+ (JSC::ProgramExecutable::visitChildren): >+ * runtime/ScopedArguments.cpp: >+ (JSC::ScopedArguments::visitChildren): >+ * runtime/ScopedArguments.h: >+ * runtime/Structure.cpp: >+ (JSC::Structure::visitChildren): >+ * runtime/StructureRareData.cpp: >+ (JSC::StructureRareData::visitChildren): >+ * runtime/SymbolTable.cpp: >+ (JSC::SymbolTable::visitChildren): >+ > 2018-06-20 Keith Miller <keith_miller@apple.com> > > flattenDictionaryStruture needs to zero inline storage. >diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >index 98ef06f47a33611351c74cba411ac2f31b864a8f..3be932b3e37ca66d907697bfaf6f3cf9becb251b 100644 >--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp >+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >@@ -1012,7 +1012,7 @@ void CodeBlock::visitChildren(JSCell* cell, SlotVisitor& visitor) > { > CodeBlock* thisObject = jsCast<CodeBlock*>(cell); > ASSERT_GC_OBJECT_INHERITS(thisObject, info()); >- JSCell::visitChildren(thisObject, visitor); >+ Base::visitChildren(cell, visitor); > visitor.append(thisObject->m_ownerEdge); > thisObject->visitChildren(visitor); > } >diff --git a/Source/JavaScriptCore/bytecode/ExecutableToCodeBlockEdge.cpp b/Source/JavaScriptCore/bytecode/ExecutableToCodeBlockEdge.cpp >index 5657e222d0b5091104e44f01a7b55b12f0b5f5d2..81bc9a98532b73739149b771b265458323d2ba80 100644 >--- a/Source/JavaScriptCore/bytecode/ExecutableToCodeBlockEdge.cpp >+++ b/Source/JavaScriptCore/bytecode/ExecutableToCodeBlockEdge.cpp >@@ -48,6 +48,8 @@ void ExecutableToCodeBlockEdge::visitChildren(JSCell* cell, SlotVisitor& visitor > { > VM& vm = visitor.vm(); > ExecutableToCodeBlockEdge* edge = jsCast<ExecutableToCodeBlockEdge*>(cell); >+ Base::visitChildren(cell, visitor); >+ > CodeBlock* codeBlock = edge->m_codeBlock.get(); > > // It's possible for someone to hold a pointer to the edge after the edge has cleared its weak >diff --git a/Source/JavaScriptCore/debugger/DebuggerScope.cpp b/Source/JavaScriptCore/debugger/DebuggerScope.cpp >index 55136ff462618650d0701527c7ceebd6956c26bd..d5404b563b5d4b816fe54e2a392a6b221bb3c1f5 100644 >--- a/Source/JavaScriptCore/debugger/DebuggerScope.cpp >+++ b/Source/JavaScriptCore/debugger/DebuggerScope.cpp >@@ -60,7 +60,8 @@ void DebuggerScope::visitChildren(JSCell* cell, SlotVisitor& visitor) > { > DebuggerScope* thisObject = jsCast<DebuggerScope*>(cell); > ASSERT_GC_OBJECT_INHERITS(thisObject, info()); >- JSObject::visitChildren(thisObject, visitor); >+ Base::visitChildren(cell, visitor); >+ > visitor.append(thisObject->m_scope); > visitor.append(thisObject->m_next); > } >diff --git a/Source/JavaScriptCore/runtime/EvalExecutable.cpp b/Source/JavaScriptCore/runtime/EvalExecutable.cpp >index 3386d0ee66102e88c3e9181f5e12ce071a5f7a46..6ed8cccb2c42e5c5df6047e4075f2bdcff39b535 100644 >--- a/Source/JavaScriptCore/runtime/EvalExecutable.cpp >+++ b/Source/JavaScriptCore/runtime/EvalExecutable.cpp >@@ -48,7 +48,7 @@ void EvalExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor) > { > EvalExecutable* thisObject = jsCast<EvalExecutable*>(cell); > ASSERT_GC_OBJECT_INHERITS(thisObject, info()); >- ScriptExecutable::visitChildren(thisObject, visitor); >+ Base::visitChildren(thisObject, visitor); > visitor.append(thisObject->m_unlinkedEvalCodeBlock); > visitor.append(thisObject->m_evalCodeBlock); > } >diff --git a/Source/JavaScriptCore/runtime/FunctionExecutable.cpp b/Source/JavaScriptCore/runtime/FunctionExecutable.cpp >index 7196426695cbd12476c7a108168df9a8900d0756..d5770d4a0649c50d2094b7f16ae898fab9778472 100644 >--- a/Source/JavaScriptCore/runtime/FunctionExecutable.cpp >+++ b/Source/JavaScriptCore/runtime/FunctionExecutable.cpp >@@ -84,7 +84,7 @@ void FunctionExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor) > { > FunctionExecutable* thisObject = jsCast<FunctionExecutable*>(cell); > ASSERT_GC_OBJECT_INHERITS(thisObject, info()); >- ScriptExecutable::visitChildren(thisObject, visitor); >+ Base::visitChildren(thisObject, visitor); > visitor.append(thisObject->m_codeBlockForCall); > visitor.append(thisObject->m_codeBlockForConstruct); > visitor.append(thisObject->m_unlinkedExecutable); >diff --git a/Source/JavaScriptCore/runtime/FunctionRareData.cpp b/Source/JavaScriptCore/runtime/FunctionRareData.cpp >index cfedf9507f0508e0a2e647fba5973b561df3329e..dc3cb7dbab3e3a50609692bb8873475133d05ed8 100644 >--- a/Source/JavaScriptCore/runtime/FunctionRareData.cpp >+++ b/Source/JavaScriptCore/runtime/FunctionRareData.cpp >@@ -54,6 +54,7 @@ Structure* FunctionRareData::createStructure(VM& vm, JSGlobalObject* globalObjec > void FunctionRareData::visitChildren(JSCell* cell, SlotVisitor& visitor) > { > FunctionRareData* rareData = jsCast<FunctionRareData*>(cell); >+ Base::visitChildren(cell, visitor); > > rareData->m_objectAllocationProfile.visitAggregate(visitor); > rareData->m_internalFunctionAllocationProfile.visitAggregate(visitor); >diff --git a/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h b/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h >index 1aa4754cffb2efdf77b7cccba5a39d731ae386e4..25eba9264602e9644dda12e67fa7a1d34eb0d4b8 100644 >--- a/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h >+++ b/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h >@@ -35,6 +35,7 @@ void GenericArguments<Type>::visitChildren(JSCell* thisCell, SlotVisitor& visito > { > Type* thisObject = static_cast<Type*>(thisCell); > ASSERT_GC_OBJECT_INHERITS(thisObject, info()); >+ Base::visitChildren(thisCell, visitor); > > if (thisObject->m_modifiedArgumentsDescriptor) > visitor.markAuxiliary(thisObject->m_modifiedArgumentsDescriptor.get()); >diff --git a/Source/JavaScriptCore/runtime/GetterSetter.cpp b/Source/JavaScriptCore/runtime/GetterSetter.cpp >index 0415c84a57046cb0a143c92c4af9ef5550b6012d..b865777c1815735976c303397e7da74c945465b4 100644 >--- a/Source/JavaScriptCore/runtime/GetterSetter.cpp >+++ b/Source/JavaScriptCore/runtime/GetterSetter.cpp >@@ -39,7 +39,7 @@ void GetterSetter::visitChildren(JSCell* cell, SlotVisitor& visitor) > { > GetterSetter* thisObject = jsCast<GetterSetter*>(cell); > ASSERT_GC_OBJECT_INHERITS(thisObject, info()); >- JSCell::visitChildren(thisObject, visitor); >+ Base::visitChildren(thisObject, visitor); > > visitor.append(thisObject->m_getter); > visitor.append(thisObject->m_setter); >diff --git a/Source/JavaScriptCore/runtime/GetterSetter.h b/Source/JavaScriptCore/runtime/GetterSetter.h >index 55f7fe10285932bb53ee25330d0f1456a1939312..dc9d113df9a355b0ba27fce866f5d2ae2d7048db 100644 >--- a/Source/JavaScriptCore/runtime/GetterSetter.h >+++ b/Source/JavaScriptCore/runtime/GetterSetter.h >@@ -118,6 +118,8 @@ public: > > static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&) { RELEASE_ASSERT_NOT_REACHED(); return false; } > static bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&) { RELEASE_ASSERT_NOT_REACHED(); return false; } >+ static bool putByIndex(JSCell*, ExecState*, unsigned, JSValue, bool) { RELEASE_ASSERT_NOT_REACHED(); return false; } >+ static bool setPrototype(JSObject*, ExecState*, JSValue, bool) { RELEASE_ASSERT_NOT_REACHED(); return false; } > static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool) { RELEASE_ASSERT_NOT_REACHED(); return false; } > static bool deleteProperty(JSCell*, ExecState*, PropertyName) { RELEASE_ASSERT_NOT_REACHED(); return false; } > >diff --git a/Source/JavaScriptCore/runtime/InferredType.cpp b/Source/JavaScriptCore/runtime/InferredType.cpp >index aa06db6a027830f7257c1f54f37d1c9dafcb6fd4..c5239d8fffb07814be3c566d4abc06f0dc3b5ecd 100644 >--- a/Source/JavaScriptCore/runtime/InferredType.cpp >+++ b/Source/JavaScriptCore/runtime/InferredType.cpp >@@ -86,6 +86,7 @@ Structure* InferredType::createStructure(VM& vm, JSGlobalObject* globalObject, J > void InferredType::visitChildren(JSCell* cell, SlotVisitor& visitor) > { > InferredType* inferredType = jsCast<InferredType*>(cell); >+ Base::visitChildren(cell, visitor); > if (inferredType->m_structure) > visitor.vm().inferredTypesWithFinalizers.add(inferredType); > } >diff --git a/Source/JavaScriptCore/runtime/InferredTypeTable.cpp b/Source/JavaScriptCore/runtime/InferredTypeTable.cpp >index 1fc52b4adfa41de5114c9ff538c61574d463637f..47a42e80ec4d0447999e0f0fd8a3d0d93f945b49 100644 >--- a/Source/JavaScriptCore/runtime/InferredTypeTable.cpp >+++ b/Source/JavaScriptCore/runtime/InferredTypeTable.cpp >@@ -53,6 +53,7 @@ Structure* InferredTypeTable::createStructure(VM& vm, JSGlobalObject* globalObje > void InferredTypeTable::visitChildren(JSCell* cell, SlotVisitor& visitor) > { > InferredTypeTable* inferredTypeTable = jsCast<InferredTypeTable*>(cell); >+ Base::visitChildren(cell, visitor); > > ConcurrentJSLocker locker(inferredTypeTable->m_lock); > >diff --git a/Source/JavaScriptCore/runtime/InferredValue.cpp b/Source/JavaScriptCore/runtime/InferredValue.cpp >index 8489039a572b30366fafcd12b7d3dd04288552c7..69de0fb04303f47000256520a8885a19098477de 100644 >--- a/Source/JavaScriptCore/runtime/InferredValue.cpp >+++ b/Source/JavaScriptCore/runtime/InferredValue.cpp >@@ -54,7 +54,8 @@ Structure* InferredValue::createStructure(VM& vm, JSGlobalObject* globalObject, > void InferredValue::visitChildren(JSCell* cell, SlotVisitor& visitor) > { > InferredValue* inferredValue = jsCast<InferredValue*>(cell); >- >+ Base::visitChildren(cell, visitor); >+ > JSValue value = inferredValue->m_value.get(); > if (!value) > return; >diff --git a/Source/JavaScriptCore/runtime/JSArrayBufferView.cpp b/Source/JavaScriptCore/runtime/JSArrayBufferView.cpp >index 730eefdd240d46b917aabda89c5f2bc039c99976..2dbb452b3493b9c3ccf72f032f423a2e11bfa2ed 100644 >--- a/Source/JavaScriptCore/runtime/JSArrayBufferView.cpp >+++ b/Source/JavaScriptCore/runtime/JSArrayBufferView.cpp >@@ -159,6 +159,7 @@ void JSArrayBufferView::finishCreation(VM& vm) > void JSArrayBufferView::visitChildren(JSCell* cell, SlotVisitor& visitor) > { > JSArrayBufferView* thisObject = jsCast<JSArrayBufferView*>(cell); >+ Base::visitChildren(cell, visitor); > > if (thisObject->hasArrayBuffer()) { > WTF::loadLoadFence(); >@@ -166,8 +167,6 @@ void JSArrayBufferView::visitChildren(JSCell* cell, SlotVisitor& visitor) > RELEASE_ASSERT(buffer); > visitor.addOpaqueRoot(buffer); > } >- >- Base::visitChildren(thisObject, visitor); > } > > bool JSArrayBufferView::put( >diff --git a/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h b/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h >index 3e3f36cd377ad1664880296f4d91141ce6fa6406..775aaf72fb97ce868e251ae487c465e9af716abd 100644 >--- a/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h >+++ b/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h >@@ -514,7 +514,8 @@ template<typename Adaptor> > void JSGenericTypedArrayView<Adaptor>::visitChildren(JSCell* cell, SlotVisitor& visitor) > { > JSGenericTypedArrayView* thisObject = jsCast<JSGenericTypedArrayView*>(cell); >- >+ Base::visitChildren(thisObject, visitor); >+ > TypedArrayMode mode; > void* vector; > size_t byteSize; >@@ -545,8 +546,6 @@ void JSGenericTypedArrayView<Adaptor>::visitChildren(JSCell* cell, SlotVisitor& > RELEASE_ASSERT_NOT_REACHED(); > break; > } >- >- Base::visitChildren(thisObject, visitor); > } > > template<typename Adaptor> >diff --git a/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp b/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp >index eaeef8ad71cc708e06eae1ae8c8490c928dc71f5..25fd954a5e9b4b602962c726c7ad7a6e406a890c 100644 >--- a/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp >+++ b/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp >@@ -90,7 +90,7 @@ void ModuleProgramExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor) > { > ModuleProgramExecutable* thisObject = jsCast<ModuleProgramExecutable*>(cell); > ASSERT_GC_OBJECT_INHERITS(thisObject, info()); >- ScriptExecutable::visitChildren(thisObject, visitor); >+ Base::visitChildren(thisObject, visitor); > visitor.append(thisObject->m_unlinkedModuleProgramCodeBlock); > visitor.append(thisObject->m_moduleEnvironmentSymbolTable); > visitor.append(thisObject->m_moduleProgramCodeBlock); >diff --git a/Source/JavaScriptCore/runtime/ProgramExecutable.cpp b/Source/JavaScriptCore/runtime/ProgramExecutable.cpp >index 53a24615a17338bacf0276a638c341d11bab7476..51b68d7bbd70f5b11ebb7f20873a1ba65cd50d5c 100644 >--- a/Source/JavaScriptCore/runtime/ProgramExecutable.cpp >+++ b/Source/JavaScriptCore/runtime/ProgramExecutable.cpp >@@ -207,7 +207,7 @@ void ProgramExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor) > { > ProgramExecutable* thisObject = jsCast<ProgramExecutable*>(cell); > ASSERT_GC_OBJECT_INHERITS(thisObject, info()); >- ScriptExecutable::visitChildren(thisObject, visitor); >+ Base::visitChildren(thisObject, visitor); > visitor.append(thisObject->m_unlinkedProgramCodeBlock); > visitor.append(thisObject->m_programCodeBlock); > } >diff --git a/Source/JavaScriptCore/runtime/ScopedArguments.cpp b/Source/JavaScriptCore/runtime/ScopedArguments.cpp >index d1b8c2068e23bb86284865ef242d2c77d8865fc8..b5749e323a491931a595197b08f1f4fdbb0fda2b 100644 >--- a/Source/JavaScriptCore/runtime/ScopedArguments.cpp >+++ b/Source/JavaScriptCore/runtime/ScopedArguments.cpp >@@ -120,8 +120,6 @@ void ScopedArguments::visitChildren(JSCell* cell, SlotVisitor& visitor) > visitor.appendValues( > thisObject->overflowStorage(), thisObject->storageHeader().totalLength - thisObject->m_table->length()); > } >- >- GenericArguments<ScopedArguments>::visitChildren(cell, visitor); > } > > Structure* ScopedArguments::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) >diff --git a/Source/JavaScriptCore/runtime/ScopedArguments.h b/Source/JavaScriptCore/runtime/ScopedArguments.h >index 93621671107b8ae2e9f265b501294d6bdce5949a..b2e80ff4d926a128a2939f9b598deb6c2e3d5893 100644 >--- a/Source/JavaScriptCore/runtime/ScopedArguments.h >+++ b/Source/JavaScriptCore/runtime/ScopedArguments.h >@@ -40,6 +40,7 @@ class ScopedArguments final : public GenericArguments<ScopedArguments> { > private: > ScopedArguments(VM&, Structure*, WriteBarrier<Unknown>* storage); > void finishCreation(VM&, JSFunction* callee, ScopedArgumentsTable*, JSLexicalEnvironment*); >+ using Base = GenericArguments<ScopedArguments>; > > public: > template<typename CellType> >diff --git a/Source/JavaScriptCore/runtime/Structure.cpp b/Source/JavaScriptCore/runtime/Structure.cpp >index 30eeee9cc26f141bea0c893602d12e145aa159ea..a17b6ac0f56175d3f403d2c0a5444f4e51154039 100644 >--- a/Source/JavaScriptCore/runtime/Structure.cpp >+++ b/Source/JavaScriptCore/runtime/Structure.cpp >@@ -1078,7 +1078,7 @@ void Structure::visitChildren(JSCell* cell, SlotVisitor& visitor) > Structure* thisObject = jsCast<Structure*>(cell); > ASSERT_GC_OBJECT_INHERITS(thisObject, info()); > >- JSCell::visitChildren(thisObject, visitor); >+ Base::visitChildren(thisObject, visitor); > > ConcurrentJSLocker locker(thisObject->m_lock); > >diff --git a/Source/JavaScriptCore/runtime/StructureRareData.cpp b/Source/JavaScriptCore/runtime/StructureRareData.cpp >index ae301e269fe07a2c7a9d4333a28b81373522f3f6..a0375fb982fdf87179bca7057610f036b89e7b65 100644 >--- a/Source/JavaScriptCore/runtime/StructureRareData.cpp >+++ b/Source/JavaScriptCore/runtime/StructureRareData.cpp >@@ -66,7 +66,7 @@ void StructureRareData::visitChildren(JSCell* cell, SlotVisitor& visitor) > StructureRareData* thisObject = jsCast<StructureRareData*>(cell); > ASSERT_GC_OBJECT_INHERITS(thisObject, info()); > >- JSCell::visitChildren(thisObject, visitor); >+ Base::visitChildren(thisObject, visitor); > visitor.append(thisObject->m_previous); > visitor.append(thisObject->m_objectToStringValue); > visitor.append(thisObject->m_cachedPropertyNameEnumerator); >diff --git a/Source/JavaScriptCore/runtime/SymbolTable.cpp b/Source/JavaScriptCore/runtime/SymbolTable.cpp >index ced975fb3e210537f707ff3031b7222a2124deb1..6b95a0ed8638933b979da4fab5e948ea9ce267be 100644 >--- a/Source/JavaScriptCore/runtime/SymbolTable.cpp >+++ b/Source/JavaScriptCore/runtime/SymbolTable.cpp >@@ -101,7 +101,8 @@ void SymbolTable::finishCreation(VM& vm) > void SymbolTable::visitChildren(JSCell* thisCell, SlotVisitor& visitor) > { > SymbolTable* thisSymbolTable = jsCast<SymbolTable*>(thisCell); >- >+ Base::visitChildren(thisSymbolTable, visitor); >+ > visitor.append(thisSymbolTable->m_arguments); > visitor.append(thisSymbolTable->m_singletonScope); >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
keith_miller
:
commit-queue+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 186928
:
343337
| 343340