Changeset 217429 in webkit
- Timestamp:
- May 25, 2017, 10:03:13 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r217314 r217429 1 2017-05-25 Mark Lam <mark.lam@apple.com> 2 3 ObjectToStringAdaptiveInferredPropertyValueWatchpoint should not reinstall itself nor handleFire if it's dying shortly. 4 https://bugs.webkit.org/show_bug.cgi?id=172548 5 <rdar://problem/31458393> 6 7 Reviewed by Filip Pizlo. 8 9 * stress/regress-172548.patch: Added. 10 1 11 2017-05-23 Saam Barati <sbarati@apple.com> 2 12 -
trunk/Source/JavaScriptCore/ChangeLog
r217314 r217429 1 2017-05-25 Mark Lam <mark.lam@apple.com> 2 3 ObjectToStringAdaptiveInferredPropertyValueWatchpoint should not reinstall itself nor handleFire if it's dying shortly. 4 https://bugs.webkit.org/show_bug.cgi?id=172548 5 <rdar://problem/31458393> 6 7 Reviewed by Filip Pizlo. 8 9 Consider the following scenario: 10 11 1. A ObjectToStringAdaptiveInferredPropertyValueWatchpoint O1, watches for 12 structure transitions, e.g. structure S2 transitioning to structure S3. 13 In this case, O1 would be installed in S2's watchpoint set. 14 2. When the structure transition happens, structure S2 will fire watchpoint O1. 15 3. O1's handler will normally re-install itself in the watchpoint set of the new 16 "transitioned to" structure S3. 17 4. "Installation" here requires writing into the StructureRareData SD3 of the new 18 structure S3. If SD3 does not exist yet, the installation process will trigger 19 the allocation of StructureRareData SD3. 20 5. It is possible that the Structure S1, and StructureRareData SD1 that owns the 21 ObjectToStringAdaptiveInferredPropertyValueWatchpoint O1 is no longer reachable 22 by the GC, and therefore will be collected soon. 23 6. The allocation of SD3 in (4) may trigger the sweeping of the StructureRareData 24 SD1. This, in turn, triggers the deletion of the 25 ObjectToStringAdaptiveInferredPropertyValueWatchpoint O1. 26 27 After O1 is deleted in (6) and SD3 is allocated in (4), execution continues in 28 AdaptiveInferredPropertyValueWatchpointBase::fire() where O1 gets installed in 29 structure S3's watchpoint set. This is obviously incorrect because O1 is already 30 deleted. The result is that badness happens later when S3's watchpoint set fires 31 its watchpoints and accesses the deleted O1. 32 33 The fix is to enhance AdaptiveInferredPropertyValueWatchpointBase::fire() to 34 check if "this" is still valid before proceeding to re-install itself or to 35 invoke its handleFire() method. 36 37 ObjectToStringAdaptiveInferredPropertyValueWatchpoint (which extends 38 AdaptiveInferredPropertyValueWatchpointBase) will override its isValid() method, 39 and return false its owner StructureRareData is no longer reachable by the GC. 40 This ensures that it won't be deleted while it's installed to any watchpoint set. 41 42 Additional considerations and notes: 43 1. In the above, I talked about the ObjectToStringAdaptiveInferredPropertyValueWatchpoint 44 being installed in watchpoint sets. What actually happens is that 45 ObjectToStringAdaptiveInferredPropertyValueWatchpoint has 2 members 46 (m_structureWatchpoint and m_propertyWatchpoint) which may be installed in 47 watchpoint sets. The ObjectToStringAdaptiveInferredPropertyValueWatchpoint is 48 not itself a Watchpoint object. 49 50 But for brevity, in the above, I refer to the ObjectToStringAdaptiveInferredPropertyValueWatchpoint 51 instead of its Watchpoint members. The description of the issue is still 52 accurate given the life-cycle of the Watchpoint members are embedded in the 53 enclosing ObjectToStringAdaptiveInferredPropertyValueWatchpoint object, and 54 hence, they share the same life-cycle. 55 56 2. The top of AdaptiveInferredPropertyValueWatchpointBase::fire() removes its 57 m_structureWatchpoint and m_propertyWatchpoint if they have been added to any 58 watchpoint sets. This is safe to do even if the owner StructureRareData is no 59 longer reachable by the GC. 60 61 This is because the only way we can get to AdaptiveInferredPropertyValueWatchpointBase::fire() 62 is if its Watchpoint members are still installed in some watchpoint set that 63 fired. This means that the AdaptiveInferredPropertyValueWatchpointBase 64 instance has not been deleted yet, because its destructor will automatically 65 remove the Watchpoint members from any watchpoint sets. 66 67 * bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp: 68 (JSC::AdaptiveInferredPropertyValueWatchpointBase::fire): 69 (JSC::AdaptiveInferredPropertyValueWatchpointBase::isValid): 70 * bytecode/AdaptiveInferredPropertyValueWatchpointBase.h: 71 * heap/FreeList.cpp: 72 (JSC::FreeList::contains): 73 * heap/FreeList.h: 74 * heap/HeapCell.h: 75 * heap/HeapCellInlines.h: 76 (JSC::HeapCell::isLive): 77 * heap/MarkedAllocator.h: 78 (JSC::MarkedAllocator::isFreeListedCell): 79 * heap/MarkedBlock.h: 80 * heap/MarkedBlockInlines.h: 81 (JSC::MarkedBlock::Handle::isFreeListedCell): 82 * runtime/StructureRareData.cpp: 83 (JSC::ObjectToStringAdaptiveInferredPropertyValueWatchpoint::isValid): 84 1 85 2017-05-23 Saam Barati <sbarati@apple.com> 2 86 -
trunk/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp
r205462 r217429 1 1 /* 2 * Copyright (C) 2015 Apple Inc. All rights reserved.2 * Copyright (C) 2015-2017 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 58 58 m_propertyWatchpoint.remove(); 59 59 60 if (!isValid()) 61 return; 62 60 63 if (m_key.isWatchable(PropertyCondition::EnsureWatchability)) { 61 64 install(); … … 64 67 65 68 handleFire(detail); 69 } 70 71 bool AdaptiveInferredPropertyValueWatchpointBase::isValid() const 72 { 73 return true; 66 74 } 67 75 -
trunk/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.h
r206525 r217429 1 1 /* 2 * Copyright (C) 2015 Apple Inc. All rights reserved.2 * Copyright (C) 2015-2017 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 47 47 48 48 protected: 49 virtual bool isValid() const; 49 50 virtual void handleFire(const FireDetail&) = 0; 50 51 -
trunk/Source/JavaScriptCore/heap/FreeList.cpp
r205462 r217429 1 1 /* 2 * Copyright (C) 2016 Apple Inc. All rights reserved.2 * Copyright (C) 2016-2017 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 namespace JSC { 30 30 31 bool FreeList::contains(const void* target) const 32 { 33 if (remaining) { 34 const void* start = (payloadEnd - remaining); 35 const void* end = payloadEnd; 36 return (start <= target) && (target < end); 37 } 38 39 FreeCell* candidate = head; 40 while (candidate) { 41 if (candidate == target) 42 return true; 43 candidate = candidate->next; 44 } 45 46 return false; 47 } 48 31 49 void FreeList::dump(PrintStream& out) const 32 50 { -
trunk/Source/JavaScriptCore/heap/FreeList.h
r205462 r217429 1 1 /* 2 * Copyright (C) 2016 Apple Inc. All rights reserved.2 * Copyright (C) 2016-2017 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 81 81 return *this != FreeList(); 82 82 } 83 83 84 bool contains(const void* target) const; 85 84 86 bool allocationWillFail() const { return !head && !remaining; } 85 87 bool allocationWillSucceed() const { return !allocationWillFail(); } -
trunk/Source/JavaScriptCore/heap/HeapCell.h
r213773 r217429 48 48 void zap() { *reinterpret_cast_ptr<uintptr_t**>(this) = 0; } 49 49 bool isZapped() const { return !*reinterpret_cast_ptr<uintptr_t* const*>(this); } 50 50 51 bool isLive(); 52 51 53 bool isLargeAllocation() const; 52 54 CellContainer cellContainer() const; -
trunk/Source/JavaScriptCore/heap/HeapCellInlines.h
r205666 r217429 1 1 /* 2 * Copyright (C) 2016 Apple Inc. All rights reserved.2 * Copyright (C) 2016-2017 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 #include "HeapCell.h" 30 30 #include "LargeAllocation.h" 31 #include "MarkedBlock .h"31 #include "MarkedBlockInlines.h" 32 32 #include "VM.h" 33 33 34 34 namespace JSC { 35 36 ALWAYS_INLINE bool HeapCell::isLive() 37 { 38 if (isLargeAllocation()) 39 return largeAllocation().isLive(); 40 auto& markedBlockHandle = markedBlock().handle(); 41 if (markedBlockHandle.isFreeListed()) 42 return !markedBlockHandle.isFreeListedCell(this); 43 return markedBlockHandle.isLive(this); 44 } 35 45 36 46 ALWAYS_INLINE bool HeapCell::isLargeAllocation() const -
trunk/Source/JavaScriptCore/heap/MarkedAllocator.h
r213883 r217429 157 157 Heap* heap() { return m_heap; } 158 158 159 bool isFreeListedCell(const void* target) const { return m_freeList.contains(target); } 160 159 161 template<typename Functor> void forEachBlock(const Functor&); 160 162 template<typename Functor> void forEachNotEmptyBlock(const Functor&); -
trunk/Source/JavaScriptCore/heap/MarkedBlock.h
r215637 r217429 167 167 bool isLiveCell(const void*); 168 168 169 bool isFreeListedCell(const void* target) const; 170 169 171 bool isNewlyAllocated(const void*); 170 172 void setNewlyAllocated(const void*); -
trunk/Source/JavaScriptCore/heap/MarkedBlockInlines.h
r210844 r217429 116 116 return false; 117 117 return isLive(markingVersion, isMarking, static_cast<const HeapCell*>(p)); 118 } 119 120 inline bool MarkedBlock::Handle::isFreeListedCell(const void* target) const 121 { 122 ASSERT(isFreeListed()); 123 return m_allocator->isFreeListedCell(target); 118 124 } 119 125 -
trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp
r217108 r217429 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013-2017 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 91 91 92 92 private: 93 bool isValid() const override; 93 94 void handleFire(const FireDetail&) override; 94 95 … … 213 214 } 214 215 216 bool ObjectToStringAdaptiveInferredPropertyValueWatchpoint::isValid() const 217 { 218 return m_structureRareData->isLive(); 219 } 220 215 221 void ObjectToStringAdaptiveInferredPropertyValueWatchpoint::handleFire(const FireDetail& detail) 216 222 {
Note:
See TracChangeset
for help on using the changeset viewer.