Changeset 120172 in webkit for trunk/Source/JavaScriptCore/ChangeLog
- Timestamp:
- Jun 13, 2012, 1:20:39 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r120159 r120172 1 2012-06-12 Filip Pizlo <[email protected]> 2 3 DFG should be able to set watchpoints on global variables 4 https://bugs.webkit.org/show_bug.cgi?id=88692 5 6 Reviewed by Geoffrey Garen. 7 8 This implements global variable constant folding by allowing the optimizing 9 compiler to set a "watchpoint" on globals that it wishes to constant fold. 10 If the watchpoint fires, then an OSR exit is forced by overwriting the 11 machine code that the optimizing compiler generated with a jump. 12 13 As such, this patch is adding quite a bit of stuff: 14 15 - Jump replacement on those hardware targets supported by the optimizing 16 JIT. It is now possible to patch in a jump instruction over any recorded 17 watchpoint label. The jump must be "local" in the sense that it must be 18 within the range of the largest jump distance supported by a one 19 instruction jump. 20 21 - WatchpointSets and Watchpoints. A Watchpoint is a doubly-linked list node 22 that records the location where a jump must be inserted and the 23 destination to which it should jump. Watchpoints can be added to a 24 WatchpointSet. The WatchpointSet can be fired all at once, which plants 25 all jumps. WatchpointSet also remembers if it had ever been invalidated, 26 which allows for monotonicity: we typically don't want to optimize using 27 watchpoints on something for which watchpoints had previously fired. The 28 act of notifying a WatchpointSet has a trivial fast path in case no 29 Watchpoints are registered (one-byte load+branch). 30 31 - SpeculativeJIT::speculationWatchpoint(). It's like speculationCheck(), 32 except that you don't have to emit branches. But, you need to know what 33 WatchpointSet to add the resulting Watchpoint to. Not everything that 34 you could write a speculationCheck() for will have a WatchpointSet that 35 would get notified if the condition you were speculating against became 36 invalid. 37 38 - SymbolTableEntry now has the ability to refer to a WatchpointSet. It can 39 do so without incurring any space overhead for those entries that don't 40 have WatchpointSets. 41 42 - The bytecode generator infers all global function variables to be 43 watchable, and makes all stores perform the WatchpointSet's write check, 44 and marks all loads as being potentially watchable (i.e. you can compile 45 them to a watchpoint and a constant). 46 47 Put together, this allows for fully sleazy inlining of calls to globally 48 declared functions. The inline prologue will no longer contain the load of 49 the function, or any checks of the function you're calling. I.e. it's 50 pretty much like the kind of inlining you would see in Java or C++. 51 Furthermore, the watchpointing functionality is built to be fairly general, 52 and should allow setting watchpoints on all sorts of interesting things 53 in the future. 54 55 The sleazy inlining means that we will now sometimes inline in code paths 56 that have never executed. Previously, to inline we would have either had 57 to have executed the call (to read the call's inline cache) or have 58 executed the method check (to read the method check's inline cache). Now, 59 we might inline when the callee is a watched global variable. This 60 revealed some humorous bugs. First, constant folding disagreed with CFA 61 over what kinds of operations can clobber (example: code path A is dead 62 but stores a String into variable X, all other code paths store 0 into 63 X, and then you do CompareEq(X, 0) - CFA will say that this is a non- 64 clobbering constant, but constant folding thought it was clobbering 65 because it saw the String prediction). Second, inlining would crash if 66 the inline callee had not been compiled. This patch fixes both bugs, 67 since otherwise run-javascriptcore-tests would report regressions. 68 69 * CMakeLists.txt: 70 * GNUmakefile.list.am: 71 * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: 72 * JavaScriptCore.xcodeproj/project.pbxproj: 73 * Target.pri: 74 * assembler/ARMv7Assembler.h: 75 (ARMv7Assembler): 76 (JSC::ARMv7Assembler::ARMv7Assembler): 77 (JSC::ARMv7Assembler::labelForWatchpoint): 78 (JSC::ARMv7Assembler::label): 79 (JSC::ARMv7Assembler::replaceWithJump): 80 (JSC::ARMv7Assembler::maxJumpReplacementSize): 81 * assembler/AbstractMacroAssembler.h: 82 (JSC): 83 (AbstractMacroAssembler): 84 (Label): 85 (JSC::AbstractMacroAssembler::watchpointLabel): 86 * assembler/AssemblerBuffer.h: 87 * assembler/MacroAssemblerARM.h: 88 (JSC::MacroAssemblerARM::replaceWithJump): 89 (MacroAssemblerARM): 90 (JSC::MacroAssemblerARM::maxJumpReplacementSize): 91 * assembler/MacroAssemblerARMv7.h: 92 (MacroAssemblerARMv7): 93 (JSC::MacroAssemblerARMv7::replaceWithJump): 94 (JSC::MacroAssemblerARMv7::maxJumpReplacementSize): 95 (JSC::MacroAssemblerARMv7::branchTest8): 96 (JSC::MacroAssemblerARMv7::jump): 97 (JSC::MacroAssemblerARMv7::makeBranch): 98 * assembler/MacroAssemblerMIPS.h: 99 (JSC::MacroAssemblerMIPS::replaceWithJump): 100 (MacroAssemblerMIPS): 101 (JSC::MacroAssemblerMIPS::maxJumpReplacementSize): 102 * assembler/MacroAssemblerSH4.h: 103 (JSC::MacroAssemblerSH4::replaceWithJump): 104 (MacroAssemblerSH4): 105 (JSC::MacroAssemblerSH4::maxJumpReplacementSize): 106 * assembler/MacroAssemblerX86.h: 107 (MacroAssemblerX86): 108 (JSC::MacroAssemblerX86::branchTest8): 109 * assembler/MacroAssemblerX86Common.h: 110 (JSC::MacroAssemblerX86Common::replaceWithJump): 111 (MacroAssemblerX86Common): 112 (JSC::MacroAssemblerX86Common::maxJumpReplacementSize): 113 * assembler/MacroAssemblerX86_64.h: 114 (MacroAssemblerX86_64): 115 (JSC::MacroAssemblerX86_64::branchTest8): 116 * assembler/X86Assembler.h: 117 (JSC::X86Assembler::X86Assembler): 118 (X86Assembler): 119 (JSC::X86Assembler::cmpb_im): 120 (JSC::X86Assembler::testb_im): 121 (JSC::X86Assembler::labelForWatchpoint): 122 (JSC::X86Assembler::label): 123 (JSC::X86Assembler::replaceWithJump): 124 (JSC::X86Assembler::maxJumpReplacementSize): 125 (JSC::X86Assembler::X86InstructionFormatter::memoryModRM): 126 * bytecode/CodeBlock.cpp: 127 (JSC::CodeBlock::dump): 128 * bytecode/CodeBlock.h: 129 (JSC::CodeBlock::appendOSRExit): 130 (JSC::CodeBlock::appendSpeculationRecovery): 131 (CodeBlock): 132 (JSC::CodeBlock::appendWatchpoint): 133 (JSC::CodeBlock::numberOfWatchpoints): 134 (JSC::CodeBlock::watchpoint): 135 (DFGData): 136 * bytecode/DFGExitProfile.h: 137 (JSC::DFG::exitKindToString): 138 (JSC::DFG::exitKindIsCountable): 139 * bytecode/Instruction.h: 140 (Instruction): 141 (JSC::Instruction::Instruction): 142 * bytecode/Opcode.h: 143 (JSC): 144 (JSC::padOpcodeName): 145 * bytecode/Watchpoint.cpp: Added. 146 (JSC): 147 (JSC::Watchpoint::~Watchpoint): 148 (JSC::Watchpoint::correctLabels): 149 (JSC::Watchpoint::fire): 150 (JSC::WatchpointSet::WatchpointSet): 151 (JSC::WatchpointSet::~WatchpointSet): 152 (JSC::WatchpointSet::add): 153 (JSC::WatchpointSet::notifyWriteSlow): 154 (JSC::WatchpointSet::fireAllWatchpoints): 155 * bytecode/Watchpoint.h: Added. 156 (JSC): 157 (Watchpoint): 158 (JSC::Watchpoint::Watchpoint): 159 (JSC::Watchpoint::setDestination): 160 (WatchpointSet): 161 (JSC::WatchpointSet::isStillValid): 162 (JSC::WatchpointSet::hasBeenInvalidated): 163 (JSC::WatchpointSet::startWatching): 164 (JSC::WatchpointSet::notifyWrite): 165 (JSC::WatchpointSet::addressOfIsWatched): 166 * bytecompiler/BytecodeGenerator.cpp: 167 (JSC::ResolveResult::checkValidity): 168 (JSC::BytecodeGenerator::addGlobalVar): 169 (JSC::BytecodeGenerator::BytecodeGenerator): 170 (JSC::BytecodeGenerator::resolve): 171 (JSC::BytecodeGenerator::emitResolve): 172 (JSC::BytecodeGenerator::emitResolveWithBase): 173 (JSC::BytecodeGenerator::emitResolveWithThis): 174 (JSC::BytecodeGenerator::emitGetStaticVar): 175 (JSC::BytecodeGenerator::emitPutStaticVar): 176 * bytecompiler/BytecodeGenerator.h: 177 (BytecodeGenerator): 178 * bytecompiler/NodesCodegen.cpp: 179 (JSC::FunctionCallResolveNode::emitBytecode): 180 (JSC::PostfixResolveNode::emitBytecode): 181 (JSC::PrefixResolveNode::emitBytecode): 182 (JSC::ReadModifyResolveNode::emitBytecode): 183 (JSC::AssignResolveNode::emitBytecode): 184 (JSC::ConstDeclNode::emitCodeSingle): 185 * dfg/DFGAbstractState.cpp: 186 (JSC::DFG::AbstractState::execute): 187 (JSC::DFG::AbstractState::clobberStructures): 188 * dfg/DFGAbstractState.h: 189 (AbstractState): 190 (JSC::DFG::AbstractState::didClobber): 191 * dfg/DFGByteCodeParser.cpp: 192 (JSC::DFG::ByteCodeParser::handleInlining): 193 (JSC::DFG::ByteCodeParser::parseBlock): 194 * dfg/DFGCCallHelpers.h: 195 (CCallHelpers): 196 (JSC::DFG::CCallHelpers::setupArguments): 197 * dfg/DFGCSEPhase.cpp: 198 (JSC::DFG::CSEPhase::globalVarWatchpointElimination): 199 (CSEPhase): 200 (JSC::DFG::CSEPhase::globalVarStoreElimination): 201 (JSC::DFG::CSEPhase::performNodeCSE): 202 * dfg/DFGCapabilities.h: 203 (JSC::DFG::canCompileOpcode): 204 * dfg/DFGConstantFoldingPhase.cpp: 205 (JSC::DFG::ConstantFoldingPhase::run): 206 * dfg/DFGCorrectableJumpPoint.h: 207 (JSC::DFG::CorrectableJumpPoint::isSet): 208 (CorrectableJumpPoint): 209 * dfg/DFGJITCompiler.cpp: 210 (JSC::DFG::JITCompiler::linkOSRExits): 211 (JSC::DFG::JITCompiler::link): 212 * dfg/DFGNode.h: 213 (JSC::DFG::Node::hasIdentifierNumberForCheck): 214 (Node): 215 (JSC::DFG::Node::identifierNumberForCheck): 216 (JSC::DFG::Node::hasRegisterPointer): 217 * dfg/DFGNodeType.h: 218 (DFG): 219 * dfg/DFGOSRExit.cpp: 220 (JSC::DFG::OSRExit::OSRExit): 221 * dfg/DFGOSRExit.h: 222 (OSRExit): 223 * dfg/DFGOperations.cpp: 224 * dfg/DFGOperations.h: 225 * dfg/DFGPredictionPropagationPhase.cpp: 226 (JSC::DFG::PredictionPropagationPhase::propagate): 227 * dfg/DFGSpeculativeJIT.h: 228 (JSC::DFG::SpeculativeJIT::callOperation): 229 (JSC::DFG::SpeculativeJIT::appendCall): 230 (SpeculativeJIT): 231 (JSC::DFG::SpeculativeJIT::speculationWatchpoint): 232 * dfg/DFGSpeculativeJIT32_64.cpp: 233 (JSC::DFG::SpeculativeJIT::compile): 234 * dfg/DFGSpeculativeJIT64.cpp: 235 (JSC::DFG::SpeculativeJIT::compile): 236 * jit/JIT.cpp: 237 (JSC::JIT::privateCompileMainPass): 238 (JSC::JIT::privateCompileSlowCases): 239 * jit/JIT.h: 240 * jit/JITPropertyAccess.cpp: 241 (JSC::JIT::emit_op_put_global_var_check): 242 (JSC): 243 (JSC::JIT::emitSlow_op_put_global_var_check): 244 * jit/JITPropertyAccess32_64.cpp: 245 (JSC::JIT::emit_op_put_global_var_check): 246 (JSC): 247 (JSC::JIT::emitSlow_op_put_global_var_check): 248 * jit/JITStubs.cpp: 249 (JSC::JITThunks::JITThunks): 250 (JSC::DEFINE_STUB_FUNCTION): 251 (JSC): 252 * jit/JITStubs.h: 253 * llint/LLIntSlowPaths.cpp: 254 (JSC::LLInt::LLINT_SLOW_PATH_DECL): 255 (LLInt): 256 * llint/LLIntSlowPaths.h: 257 (LLInt): 258 * llint/LowLevelInterpreter32_64.asm: 259 * llint/LowLevelInterpreter64.asm: 260 * runtime/JSObject.cpp: 261 (JSC::JSObject::removeDirect): 262 * runtime/JSObject.h: 263 (JSObject): 264 * runtime/JSSymbolTableObject.h: 265 (JSC::symbolTableGet): 266 (JSC::symbolTablePut): 267 (JSC::symbolTablePutWithAttributes): 268 * runtime/SymbolTable.cpp: Added. 269 (JSC): 270 (JSC::SymbolTableEntry::copySlow): 271 (JSC::SymbolTableEntry::freeFatEntrySlow): 272 (JSC::SymbolTableEntry::couldBeWatched): 273 (JSC::SymbolTableEntry::attemptToWatch): 274 (JSC::SymbolTableEntry::addressOfIsWatched): 275 (JSC::SymbolTableEntry::addWatchpoint): 276 (JSC::SymbolTableEntry::notifyWriteSlow): 277 (JSC::SymbolTableEntry::inflateSlow): 278 * runtime/SymbolTable.h: 279 (JSC): 280 (SymbolTableEntry): 281 (Fast): 282 (JSC::SymbolTableEntry::Fast::Fast): 283 (JSC::SymbolTableEntry::Fast::isNull): 284 (JSC::SymbolTableEntry::Fast::getIndex): 285 (JSC::SymbolTableEntry::Fast::isReadOnly): 286 (JSC::SymbolTableEntry::Fast::getAttributes): 287 (JSC::SymbolTableEntry::Fast::isFat): 288 (JSC::SymbolTableEntry::SymbolTableEntry): 289 (JSC::SymbolTableEntry::~SymbolTableEntry): 290 (JSC::SymbolTableEntry::operator=): 291 (JSC::SymbolTableEntry::isNull): 292 (JSC::SymbolTableEntry::getIndex): 293 (JSC::SymbolTableEntry::getFast): 294 (JSC::SymbolTableEntry::getAttributes): 295 (JSC::SymbolTableEntry::isReadOnly): 296 (JSC::SymbolTableEntry::watchpointSet): 297 (JSC::SymbolTableEntry::notifyWrite): 298 (FatEntry): 299 (JSC::SymbolTableEntry::FatEntry::FatEntry): 300 (JSC::SymbolTableEntry::isFat): 301 (JSC::SymbolTableEntry::fatEntry): 302 (JSC::SymbolTableEntry::inflate): 303 (JSC::SymbolTableEntry::bits): 304 (JSC::SymbolTableEntry::freeFatEntry): 305 (JSC::SymbolTableEntry::pack): 306 (JSC::SymbolTableEntry::isValidIndex): 307 1 308 2012-06-12 Filip Pizlo <[email protected]> 2 309
Note:
See TracChangeset
for help on using the changeset viewer.