Changeset 159395 in webkit
- Timestamp:
- Nov 17, 2013 6:10:42 PM (10 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r159394 r159395 1 2013-11-16 Filip Pizlo <fpizlo@apple.com> 2 3 Simplify WatchpointSet state tracking 4 https://bugs.webkit.org/show_bug.cgi?id=124465 5 6 Reviewed by Sam Weinig. 7 8 We previously represented the state of watchpoint sets using two booleans. But that 9 makes it awkward to case over the state. 10 11 We also previously supported a watchpoint set being both watched and invalidated. We 12 never used that capability, and its presence was just purely confusing. 13 14 This turns the whole thing into an enum. 15 16 * assembler/MacroAssemblerARM64.h: 17 (JSC::MacroAssemblerARM64::branch8): 18 * assembler/MacroAssemblerARMv7.h: 19 (JSC::MacroAssemblerARMv7::branch8): 20 * assembler/MacroAssemblerX86.h: 21 (JSC::MacroAssemblerX86::branch8): 22 * assembler/MacroAssemblerX86_64.h: 23 (JSC::MacroAssemblerX86_64::branch8): 24 * bytecode/Watchpoint.cpp: 25 (JSC::WatchpointSet::WatchpointSet): 26 (JSC::WatchpointSet::add): 27 (JSC::WatchpointSet::notifyWriteSlow): 28 (JSC::InlineWatchpointSet::inflateSlow): 29 * bytecode/Watchpoint.h: 30 (JSC::WatchpointSet::state): 31 (JSC::WatchpointSet::isStillValid): 32 (JSC::WatchpointSet::startWatching): 33 (JSC::WatchpointSet::notifyWrite): 34 (JSC::WatchpointSet::addressOfState): 35 (JSC::InlineWatchpointSet::InlineWatchpointSet): 36 (JSC::InlineWatchpointSet::hasBeenInvalidated): 37 (JSC::InlineWatchpointSet::startWatching): 38 (JSC::InlineWatchpointSet::notifyWrite): 39 (JSC::InlineWatchpointSet::decodeState): 40 (JSC::InlineWatchpointSet::encodeState): 41 * jit/JITPropertyAccess.cpp: 42 (JSC::JIT::emitVarInjectionCheck): 43 * jit/JITPropertyAccess32_64.cpp: 44 (JSC::JIT::emitVarInjectionCheck): 45 * llint/LowLevelInterpreter.asm: 46 * llint/LowLevelInterpreter32_64.asm: 47 * llint/LowLevelInterpreter64.asm: 48 * runtime/JSFunction.cpp: 49 (JSC::JSFunction::JSFunction): 50 * runtime/JSFunctionInlines.h: 51 (JSC::JSFunction::JSFunction): 52 * runtime/JSGlobalObject.cpp: 53 (JSC::JSGlobalObject::JSGlobalObject): 54 * runtime/Structure.cpp: 55 (JSC::Structure::Structure): 56 * runtime/SymbolTable.cpp: 57 (JSC::SymbolTableEntry::attemptToWatch): 58 * runtime/SymbolTable.h: 59 1 60 2013-11-16 Filip Pizlo <fpizlo@apple.com> 2 61 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h
r159261 r159395 1639 1639 } 1640 1640 1641 Jump branch8(RelationalCondition cond, AbsoluteAddress left, TrustedImm32 right) 1642 { 1643 ASSERT(!(0xffffff00 & right.m_value)); 1644 load8(left, getCachedMemoryTempRegisterIDAndInvalidate()); 1645 return branch32(cond, memoryTempRegister, right); 1646 } 1647 1641 1648 Jump branchTest32(ResultCondition cond, RegisterID reg, RegisterID mask) 1642 1649 { -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
r158208 r159395 1378 1378 } 1379 1379 1380 Jump branch8(RelationalCondition cond, AbsoluteAddress left, TrustedImm32 right) 1381 { 1382 load8(left, addressTempRegister); 1383 return branch32(cond, addressTempRegister, right); 1384 } 1385 1380 1386 Jump branchTest32(ResultCondition cond, RegisterID reg, RegisterID mask) 1381 1387 { -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86.h
r158057 r159395 57 57 using MacroAssemblerX86Common::storeDouble; 58 58 using MacroAssemblerX86Common::convertInt32ToDouble; 59 using MacroAssemblerX86Common::branch8; 59 60 using MacroAssemblerX86Common::branchTest8; 60 61 … … 214 215 } 215 216 217 Jump branch8(RelationalCondition cond, AbsoluteAddress left, TrustedImm32 right) 218 { 219 m_assembler.cmpb_im(right.m_value, left.m_ptr); 220 return Jump(m_assembler.jCC(x86Condition(cond))); 221 } 222 216 223 Jump branchTest8(ResultCondition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1)) 217 224 { -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
r158975 r159395 612 612 } 613 613 614 using MacroAssemblerX86Common::branch8; 615 Jump branch8(RelationalCondition cond, AbsoluteAddress left, TrustedImm32 right) 616 { 617 MacroAssemblerX86Common::move(TrustedImmPtr(left.m_ptr), scratchRegister); 618 return MacroAssemblerX86Common::branch8(cond, Address(scratchRegister), right); 619 } 620 614 621 using MacroAssemblerX86Common::branchTest8; 615 622 Jump branchTest8(ResultCondition cond, ExtendedAddress address, TrustedImm32 mask = TrustedImm32(-1)) -
trunk/Source/JavaScriptCore/bytecode/Watchpoint.cpp
r158341 r159395 39 39 } 40 40 41 WatchpointSet::WatchpointSet(InitialWatchpointSetMode mode) 42 : m_isWatched(mode == InitializedWatching) 43 , m_isInvalidated(false) 41 WatchpointSet::WatchpointSet(WatchpointState state) 42 : m_state(state) 44 43 { 45 44 } … … 58 57 { 59 58 ASSERT(!isCompilationThread()); 59 ASSERT(state() != IsInvalidated); 60 60 if (!watchpoint) 61 61 return; 62 62 m_set.push(watchpoint); 63 m_ isWatched = true;63 m_state = IsWatched; 64 64 } 65 65 66 66 void WatchpointSet::notifyWriteSlow() 67 67 { 68 ASSERT( m_isWatched);68 ASSERT(state() == IsWatched); 69 69 70 70 fireAllWatchpoints(); 71 m_isWatched = false; 72 m_isInvalidated = true; 71 m_state = IsInvalidated; 73 72 WTF::storeStoreFence(); 74 73 } … … 89 88 ASSERT(isThin()); 90 89 ASSERT(!isCompilationThread()); 91 WatchpointSet* fat = adoptRef(new WatchpointSet(InitializedBlind)).leakRef(); 92 if (m_data & IsInvalidatedFlag) 93 fat->m_isInvalidated = true; 94 if (m_data & IsWatchedFlag) 95 fat->m_isWatched = true; 90 WatchpointSet* fat = adoptRef(new WatchpointSet(decodeState(m_data))).leakRef(); 96 91 WTF::storeStoreFence(); 97 92 m_data = bitwise_cast<uintptr_t>(fat); -
trunk/Source/JavaScriptCore/bytecode/Watchpoint.h
r158341 r159395 46 46 }; 47 47 48 enum InitialWatchpointSetMode { InitializedWatching, InitializedBlind }; 48 enum WatchpointState { 49 ClearWatchpoint, 50 IsWatched, 51 IsInvalidated 52 }; 49 53 50 54 class InlineWatchpointSet; … … 53 57 friend class LLIntOffsetsExtractor; 54 58 public: 55 WatchpointSet( InitialWatchpointSetMode);59 WatchpointSet(WatchpointState); 56 60 ~WatchpointSet(); // Note that this will not fire any of the watchpoints; if you need to know when a WatchpointSet dies then you need a separate mechanism for this. 61 62 WatchpointState state() const { return static_cast<WatchpointState>(m_state); } 57 63 58 64 // It is safe to call this from another thread. It may return true … … 65 71 { 66 72 WTF::loadLoadFence(); 67 return !m_isInvalidated;73 return state() != IsInvalidated; 68 74 } 69 75 // Like isStillValid(), may be called from another thread. … … 80 86 // probably don't want to set watchpoints, since we typically don't want to 81 87 // set watchpoints that we believe will actually be fired. 82 void startWatching() { m_isWatched = true; } 88 void startWatching() 89 { 90 ASSERT(state() != IsInvalidated); 91 m_state = IsWatched; 92 } 83 93 84 94 void notifyWrite() 85 95 { 86 if ( !m_isWatched)96 if (state() != IsWatched) 87 97 return; 88 98 notifyWriteSlow(); 89 99 } 90 91 bool* addressOfIsWatched() { return &m_isWatched; } 92 bool* addressOfIsInvalidated() { return &m_isInvalidated; } 100 101 int8_t* addressOfState() { return &m_state; } 93 102 94 103 JS_EXPORT_PRIVATE void notifyWriteSlow(); // Call only if you've checked isWatched. … … 100 109 101 110 SentinelLinkedList<Watchpoint, BasicRawSentinelNode<Watchpoint>> m_set; 102 bool m_isWatched; 103 bool m_isInvalidated; 111 int8_t m_state; 104 112 }; 105 113 … … 126 134 WTF_MAKE_NONCOPYABLE(InlineWatchpointSet); 127 135 public: 128 InlineWatchpointSet( InitialWatchpointSetMode mode)129 : m_data( (mode == InitializedWatching ? IsWatchedFlag : 0) | IsThinFlag)136 InlineWatchpointSet(WatchpointState state) 137 : m_data(encodeState(state)) 130 138 { 131 139 } … … 149 157 return fat(data)->hasBeenInvalidated(); 150 158 } 151 return d ata & IsInvalidatedFlag;159 return decodeState(data) == IsInvalidated; 152 160 } 153 161 … … 166 174 return; 167 175 } 168 m_data |= IsWatchedFlag; 176 ASSERT(decodeState(m_data) != IsInvalidated); 177 m_data = encodeState(IsWatched); 169 178 } 170 179 … … 175 184 return; 176 185 } 177 if ( !(m_data & IsWatchedFlag))178 return; 179 m_data |= IsInvalidatedFlag;186 if (decodeState(m_data) == ClearWatchpoint) 187 return; 188 m_data = encodeState(IsInvalidated); 180 189 WTF::storeStoreFence(); 181 190 } … … 183 192 private: 184 193 static const uintptr_t IsThinFlag = 1; 185 static const uintptr_t IsInvalidatedFlag = 2;186 static const uintptr_t IsWatchedFlag = 4;194 static const uintptr_t StateMask = 6; 195 static const uintptr_t StateShift = 1; 187 196 188 197 static bool isThin(uintptr_t data) { return data & IsThinFlag; } 189 198 static bool isFat(uintptr_t data) { return !isThin(data); } 199 200 static WatchpointState decodeState(uintptr_t data) 201 { 202 ASSERT(isThin(data)); 203 return static_cast<WatchpointState>((data & StateMask) >> StateShift); 204 } 205 206 static uintptr_t encodeState(WatchpointState state) 207 { 208 return (state << StateShift) | IsThinFlag; 209 } 190 210 191 211 bool isThin() const { return isThin(m_data); } -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
r159091 r159395 638 638 if (!needsVarInjectionChecks) 639 639 return; 640 addSlowCase(branch Test8(NonZero, AbsoluteAddress(m_codeBlock->globalObject()->varInjectionWatchpoint()->addressOfIsInvalidated())));640 addSlowCase(branch8(Equal, AbsoluteAddress(m_codeBlock->globalObject()->varInjectionWatchpoint()->addressOfState()), TrustedImm32(IsInvalidated))); 641 641 } 642 642 -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
r159091 r159395 668 668 if (!needsVarInjectionChecks) 669 669 return; 670 addSlowCase(branch Test8(NonZero, AbsoluteAddress(m_codeBlock->globalObject()->varInjectionWatchpoint()->addressOfIsInvalidated())));670 addSlowCase(branch8(Equal, AbsoluteAddress(m_codeBlock->globalObject()->varInjectionWatchpoint()->addressOfState()), TrustedImm32(IsInvalidated))); 671 671 } 672 672 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r159276 r159395 71 71 const LowestTag = DeletedValueTag 72 72 end 73 74 # Watchpoint states 75 const ClearWatchpoint = 0 76 const IsWatched = 1 77 const IsInvalidated = 2 73 78 74 79 # Some register conventions. -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
r159346 r159395 1988 1988 loadp CodeBlock::m_globalObject[t0], t0 1989 1989 loadp JSGlobalObject::m_varInjectionWatchpoint[t0], t0 1990 b tbnz WatchpointSet::m_isInvalidated[t0], slowPath1990 bbeq WatchpointSet::m_state[t0], IsInvalidated, slowPath 1991 1991 end 1992 1992 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r159346 r159395 1801 1801 loadp CodeBlock::m_globalObject[t0], t0 1802 1802 loadp JSGlobalObject::m_varInjectionWatchpoint[t0], t0 1803 b tbnz WatchpointSet::m_isInvalidated[t0], slowPath1803 bbeq WatchpointSet::m_state[t0], IsInvalidated, slowPath 1804 1804 end 1805 1805 -
trunk/Source/JavaScriptCore/runtime/JSFunction.cpp
r157330 r159395 97 97 // clobbered once, and if it's clobbered more than once, that will probably only occur 98 98 // before we started optimizing, anyway. 99 , m_allocationProfileWatchpoint( InitializedBlind)99 , m_allocationProfileWatchpoint(ClearWatchpoint) 100 100 { 101 101 } -
trunk/Source/JavaScriptCore/runtime/JSFunctionInlines.h
r153188 r159395 36 36 , m_executable(vm, this, executable) 37 37 , m_scope(vm, this, scope) 38 , m_allocationProfileWatchpoint( InitializedBlind) // See comment in JSFunction.cpp concerning the reason for using InitializedBlind as opposed to InitializedWatching.38 , m_allocationProfileWatchpoint(ClearWatchpoint) // See comment in JSFunction.cpp concerning the reason for using ClearWatchpoint as opposed to IsWatched. 39 39 { 40 40 } -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r159031 r159395 151 151 JSGlobalObject::JSGlobalObject(VM& vm, Structure* structure, const GlobalObjectMethodTable* globalObjectMethodTable) 152 152 : Base(vm, structure, 0) 153 , m_masqueradesAsUndefinedWatchpoint(adoptRef(new WatchpointSet(I nitializedWatching)))154 , m_havingABadTimeWatchpoint(adoptRef(new WatchpointSet(I nitializedWatching)))155 , m_varInjectionWatchpoint(adoptRef(new WatchpointSet(I nitializedWatching)))153 , m_masqueradesAsUndefinedWatchpoint(adoptRef(new WatchpointSet(IsWatched))) 154 , m_havingABadTimeWatchpoint(adoptRef(new WatchpointSet(IsWatched))) 155 , m_varInjectionWatchpoint(adoptRef(new WatchpointSet(IsWatched))) 156 156 , m_weakRandom(Options::forceWeakRandomSeed() ? Options::forcedWeakRandomSeed() : static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0))) 157 157 , m_evalEnabled(true) -
trunk/Source/JavaScriptCore/runtime/Structure.cpp
r157539 r159395 159 159 , m_prototype(vm, this, prototype) 160 160 , m_classInfo(classInfo) 161 , m_transitionWatchpointSet(I nitializedWatching)161 , m_transitionWatchpointSet(IsWatched) 162 162 , m_offset(invalidOffset) 163 163 , m_typeInfo(typeInfo) … … 186 186 , m_prototype(vm, this, jsNull()) 187 187 , m_classInfo(info()) 188 , m_transitionWatchpointSet(I nitializedWatching)188 , m_transitionWatchpointSet(IsWatched) 189 189 , m_offset(invalidOffset) 190 190 , m_typeInfo(CompoundType, OverridesVisitChildren) … … 208 208 , m_prototype(vm, this, previous->storedPrototype()) 209 209 , m_classInfo(previous->m_classInfo) 210 , m_transitionWatchpointSet(I nitializedWatching)210 , m_transitionWatchpointSet(IsWatched) 211 211 , m_offset(invalidOffset) 212 212 , m_typeInfo(previous->typeInfo().type(), previous->typeInfo().flags() & ~StructureHasRareData) -
trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp
r159116 r159395 73 73 FatEntry* entry = inflate(); 74 74 if (!entry->m_watchpoints) 75 entry->m_watchpoints = adoptRef(new WatchpointSet(InitializedWatching)); 76 } 77 78 bool* SymbolTableEntry::addressOfIsWatched() 79 { 80 ASSERT(couldBeWatched()); 81 return fatEntry()->m_watchpoints->addressOfIsWatched(); 75 entry->m_watchpoints = adoptRef(new WatchpointSet(IsWatched)); 82 76 } 83 77 -
trunk/Source/JavaScriptCore/runtime/SymbolTable.h
r159394 r159395 231 231 void attemptToWatch(); 232 232 233 bool* addressOfIsWatched();234 235 233 void addWatchpoint(Watchpoint*); 236 234
Note: See TracChangeset
for help on using the changeset viewer.