WebKit Bugzilla
Attachment 358251 Details for
Bug 193085
: Baseline version of get_by_id may corrupt metadata
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-193085-20190103143102.patch (text/plain), 13.94 KB, created by
Tadeu Zagallo
on 2019-01-03 05:31:05 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Tadeu Zagallo
Created:
2019-01-03 05:31:05 PST
Size:
13.94 KB
patch
obsolete
>Subversion Revision: 239556 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 17e010891210bef58b46a33cef329ca3a41b7833..839a71e417fc0c078ea49213b81a8dca526ef1ef 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,43 @@ >+2019-01-03 Tadeu Zagallo <tzagallo@apple.com> >+ >+ Baseline version of get_by_id may corrupt metadata >+ https://bugs.webkit.org/show_bug.cgi?id=193085 >+ <rdar://problem/23453006> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ The Baseline version of get_by_id unconditionally calls `emitArrayProfilingSiteForBytecodeIndexWithCell` >+ if the property is `length`. However, since the bytecode rewrite, get_by_id only has an ArrayProfile entry >+ in the metadata if its mode is `GetByIdMode::ArrayLength`. That might result in one of two bad things: >+ 1) get_by_id's mode is not ArrayLength, and a duplicate, out-of-line ArrayProfile entry will be created by >+ `CodeBlock::getOrAddArrayProfile`. >+ 2) get_by_id's mode *is* ArrayLength and we generate the array profiling code pointing to the ArrayProfile >+ that lives in the metadata table. This works fine as long as get_by_id does not change modes. If that happens, >+ the JIT code will write into the metadata table, overwriting the 'GetByIdModeMetadata` for another mode. >+ >+ Add a check to the Baseline version of get_by_id so that we only do the ArrayProfiling if the get_by_id's >+ mode is ArrayLength >+ >+ * bytecode/BytecodeList.rb: >+ * bytecode/CodeBlock.cpp: >+ (JSC::CodeBlock::getArrayProfile): >+ (JSC::CodeBlock::addArrayProfile): Deleted. >+ (JSC::CodeBlock::getOrAddArrayProfile): Deleted. >+ * bytecode/CodeBlock.h: >+ (JSC::CodeBlock::numberOfArrayProfiles const): Deleted. >+ (JSC::CodeBlock::arrayProfiles): Deleted. >+ * bytecode/CodeBlockInlines.h: >+ (JSC::CodeBlock::forEachArrayProfile): >+ * jit/JIT.h: >+ * jit/JITInlines.h: >+ (JSC::JIT::emitArrayProfilingSiteForBytecodeIndexWithCell): Deleted. >+ * jit/JITPropertyAccess.cpp: >+ (JSC::JIT::emit_op_get_by_id): >+ * jit/JITPropertyAccess32_64.cpp: >+ (JSC::JIT::emit_op_get_by_id): >+ * llint/LLIntSlowPaths.cpp: >+ (JSC::LLInt::LLINT_SLOW_PATH_DECL): >+ > 2018-12-27 Alex Christensen <achristensen@webkit.org> > > Resurrect Mac CMake build >diff --git a/Source/JavaScriptCore/bytecode/BytecodeList.rb b/Source/JavaScriptCore/bytecode/BytecodeList.rb >index a0672d5f4eb8056f55257ae89d7b1325ac9dbae3..211532d0f6602dd178c019c6adae43fc682bff1e 100644 >--- a/Source/JavaScriptCore/bytecode/BytecodeList.rb >+++ b/Source/JavaScriptCore/bytecode/BytecodeList.rb >@@ -413,8 +413,8 @@ op :get_by_id, > }, > metadata: { > mode: GetByIdMode, >- modeMetadata: GetByIdModeMetadata, > hitCountForLLIntCaching: unsigned, >+ modeMetadata: GetByIdModeMetadata, > profile: ValueProfile, > } > >@@ -473,8 +473,8 @@ op :put_by_id, > oldStructure: StructureID, > offset: unsigned, > newStructure: StructureID, >- structureChain: WriteBarrierBase[StructureChain], > flags: PutByIdFlags, >+ structureChain: WriteBarrierBase[StructureChain], > }, > metadata_initializers: { > flags: :flags >diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >index 7afda363172aab86f39cafa383ad87e6675c6272..86db8693f60e773b61ba37358ca3ee937dc0f35d 100644 >--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp >+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >@@ -2498,16 +2498,11 @@ ArrayProfile* CodeBlock::getArrayProfile(const ConcurrentJSLocker&, unsigned byt > return &metadata.modeMetadata.arrayLengthMode.arrayProfile; > break; > } >- > default: > break; > } > >- for (auto& m_arrayProfile : m_arrayProfiles) { >- if (m_arrayProfile.bytecodeOffset() == bytecodeOffset) >- return &m_arrayProfile; >- } >- return 0; >+ return nullptr; > } > > ArrayProfile* CodeBlock::getArrayProfile(unsigned bytecodeOffset) >@@ -2516,33 +2511,6 @@ ArrayProfile* CodeBlock::getArrayProfile(unsigned bytecodeOffset) > return getArrayProfile(locker, bytecodeOffset); > } > >-ArrayProfile* CodeBlock::addArrayProfile(const ConcurrentJSLocker&, unsigned bytecodeOffset) >-{ >- m_arrayProfiles.append(ArrayProfile(bytecodeOffset)); >- return &m_arrayProfiles.last(); >-} >- >-ArrayProfile* CodeBlock::addArrayProfile(unsigned bytecodeOffset) >-{ >- ConcurrentJSLocker locker(m_lock); >- return addArrayProfile(locker, bytecodeOffset); >-} >- >-ArrayProfile* CodeBlock::getOrAddArrayProfile(const ConcurrentJSLocker& locker, unsigned bytecodeOffset) >-{ >- ArrayProfile* result = getArrayProfile(locker, bytecodeOffset); >- if (result) >- return result; >- return addArrayProfile(locker, bytecodeOffset); >-} >- >-ArrayProfile* CodeBlock::getOrAddArrayProfile(unsigned bytecodeOffset) >-{ >- ConcurrentJSLocker locker(m_lock); >- return getOrAddArrayProfile(locker, bytecodeOffset); >-} >- >- > #if ENABLE(DFG_JIT) > Vector<CodeOrigin, 0, UnsafeVectorOverflow>& CodeBlock::codeOrigins() > { >diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h >index 8d23bbcdeed0581f53b6c6986251eee63d7e6b88..6c766a8ab229db0f683e66c06b7d5c50b8e81217 100644 >--- a/Source/JavaScriptCore/bytecode/CodeBlock.h >+++ b/Source/JavaScriptCore/bytecode/CodeBlock.h >@@ -464,14 +464,8 @@ public: > > bool couldTakeSpecialFastCase(InstructionStream::Offset bytecodeOffset); > >- unsigned numberOfArrayProfiles() const { return m_arrayProfiles.size(); } >- const ArrayProfileVector& arrayProfiles() { return m_arrayProfiles; } >- ArrayProfile* addArrayProfile(const ConcurrentJSLocker&, unsigned bytecodeOffset); >- ArrayProfile* addArrayProfile(unsigned bytecodeOffset); > ArrayProfile* getArrayProfile(const ConcurrentJSLocker&, unsigned bytecodeOffset); > ArrayProfile* getArrayProfile(unsigned bytecodeOffset); >- ArrayProfile* getOrAddArrayProfile(const ConcurrentJSLocker&, unsigned bytecodeOffset); >- ArrayProfile* getOrAddArrayProfile(unsigned bytecodeOffset); > > // Exception handling support > >@@ -987,7 +981,6 @@ private: > RefCountedArray<ValueProfile> m_argumentValueProfiles; > Vector<std::unique_ptr<ValueProfileAndOperandBuffer>> m_catchProfiles; > SegmentedVector<RareCaseProfile, 8> m_rareCaseProfiles; >- ArrayProfileVector m_arrayProfiles; > > // Constant Pool > COMPILE_ASSERT(sizeof(Register) == sizeof(WriteBarrier<Unknown>), Register_must_be_same_size_as_WriteBarrier_Unknown); >diff --git a/Source/JavaScriptCore/bytecode/CodeBlockInlines.h b/Source/JavaScriptCore/bytecode/CodeBlockInlines.h >index f81f9d5f6b63f2d2d56872bbc1a9e363a95ce98c..ed63eb3b59a687194f2605c1a530f56f9034c0f5 100644 >--- a/Source/JavaScriptCore/bytecode/CodeBlockInlines.h >+++ b/Source/JavaScriptCore/bytecode/CodeBlockInlines.h >@@ -51,9 +51,6 @@ void CodeBlock::forEachValueProfile(const Functor& func) > template<typename Functor> > void CodeBlock::forEachArrayProfile(const Functor& func) > { >- for (auto& arrayProfile : m_arrayProfiles) >- func(arrayProfile); >- > if (m_metadata) { > m_metadata->forEach<OpGetById>([&] (auto& metadata) { > if (metadata.mode == GetByIdMode::ArrayLength) >diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h >index fc710b0eb6dc4d74f1ac2a626928fc3374c6d749..a1ca2ea8ba07bcfe185afe186f6e41ad95d224e9 100644 >--- a/Source/JavaScriptCore/jit/JIT.h >+++ b/Source/JavaScriptCore/jit/JIT.h >@@ -365,7 +365,6 @@ namespace JSC { > emitValueProfilingSiteIfProfiledOpcode(Op bytecode); > > void emitArrayProfilingSiteWithCell(RegisterID cell, RegisterID indexingType, ArrayProfile*); >- void emitArrayProfilingSiteForBytecodeIndexWithCell(RegisterID cell, RegisterID indexingType, unsigned bytecodeIndex); > void emitArrayProfileStoreToHoleSpecialCase(ArrayProfile*); > void emitArrayProfileOutOfBoundsSpecialCase(ArrayProfile*); > >diff --git a/Source/JavaScriptCore/jit/JITInlines.h b/Source/JavaScriptCore/jit/JITInlines.h >index d6c7b7fa788cc368278cedc61347ead6d301b129..9ea8deb388abf9bb9887905b5d32d4997fea6a7d 100644 >--- a/Source/JavaScriptCore/jit/JITInlines.h >+++ b/Source/JavaScriptCore/jit/JITInlines.h >@@ -354,11 +354,6 @@ inline void JIT::emitArrayProfilingSiteWithCell(RegisterID cell, RegisterID inde > load8(Address(cell, JSCell::indexingTypeAndMiscOffset()), indexingType); > } > >-inline void JIT::emitArrayProfilingSiteForBytecodeIndexWithCell(RegisterID cell, RegisterID indexingType, unsigned bytecodeIndex) >-{ >- emitArrayProfilingSiteWithCell(cell, indexingType, m_codeBlock->getOrAddArrayProfile(bytecodeIndex)); >-} >- > inline void JIT::emitArrayProfileStoreToHoleSpecialCase(ArrayProfile* arrayProfile) > { > store8(TrustedImm32(1), arrayProfile->addressOfMayStoreToHole()); >diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp >index bd785be866d6d83e6a6941a977300b5ad42ab49f..ad1d3dccc62ba5f7382702c2ee9e1e115d34f3d9 100644 >--- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp >+++ b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp >@@ -572,6 +572,7 @@ void JIT::emitSlow_op_get_by_id_direct(const Instruction* currentInstruction, Ve > void JIT::emit_op_get_by_id(const Instruction* currentInstruction) > { > auto bytecode = currentInstruction->as<OpGetById>(); >+ auto& metadata = bytecode.metadata(m_codeBlock); > int resultVReg = bytecode.dst.offset(); > int baseVReg = bytecode.base.offset(); > const Identifier* ident = &(m_codeBlock->identifier(bytecode.property)); >@@ -580,8 +581,11 @@ void JIT::emit_op_get_by_id(const Instruction* currentInstruction) > > emitJumpSlowCaseIfNotJSCell(regT0, baseVReg); > >- if (*ident == m_vm->propertyNames->length && shouldEmitProfiling()) >- emitArrayProfilingSiteForBytecodeIndexWithCell(regT0, regT1, m_bytecodeOffset); >+ if (*ident == m_vm->propertyNames->length && shouldEmitProfiling()) { >+ Jump notArrayLengthMode = branch8(NotEqual, AbsoluteAddress(&metadata.mode), TrustedImm32(static_cast<uint8_t>(GetByIdMode::ArrayLength))); >+ emitArrayProfilingSiteWithCell(regT0, regT1, &metadata.modeMetadata.arrayLengthMode.arrayProfile); >+ notArrayLengthMode.link(this); >+ } > > JITGetByIdGenerator gen( > m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(m_bytecodeOffset), RegisterSet::stubUnavailableRegisters(), >diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp >index 40ac4f3fc66e85baf9f29a3d1a363efa881f0905..e8314ca79d1939ba3eb955000b73d952c26d3e2b 100644 >--- a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp >+++ b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp >@@ -571,6 +571,7 @@ void JIT::emitSlow_op_get_by_id_direct(const Instruction* currentInstruction, Ve > void JIT::emit_op_get_by_id(const Instruction* currentInstruction) > { > auto bytecode = currentInstruction->as<OpGetById>(); >+ auto& metadata = bytecode.metadata(m_codeBlock); > int dst = bytecode.dst.offset(); > int base = bytecode.base.offset(); > const Identifier* ident = &(m_codeBlock->identifier(bytecode.property)); >@@ -578,8 +579,11 @@ void JIT::emit_op_get_by_id(const Instruction* currentInstruction) > emitLoad(base, regT1, regT0); > emitJumpSlowCaseIfNotJSCell(base, regT1); > >- if (*ident == m_vm->propertyNames->length && shouldEmitProfiling()) >- emitArrayProfilingSiteForBytecodeIndexWithCell(regT0, regT2, m_bytecodeOffset); >+ if (*ident == m_vm->propertyNames->length && shouldEmitProfiling()) { >+ Jump notArrayLengthMode = branch8(NotEqual, AbsoluteAddress(&metadata.mode), TrustedImm32(static_cast<uint8_t>(GetByIdMode::ArrayLength))); >+ emitArrayProfilingSiteWithCell(regT0, regT2, &metadata.modeMetadata.arrayLengthMode.arrayProfile); >+ notArrayLengthMode.link(this); >+ } > > JITGetByIdGenerator gen( > m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(currentInstruction), RegisterSet::stubUnavailableRegisters(), >diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp >index e7a62a7daff0f62e4b1f38a2e86de3095feba88d..7f221cca549ff85a3ce813b969a49175721722cf 100644 >--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp >+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp >@@ -825,6 +825,7 @@ LLINT_SLOW_PATH_DECL(slow_path_get_by_id) > && isJSArray(baseValue) > && ident == vm.propertyNames->length) { > metadata.mode = GetByIdMode::ArrayLength; >+ new (&metadata.modeMetadata.arrayLengthMode.arrayProfile) ArrayProfile(codeBlock->bytecodeOffset(pc)); > metadata.modeMetadata.arrayLengthMode.arrayProfile.observeStructure(baseValue.asCell()->structure(vm)); > > // Prevent the prototype cache from ever happening. >diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog >index 9e350a323faf25b7963d0be326807ff5799ed587..c6778dfc645e13bdb138372788ce727bfc2b5e11 100644 >--- a/JSTests/ChangeLog >+++ b/JSTests/ChangeLog >@@ -1,3 +1,14 @@ >+2019-01-03 Tadeu Zagallo <tzagallo@apple.com> >+ >+ Baseline version of get_by_id may corrupt metadata >+ https://bugs.webkit.org/show_bug.cgi?id=193085 >+ <rdar://problem/23453006> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * stress/get-by-id-change-mode.js: Added. >+ (forEach): >+ > 2018-12-13 Yusuke Suzuki <yusukesuzuki@slowstart.org> > > [BigInt] Support BigInt in JSON.stringify >diff --git a/JSTests/stress/get-by-id-change-mode.js b/JSTests/stress/get-by-id-change-mode.js >new file mode 100644 >index 0000000000000000000000000000000000000000..647588f49cdb06f3c7f757e0dd596fc52afdc3c8 >--- /dev/null >+++ b/JSTests/stress/get-by-id-change-mode.js >@@ -0,0 +1,12 @@ >+//@ runDefault("--useConcurrentJIT=0") >+ >+forEach({ length: 5 }, function() { >+ for (var i = 0; i < 10; i++) { >+ forEach([1], function() {}); >+ } >+}); >+ >+function forEach(a, b) { >+ for (var c = 0; c < a.length; c++) >+ b(); >+}
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
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 193085
:
358193
|
358202
|
358213
|
358225
|
358228
|
358239
| 358251