Diff
Modified: releases/WebKitGTK/webkit-2.20/JSTests/ChangeLog (234416 => 234417)
--- releases/WebKitGTK/webkit-2.20/JSTests/ChangeLog 2018-07-31 09:25:02 UTC (rev 234416)
+++ releases/WebKitGTK/webkit-2.20/JSTests/ChangeLog 2018-07-31 09:25:12 UTC (rev 234417)
@@ -1,3 +1,15 @@
+2018-05-30 Keith Miller <[email protected]>
+
+ LLInt get_by_id prototype caching doesn't properly handle changes
+ https://bugs.webkit.org/show_bug.cgi?id=186112
+
+ Reviewed by Filip Pizlo.
+
+ * stress/llint-proto-get-by-id-cache-change-prototype.js: Added.
+ (foo):
+ * stress/llint-proto-get-by-id-cache-intercept-value.js: Added.
+ (foo):
+
2018-05-25 Mark Lam <[email protected]>
for-in loops should preserve and restore the TDZ stack for each of its internal loops.
Added: releases/WebKitGTK/webkit-2.20/JSTests/stress/llint-proto-get-by-id-cache-change-prototype.js (0 => 234417)
--- releases/WebKitGTK/webkit-2.20/JSTests/stress/llint-proto-get-by-id-cache-change-prototype.js (rev 0)
+++ releases/WebKitGTK/webkit-2.20/JSTests/stress/llint-proto-get-by-id-cache-change-prototype.js 2018-07-31 09:25:12 UTC (rev 234417)
@@ -0,0 +1,19 @@
+let p = Object.create({ foo: 1 });
+let o = Object.create(p);
+
+let other = { foo: 10 };
+
+function foo() {
+ return o.foo
+}
+
+for (let i = 0; i < 10; i++)
+ foo();
+
+p.__proto__ = null;
+gc();
+
+Object.defineProperty(other, "foo", { get() { } });
+
+if (foo() !== undefined)
+ throw new Error("bad get by id access");
Added: releases/WebKitGTK/webkit-2.20/JSTests/stress/llint-proto-get-by-id-cache-intercept-value.js (0 => 234417)
--- releases/WebKitGTK/webkit-2.20/JSTests/stress/llint-proto-get-by-id-cache-intercept-value.js (rev 0)
+++ releases/WebKitGTK/webkit-2.20/JSTests/stress/llint-proto-get-by-id-cache-intercept-value.js 2018-07-31 09:25:12 UTC (rev 234417)
@@ -0,0 +1,17 @@
+let p = Object.create({ foo: 1 });
+let o = Object.create(p);
+
+let other = { foo: 10 };
+
+function foo() {
+ return o.foo
+}
+
+for (let i = 0; i < 10; i++)
+ foo();
+
+p.foo = null;
+gc();
+
+if (foo() !== null)
+ throw new Error("bad get by id access");
Modified: releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/ChangeLog (234416 => 234417)
--- releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/ChangeLog 2018-07-31 09:25:02 UTC (rev 234416)
+++ releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/ChangeLog 2018-07-31 09:25:12 UTC (rev 234417)
@@ -1,3 +1,25 @@
+2018-05-30 Keith Miller <[email protected]>
+
+ LLInt get_by_id prototype caching doesn't properly handle changes
+ https://bugs.webkit.org/show_bug.cgi?id=186112
+
+ Reviewed by Filip Pizlo.
+
+ The caching would sometimes fail to track that a prototype had changed
+ and wouldn't update its set of watchpoints.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::finalizeLLIntInlineCaches):
+ * bytecode/CodeBlock.h:
+ * bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h:
+ (JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::key const):
+ * bytecode/ObjectPropertyConditionSet.h:
+ (JSC::ObjectPropertyConditionSet::size const):
+ * bytecode/Watchpoint.h:
+ (JSC::Watchpoint::Watchpoint): Deleted.
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::setupGetByIdPrototypeCache):
+
2018-05-25 Mark Lam <[email protected]>
for-in loops should preserve and restore the TDZ stack for each of its internal loops.
Modified: releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/bytecode/CodeBlock.cpp (234416 => 234417)
--- releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/bytecode/CodeBlock.cpp 2018-07-31 09:25:02 UTC (rev 234416)
+++ releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/bytecode/CodeBlock.cpp 2018-07-31 09:25:12 UTC (rev 234417)
@@ -1241,9 +1241,7 @@
for (size_t size = propertyAccessInstructions.size(), i = 0; i < size; ++i) {
Instruction* curInstruction = &instructions()[propertyAccessInstructions[i]];
switch (Interpreter::getOpcodeID(curInstruction[0])) {
- case op_get_by_id:
- case op_get_by_id_proto_load:
- case op_get_by_id_unset: {
+ case op_get_by_id: {
StructureID oldStructureID = curInstruction[4].u.structureID;
if (!oldStructureID || Heap::isMarked(vm.heap.structureIDTable().get(oldStructureID)))
break;
@@ -1282,6 +1280,8 @@
// 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_get_by_id_proto_load:
+ case op_get_by_id_unset:
case op_get_array_length:
break;
case op_to_this:
@@ -1339,8 +1339,27 @@
// We can't just remove all the sets when we clear the caches since we might have created a watchpoint set
// then cleared the cache without GCing in between.
- m_llintGetByIdWatchpointMap.removeIf([](const StructureWatchpointMap::KeyValuePairType& pair) -> bool {
- return !Heap::isMarked(pair.key);
+ m_llintGetByIdWatchpointMap.removeIf([&] (const StructureWatchpointMap::KeyValuePairType& pair) -> bool {
+ auto clear = [&] () {
+ Instruction* instruction = std::get<1>(pair.key);
+ OpcodeID opcode = Interpreter::getOpcodeID(*instruction);
+ if (opcode == op_get_by_id_proto_load || opcode == op_get_by_id_unset) {
+ if (Options::verboseOSR())
+ dataLogF("Clearing LLInt property access.\n");
+ clearLLIntGetByIdCache(instruction);
+ }
+ return true;
+ };
+
+ if (!Heap::isMarked(std::get<0>(pair.key)))
+ return clear();
+
+ for (const LLIntPrototypeLoadAdaptiveStructureWatchpoint* watchpoint : pair.value) {
+ if (!watchpoint->key().isStillLive())
+ return clear();
+ }
+
+ return false;
});
for (unsigned i = 0; i < m_llintCallLinkInfos.size(); ++i) {
Modified: releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/bytecode/CodeBlock.h (234416 => 234417)
--- releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/bytecode/CodeBlock.h 2018-07-31 09:25:02 UTC (rev 234416)
+++ releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/bytecode/CodeBlock.h 2018-07-31 09:25:12 UTC (rev 234417)
@@ -625,7 +625,7 @@
return m_llintExecuteCounter;
}
- typedef HashMap<Structure*, Bag<LLIntPrototypeLoadAdaptiveStructureWatchpoint>> StructureWatchpointMap;
+ typedef HashMap<std::tuple<Structure*, Instruction*>, Bag<LLIntPrototypeLoadAdaptiveStructureWatchpoint>> StructureWatchpointMap;
StructureWatchpointMap& llintGetByIdWatchpointMap() { return m_llintGetByIdWatchpointMap; }
// Functions for controlling when tiered compilation kicks in. This
Modified: releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h (234416 => 234417)
--- releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h 2018-07-31 09:25:02 UTC (rev 234416)
+++ releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h 2018-07-31 09:25:12 UTC (rev 234417)
@@ -33,16 +33,19 @@
class LLIntPrototypeLoadAdaptiveStructureWatchpoint : public Watchpoint {
public:
+ LLIntPrototypeLoadAdaptiveStructureWatchpoint() = default;
LLIntPrototypeLoadAdaptiveStructureWatchpoint(const ObjectPropertyCondition&, Instruction*);
void install();
+ const ObjectPropertyCondition& key() const { return m_key; }
+
protected:
void fireInternal(const FireDetail&) override;
private:
ObjectPropertyCondition m_key;
- Instruction* m_getByIdInstruction;
+ Instruction* m_getByIdInstruction { nullptr };
};
} // namespace JSC
Modified: releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.h (234416 => 234417)
--- releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.h 2018-07-31 09:25:02 UTC (rev 234416)
+++ releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.h 2018-07-31 09:25:12 UTC (rev 234417)
@@ -67,7 +67,8 @@
}
bool isValidAndWatchable() const;
-
+
+ size_t size() const { return m_data ? m_data->vector.size() : 0; }
bool isEmpty() const
{
return !m_data;
Modified: releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/bytecode/Watchpoint.h (234416 => 234417)
--- releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/bytecode/Watchpoint.h 2018-07-31 09:25:02 UTC (rev 234416)
+++ releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/bytecode/Watchpoint.h 2018-07-31 09:25:12 UTC (rev 234417)
@@ -68,9 +68,7 @@
WTF_MAKE_NONCOPYABLE(Watchpoint);
WTF_MAKE_FAST_ALLOCATED;
public:
- Watchpoint()
- {
- }
+ Watchpoint() = default;
virtual ~Watchpoint();
Modified: releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (234416 => 234417)
--- releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2018-07-31 09:25:02 UTC (rev 234416)
+++ releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2018-07-31 09:25:12 UTC (rev 234417)
@@ -671,15 +671,18 @@
PropertyOffset offset = invalidOffset;
CodeBlock::StructureWatchpointMap& watchpointMap = codeBlock->llintGetByIdWatchpointMap();
- auto result = watchpointMap.add(structure, Bag<LLIntPrototypeLoadAdaptiveStructureWatchpoint>());
+ Bag<LLIntPrototypeLoadAdaptiveStructureWatchpoint> watchpoints;
for (ObjectPropertyCondition condition : conditions) {
if (!condition.isWatchable())
return;
if (condition.condition().kind() == PropertyCondition::Presence)
offset = condition.condition().offset();
- result.iterator->value.add(condition, pc)->install();
+ watchpoints.add(condition, pc)->install();
}
+
ASSERT((offset == invalidOffset) == slot.isUnset());
+ auto result = watchpointMap.add(std::make_tuple(structure, pc), WTFMove(watchpoints));
+ ASSERT_UNUSED(result, result.isNewEntry);
ConcurrentJSLocker locker(codeBlock->m_lock);
Modified: releases/WebKitGTK/webkit-2.20/Source/WTF/ChangeLog (234416 => 234417)
--- releases/WebKitGTK/webkit-2.20/Source/WTF/ChangeLog 2018-07-31 09:25:02 UTC (rev 234416)
+++ releases/WebKitGTK/webkit-2.20/Source/WTF/ChangeLog 2018-07-31 09:25:12 UTC (rev 234417)
@@ -1,3 +1,19 @@
+2018-05-30 Keith Miller <[email protected]>
+
+ LLInt get_by_id prototype caching doesn't properly handle changes
+ https://bugs.webkit.org/show_bug.cgi?id=186112
+
+ Reviewed by Filip Pizlo.
+
+ Mark some methods const.
+
+ * wtf/Bag.h:
+ (WTF::Bag::begin const):
+ (WTF::Bag::end const):
+ (WTF::Bag::unwrappedHead const):
+ (WTF::Bag::end): Deleted.
+ (WTF::Bag::unwrappedHead): Deleted.
+
2018-04-20 JF Bastien <[email protected]>
Handle more JSON stringify OOM
Modified: releases/WebKitGTK/webkit-2.20/Source/WTF/wtf/Bag.h (234416 => 234417)
--- releases/WebKitGTK/webkit-2.20/Source/WTF/wtf/Bag.h 2018-07-31 09:25:02 UTC (rev 234416)
+++ releases/WebKitGTK/webkit-2.20/Source/WTF/wtf/Bag.h 2018-07-31 09:25:12 UTC (rev 234417)
@@ -138,13 +138,21 @@
result.m_node = unwrappedHead();
return result;
}
+
+ const iterator begin() const
+ {
+ iterator result;
+ result.m_node = unwrappedHead();
+ return result;
+ }
+
+
+ iterator end() const { return iterator(); }
- iterator end() { return iterator(); }
-
bool isEmpty() const { return !m_head; }
private:
- Node* unwrappedHead() { return PtrTraits::unwrap(m_head); }
+ Node* unwrappedHead() const { return PtrTraits::unwrap(m_head); }
typename PtrTraits::StorageType m_head { nullptr };
};