Changeset 210971 in webkit
- Timestamp:
- Jan 20, 2017, 10:10:55 AM (10 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 4 edited
-
ChangeLog (modified) (1 diff)
-
dfg/DFGPlan.cpp (modified) (12 diffs)
-
dfg/DFGSafepoint.cpp (modified) (2 diffs)
-
runtime/Options.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r210958 r210971 1 2017-01-20 Saam Barati <sbarati@apple.com> 2 3 We should flash a safepoint before each DFG/FTL phase 4 https://bugs.webkit.org/show_bug.cgi?id=167234 5 6 Reviewed by Filip Pizlo. 7 8 The recent GC changes caused us to regress Kraken because of a 9 longstanding issue that happened to be hit with higher frequency because 10 of a change in timing between when a particular GC was happening and 11 when a particular FTL compilation was happening. The regression is caused 12 by the GC was waiting for a large function to make it through the DFG portion 13 of an FTL compilation. This was taking 20ms-30ms and started happened during a 14 particular test with much higher frequency. 15 16 This means that anytime the GC waits for this compilation, the test ran at least 17 ~20ms slower because the GC waits for the compiler threads the mutator is stopped. 18 19 It's good that we have such an easily reproducible case of this performance 20 issue because it will effect many real JS programs, especially ones with 21 large functions that get hot. 22 23 The most straight forward solution to fix this is to flash a safepoint before 24 each phase, allowing the GC to suspend the compiler if needed. In my testing, 25 this progresses Kraken in the browser, and doesn't regress anything else. This 26 solution also makes the most sense. I did some analysis on the compilation time 27 of this function that took ~20-30ms to pass through the DFG phases, and 28 the phase times were mostly evenly distributed. Some took longer than others, 29 but no phase was longer than 3ms. Most were in the 0.25ms to 1.5ms range. 30 31 * dfg/DFGPlan.cpp: 32 (JSC::DFG::Plan::compileInThreadImpl): 33 * dfg/DFGSafepoint.cpp: 34 (JSC::DFG::Safepoint::begin): 35 * runtime/Options.h: 36 1 37 2017-01-20 Skachkov Oleksandr <gskachkov@gmail.com> 2 38 -
trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp
r210521 r210971 255 255 256 256 codeBlock->setCalleeSaveRegisters(RegisterSet::dfgCalleeSaveRegisters()); 257 258 bool changed = false; 259 260 #define RUN_PHASE(phase) \ 261 do { \ 262 if (Options::safepointBeforeEachPhase()) { \ 263 Safepoint::Result safepointResult; \ 264 { \ 265 GraphSafepoint safepoint(dfg, safepointResult); \ 266 } \ 267 if (safepointResult.didGetCancelled()) \ 268 return CancelPath; \ 269 } \ 270 changed |= phase(dfg); \ 271 } while (false); \ 272 257 273 258 274 // By this point the DFG bytecode parser will have potentially mutated various tables … … 270 286 } 271 287 272 performLiveCatchVariablePreservationPhase(dfg);288 RUN_PHASE(performLiveCatchVariablePreservationPhase); 273 289 274 290 if (Options::useMaximalFlushInsertionPhase()) 275 performMaximalFlushInsertion(dfg);276 277 performCPSRethreading(dfg);278 performUnification(dfg);279 performPredictionInjection(dfg);280 281 performStaticExecutionCountEstimation(dfg);291 RUN_PHASE(performMaximalFlushInsertion); 292 293 RUN_PHASE(performCPSRethreading); 294 RUN_PHASE(performUnification); 295 RUN_PHASE(performPredictionInjection); 296 297 RUN_PHASE(performStaticExecutionCountEstimation); 282 298 283 299 if (mode == FTLForOSREntryMode) { … … 287 303 return FailPath; 288 304 } 289 performCPSRethreading(dfg);305 RUN_PHASE(performCPSRethreading); 290 306 } 291 307 … … 293 309 validate(dfg); 294 310 295 performBackwardsPropagation(dfg);296 performPredictionPropagation(dfg);297 performFixup(dfg);298 performStructureRegistration(dfg);299 performInvalidationPointInjection(dfg);300 performTypeCheckHoisting(dfg);311 RUN_PHASE(performBackwardsPropagation); 312 RUN_PHASE(performPredictionPropagation); 313 RUN_PHASE(performFixup); 314 RUN_PHASE(performStructureRegistration); 315 RUN_PHASE(performInvalidationPointInjection); 316 RUN_PHASE(performTypeCheckHoisting); 301 317 302 318 dfg.m_fixpointState = FixpointNotConverged; … … 310 326 validate(dfg); 311 327 312 performStrengthReduction(dfg);313 performCPSRethreading(dfg);314 performCFA(dfg);315 performConstantFolding(dfg);316 boolchanged = false;317 changed |= performCFGSimplification(dfg);318 changed |= performLocalCSE(dfg);328 RUN_PHASE(performStrengthReduction); 329 RUN_PHASE(performCPSRethreading); 330 RUN_PHASE(performCFA); 331 RUN_PHASE(performConstantFolding); 332 changed = false; 333 RUN_PHASE(performCFGSimplification); 334 RUN_PHASE(performLocalCSE); 319 335 320 336 if (validationEnabled()) 321 337 validate(dfg); 322 338 323 performCPSRethreading(dfg);339 RUN_PHASE(performCPSRethreading); 324 340 if (!isFTL(mode)) { 325 341 // Only run this if we're not FTLing, because currently for a LoadVarargs that is forwardable and … … 342 358 // pathology. 343 359 344 changed |= performVarargsForwarding(dfg); // Do this after CFG simplification and CPS rethreading.360 RUN_PHASE(performVarargsForwarding); // Do this after CFG simplification and CPS rethreading. 345 361 } 346 362 if (changed) { 347 performCFA(dfg);348 performConstantFolding(dfg);363 RUN_PHASE(performCFA); 364 RUN_PHASE(performConstantFolding); 349 365 } 350 366 … … 361 377 dfg.m_fixpointState = FixpointConverged; 362 378 363 performTierUpCheckInjection(dfg);364 365 performFastStoreBarrierInsertion(dfg);366 performStoreBarrierClustering(dfg);367 performCleanUp(dfg);368 performCPSRethreading(dfg);369 performDCE(dfg);370 performPhantomInsertion(dfg);371 performStackLayout(dfg);372 performVirtualRegisterAllocation(dfg);373 performWatchpointCollection(dfg);379 RUN_PHASE(performTierUpCheckInjection); 380 381 RUN_PHASE(performFastStoreBarrierInsertion); 382 RUN_PHASE(performStoreBarrierClustering); 383 RUN_PHASE(performCleanUp); 384 RUN_PHASE(performCPSRethreading); 385 RUN_PHASE(performDCE); 386 RUN_PHASE(performPhantomInsertion); 387 RUN_PHASE(performStackLayout); 388 RUN_PHASE(performVirtualRegisterAllocation); 389 RUN_PHASE(performWatchpointCollection); 374 390 dumpAndVerifyGraph(dfg, "Graph after optimization:"); 375 391 … … 391 407 } 392 408 393 performCleanUp(dfg); // Reduce the graph size a bit.394 performCriticalEdgeBreaking(dfg);409 RUN_PHASE(performCleanUp); // Reduce the graph size a bit. 410 RUN_PHASE(performCriticalEdgeBreaking); 395 411 if (Options::createPreHeaders()) 396 performLoopPreHeaderCreation(dfg);397 performCPSRethreading(dfg);398 performSSAConversion(dfg);399 performSSALowering(dfg);412 RUN_PHASE(performLoopPreHeaderCreation); 413 RUN_PHASE(performCPSRethreading); 414 RUN_PHASE(performSSAConversion); 415 RUN_PHASE(performSSALowering); 400 416 401 417 // Ideally, these would be run to fixpoint with the object allocation sinking phase. 402 performArgumentsElimination(dfg);418 RUN_PHASE(performArgumentsElimination); 403 419 if (Options::usePutStackSinking()) 404 performPutStackSinking(dfg);405 406 performConstantHoisting(dfg);407 performGlobalCSE(dfg);408 performLivenessAnalysis(dfg);409 performCFA(dfg);410 performConstantFolding(dfg);411 performCleanUp(dfg); // Reduce the graph size a lot.420 RUN_PHASE(performPutStackSinking); 421 422 RUN_PHASE(performConstantHoisting); 423 RUN_PHASE(performGlobalCSE); 424 RUN_PHASE(performLivenessAnalysis); 425 RUN_PHASE(performCFA); 426 RUN_PHASE(performConstantFolding); 427 RUN_PHASE(performCleanUp); // Reduce the graph size a lot. 412 428 changed = false; 413 changed |= performStrengthReduction(dfg);429 RUN_PHASE(performStrengthReduction); 414 430 if (Options::useObjectAllocationSinking()) { 415 changed |= performCriticalEdgeBreaking(dfg);416 changed |= performObjectAllocationSinking(dfg);431 RUN_PHASE(performCriticalEdgeBreaking); 432 RUN_PHASE(performObjectAllocationSinking); 417 433 } 418 434 if (changed) { 419 435 // State-at-tail and state-at-head will be invalid if we did strength reduction since 420 436 // it might increase live ranges. 421 performLivenessAnalysis(dfg);422 performCFA(dfg);423 performConstantFolding(dfg);437 RUN_PHASE(performLivenessAnalysis); 438 RUN_PHASE(performCFA); 439 RUN_PHASE(performConstantFolding); 424 440 } 425 441 … … 429 445 // Alternatively, we could run loop pre-header creation after SSA conversion - but if we did that 430 446 // then we'd need to do some simple SSA fix-up. 431 performLivenessAnalysis(dfg);432 performCFA(dfg);433 performLICM(dfg);447 RUN_PHASE(performLivenessAnalysis); 448 RUN_PHASE(performCFA); 449 RUN_PHASE(performLICM); 434 450 435 451 // FIXME: Currently: IntegerRangeOptimization *must* be run after LICM. … … 440 456 // 441 457 // Ideally, the dependencies should be explicit. See https://bugs.webkit.org/show_bug.cgi?id=157534. 442 performLivenessAnalysis(dfg);443 performIntegerRangeOptimization(dfg);444 445 performCleanUp(dfg);446 performIntegerCheckCombining(dfg);447 performGlobalCSE(dfg);458 RUN_PHASE(performLivenessAnalysis); 459 RUN_PHASE(performIntegerRangeOptimization); 460 461 RUN_PHASE(performCleanUp); 462 RUN_PHASE(performIntegerCheckCombining); 463 RUN_PHASE(performGlobalCSE); 448 464 449 465 // At this point we're not allowed to do any further code motion because our reasoning … … 451 467 dfg.m_fixpointState = FixpointConverged; 452 468 453 performLivenessAnalysis(dfg);454 performCFA(dfg);455 performGlobalStoreBarrierInsertion(dfg);456 performStoreBarrierClustering(dfg);469 RUN_PHASE(performLivenessAnalysis); 470 RUN_PHASE(performCFA); 471 RUN_PHASE(performGlobalStoreBarrierInsertion); 472 RUN_PHASE(performStoreBarrierClustering); 457 473 if (Options::useMovHintRemoval()) 458 performMovHintRemoval(dfg);459 performCleanUp(dfg);460 performDCE(dfg); // We rely on this to kill dead code that won't be recognized as dead by B3.461 performStackLayout(dfg);462 performLivenessAnalysis(dfg);463 performOSRAvailabilityAnalysis(dfg);464 performWatchpointCollection(dfg);474 RUN_PHASE(performMovHintRemoval); 475 RUN_PHASE(performCleanUp); 476 RUN_PHASE(performDCE); // We rely on this to kill dead code that won't be recognized as dead by B3. 477 RUN_PHASE(performStackLayout); 478 RUN_PHASE(performLivenessAnalysis); 479 RUN_PHASE(performOSRAvailabilityAnalysis); 480 RUN_PHASE(performWatchpointCollection); 465 481 466 482 if (FTL::canCompile(dfg) == FTL::CannotCompile) { … … 522 538 return FailPath; 523 539 } 540 541 #undef RUN_PHASE 524 542 } 525 543 -
trunk/Source/JavaScriptCore/dfg/DFGSafepoint.cpp
r200933 r210971 1 1 /* 2 * Copyright (C) 2014 , 2016Apple Inc. All rights reserved.2 * Copyright (C) 2014-2017 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 81 81 RELEASE_ASSERT(!data->m_safepoint); 82 82 data->m_safepoint = this; 83 data->m_rightToRun.unlock ();83 data->m_rightToRun.unlockFairly(); 84 84 } 85 85 } -
trunk/Source/JavaScriptCore/runtime/Options.h
r210521 r210971 159 159 v(bool, dumpAirGraphAtEachPhase, false, Normal, "dumps the Air graph at each phase of compilation") \ 160 160 v(bool, verboseDFGByteCodeParsing, false, Normal, nullptr) \ 161 v(bool, safepointBeforeEachPhase, true, Normal, nullptr) \ 161 162 v(bool, verboseCompilation, false, Normal, nullptr) \ 162 163 v(bool, verboseFTLCompilation, false, Normal, nullptr) \
Note:
See TracChangeset
for help on using the changeset viewer.