Changeset 211245 in webkit
- Timestamp:
- Jan 26, 2017 5:33:38 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 3 deleted
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r211224 r211245 1 2017-01-26 Commit Queue <commit-queue@webkit.org> 2 3 Unreviewed, rolling out r211224. 4 https://bugs.webkit.org/show_bug.cgi?id=167479 5 6 "It was a Kraken performance regression" (Requested by 7 saamyjoon on #webkit). 8 9 Reverted changeset: 10 11 "OSR entry: delay outer-loop compilation when at inner-loop" 12 https://bugs.webkit.org/show_bug.cgi?id=167149 13 http://trac.webkit.org/changeset/211224 14 1 15 2017-01-26 JF Bastien <jfbastien@apple.com> 2 16 -
trunk/Source/JavaScriptCore/ChangeLog
r211237 r211245 1 2017-01-26 Commit Queue <commit-queue@webkit.org> 2 3 Unreviewed, rolling out r211224. 4 https://bugs.webkit.org/show_bug.cgi?id=167479 5 6 "It was a Kraken performance regression" (Requested by 7 saamyjoon on #webkit). 8 9 Reverted changeset: 10 11 "OSR entry: delay outer-loop compilation when at inner-loop" 12 https://bugs.webkit.org/show_bug.cgi?id=167149 13 http://trac.webkit.org/changeset/211224 14 1 15 2017-01-26 Saam Barati <sbarati@apple.com> 2 16 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r211237 r211245 2061 2061 ADE8029C1E08F1DE0058DE78 /* WebAssemblyLinkErrorPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = ADE802971E08F1C90058DE78 /* WebAssemblyLinkErrorPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2062 2062 ADE8029E1E08F2280058DE78 /* WebAssemblyLinkErrorConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADE8029D1E08F2260058DE78 /* WebAssemblyLinkErrorConstructor.cpp */; }; 2063 ADFF2F701E319DE3001EA54E /* DFGTierUpEntryTrigger.h in Headers */ = {isa = PBXBuildFile; fileRef = ADFF2F6F1E319DD0001EA54E /* DFGTierUpEntryTrigger.h */; };2064 2063 B59F89391891F29F00D5CCDC /* UnlinkedInstructionStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B59F89381891ADB500D5CCDC /* UnlinkedInstructionStream.cpp */; }; 2065 2064 BC02E90D0E1839DB000F9297 /* ErrorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02E9050E1839DB000F9297 /* ErrorConstructor.h */; }; … … 4575 4574 ADE802971E08F1C90058DE78 /* WebAssemblyLinkErrorPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAssemblyLinkErrorPrototype.h; path = js/WebAssemblyLinkErrorPrototype.h; sourceTree = "<group>"; }; 4576 4575 ADE8029D1E08F2260058DE78 /* WebAssemblyLinkErrorConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebAssemblyLinkErrorConstructor.cpp; path = js/WebAssemblyLinkErrorConstructor.cpp; sourceTree = "<group>"; }; 4577 ADFF2F6F1E319DD0001EA54E /* DFGTierUpEntryTrigger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGTierUpEntryTrigger.h; path = dfg/DFGTierUpEntryTrigger.h; sourceTree = "<group>"; };4578 4576 B59F89371891AD3300D5CCDC /* UnlinkedInstructionStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnlinkedInstructionStream.h; sourceTree = "<group>"; }; 4579 4577 B59F89381891ADB500D5CCDC /* UnlinkedInstructionStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnlinkedInstructionStream.cpp; sourceTree = "<group>"; }; … … 7135 7133 0FD8A31F17D51F5700CA2C40 /* DFGTierUpCheckInjectionPhase.cpp */, 7136 7134 0FD8A32017D51F5700CA2C40 /* DFGTierUpCheckInjectionPhase.h */, 7137 ADFF2F6F1E319DD0001EA54E /* DFGTierUpEntryTrigger.h */,7138 7135 0FD8A32117D51F5700CA2C40 /* DFGToFTLDeferredCompilationCallback.cpp */, 7139 7136 0FD8A32217D51F5700CA2C40 /* DFGToFTLDeferredCompilationCallback.h */, … … 8819 8816 A1A009C01831A22D00CF8711 /* MacroAssemblerARM64.h in Headers */, 8820 8817 86ADD1460FDDEA980006EEC2 /* MacroAssemblerARMv7.h in Headers */, 8821 ADFF2F701E319DE3001EA54E /* DFGTierUpEntryTrigger.h in Headers */,8822 8818 863B23E00FC6118900703AA4 /* MacroAssemblerCodeRef.h in Headers */, 8823 8819 E32AB2441DCD75F400D7533A /* MacroAssemblerHelpers.h in Headers */, -
trunk/Source/JavaScriptCore/dfg/DFGJITCode.h
r211224 r211245 34 34 #include "DFGOSREntry.h" 35 35 #include "DFGOSRExit.h" 36 #include "DFGTierUpEntryTrigger.h"37 36 #include "DFGVariableEventStream.h" 38 37 #include "ExecutionCounter.h" … … 156 155 // This can never be modified after it has been initialized since the addresses of the triggers 157 156 // are used by the JIT. 158 HashMap<unsigned, TierUpEntryTrigger> tierUpEntryTriggers;157 HashMap<unsigned, uint8_t> tierUpEntryTriggers; 159 158 160 159 // Set of bytecode that were the target of a TierUp operation. -
trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
r211224 r211245 61 61 m_jitCode->tierUpInLoopHierarchy = WTFMove(m_graph.m_plan.tierUpInLoopHierarchy); 62 62 for (unsigned tierUpBytecode : m_graph.m_plan.tierUpAndOSREnterBytecodes) 63 m_jitCode->tierUpEntryTriggers.add(tierUpBytecode, TierUpEntryTrigger::None);63 m_jitCode->tierUpEntryTriggers.add(tierUpBytecode, 0); 64 64 #endif 65 65 } -
trunk/Source/JavaScriptCore/dfg/DFGOSREntry.cpp
r211224 r211245 92 92 93 93 SUPPRESS_ASAN 94 Expected<void*, OSREntryFail>prepareOSREntry(ExecState* exec, CodeBlock* codeBlock, unsigned bytecodeIndex)94 void* prepareOSREntry(ExecState* exec, CodeBlock* codeBlock, unsigned bytecodeIndex) 95 95 { 96 96 ASSERT(JITCode::isOptimizingJIT(codeBlock->jitType())); … … 100 100 101 101 if (!Options::useOSREntryToDFG()) 102 return makeUnexpected(OSREntryFail::Disabled);102 return 0; 103 103 104 104 if (Options::verboseOSR()) { … … 137 137 if (Options::verboseOSR()) 138 138 dataLog(" OSR failed because the target code block is not DFG.\n"); 139 return makeUnexpected(OSREntryFail::TargetNotDFG);139 return 0; 140 140 } 141 141 … … 146 146 if (Options::verboseOSR()) 147 147 dataLogF(" OSR failed because the entrypoint was optimized out.\n"); 148 return makeUnexpected(OSREntryFail::TargetOptimizedOut);148 return 0; 149 149 } 150 150 … … 182 182 dataLogF(".\n"); 183 183 } 184 return makeUnexpected(OSREntryFail::BadPrediction);184 return 0; 185 185 } 186 186 … … 197 197 ", expected ", entry->m_expectedValues.argument(argument), ".\n"); 198 198 } 199 return makeUnexpected(OSREntryFail::BadPrediction);199 return 0; 200 200 } 201 201 } … … 210 210 exec->registers()[localOffset].asanUnsafeJSValue(), ", expected number.\n"); 211 211 } 212 return makeUnexpected(OSREntryFail::BadPrediction);212 return 0; 213 213 } 214 214 continue; … … 222 222 "machine int.\n"); 223 223 } 224 return makeUnexpected(OSREntryFail::BadPrediction);224 return 0; 225 225 } 226 226 continue; … … 233 233 entry->m_expectedValues.local(local), ".\n"); 234 234 } 235 return makeUnexpected(OSREntryFail::BadPrediction);235 return 0; 236 236 } 237 237 } … … 248 248 if (Options::verboseOSR()) 249 249 dataLogF(" OSR failed because stack growth failed.\n"); 250 return makeUnexpected(OSREntryFail::StackGrowthFailed);250 return 0; 251 251 } 252 252 -
trunk/Source/JavaScriptCore/dfg/DFGOSREntry.h
r211224 r211245 29 29 #include "Operands.h" 30 30 #include <wtf/BitVector.h> 31 #include <wtf/Expected.h>32 31 33 32 namespace JSC { … … 37 36 38 37 namespace DFG { 39 40 enum class OSREntryFail {41 Disabled,42 TargetNotDFG,43 TargetOptimizedOut,44 BadPrediction,45 StackGrowthFailed,46 };47 38 48 39 #if ENABLE(DFG_JIT) … … 79 70 } 80 71 81 // Returns a pointer to a data buffer that the OSR entry thunk will recognize and parse. 82 Expected<void*, OSREntryFail> prepareOSREntry(ExecState*, CodeBlock*, unsigned bytecodeIndex); 72 // Returns a pointer to a data buffer that the OSR entry thunk will recognize and 73 // parse. If this returns null, it means 74 void* prepareOSREntry(ExecState*, CodeBlock*, unsigned bytecodeIndex); 83 75 #else 84 inline Expected<void*, OSREntryFail> prepareOSREntry(ExecState*, CodeBlock*, unsigned) { return makeUnexpected(OSREntryFail::Disabled); }76 inline void* prepareOSREntry(ExecState*, CodeBlock*, unsigned) { return 0; } 85 77 #endif 86 78 -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r211224 r211245 2315 2315 } 2316 2316 2317 // This updates the execution counter.2318 2317 if (shouldTriggerFTLCompile(codeBlock, jitCode)) 2319 2318 triggerFTLReplacementCompile(vm, codeBlock, jitCode); … … 2339 2338 } 2340 2339 2341 enum class EntryReason { 2342 Spurious, 2343 CheckingUpOnHowCompilationIsGoing, 2344 HaveOSREntryReady, 2345 ShouldStartCompiling, 2346 ShouldStartCompilingRightNow, 2347 CompilationFailed, 2348 }; 2349 2350 static EntryReason whatHaveYouDoneAndWhyAmIHere(VM* vm, CodeBlock* codeBlock, JITCode* jitCode, unsigned bytecodeIndex, CodeBlock*& osrEntryBlock) 2351 { 2352 // Gather facts about why we could be here. 2340 static char* tierUpCommon(ExecState* exec, unsigned originBytecodeIndex, unsigned osrEntryBytecodeIndex) 2341 { 2342 VM* vm = &exec->vm(); 2343 CodeBlock* codeBlock = exec->codeBlock(); 2353 2344 2354 2345 // Resolve any pending plan for OSR Enter on this function. 2355 2346 Worklist::State worklistState; 2356 if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) 2357 worklistState = worklist->completeAllReadyPlansForVM(*vm, CompilationKey(codeBlock->baselineVersion(), FTLForOSREntryMode)); 2358 else 2347 if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) { 2348 worklistState = worklist->completeAllReadyPlansForVM( 2349 *vm, CompilationKey(codeBlock->baselineVersion(), FTLForOSREntryMode)); 2350 } else 2359 2351 worklistState = Worklist::NotKnown; 2360 2352 2361 osrEntryBlock = jitCode->osrEntryBlock(); 2362 2363 // Was the tier-up entry trigger set to slow-path? 2364 bool triggeredSlowPath = false; 2365 auto tierUpEntryTriggers = jitCode->tierUpEntryTriggers.find(bytecodeIndex); 2366 if (tierUpEntryTriggers != jitCode->tierUpEntryTriggers.end()) { 2367 if (tierUpEntryTriggers->value == TierUpEntryTrigger::TakeSlowPath) { 2368 // We were asked to enter as soon as possible. Unset this trigger so we don't continually enter. 2369 if (Options::verboseOSR()) 2370 dataLog("EntryTrigger for ", *codeBlock, " forced slow-path.\n"); 2371 triggeredSlowPath = true; 2372 tierUpEntryTriggers->value = TierUpEntryTrigger::None; 2373 } 2374 } 2375 2376 // Put those facts together to make a final determination. 2377 2378 switch (worklistState) { 2379 case Worklist::NotKnown: 2380 if (osrEntryBlock) 2381 return EntryReason::HaveOSREntryReady; 2382 if (triggeredSlowPath) { 2383 // Someone went through the trouble of forcing us into slow-path, they really wanted us to compile. 2384 return EntryReason::ShouldStartCompilingRightNow; 2385 } 2386 return EntryReason::ShouldStartCompiling; 2387 2388 case Worklist::Compiling: 2389 if (triggeredSlowPath) { 2390 // We're already compiling, and can't OSR enter. We therefore must 2391 // have set our slow-path trigger as well as another slow path 2392 // trigger, hoping one of these would kick off a compilation. Sure 2393 // enough another bytecode location did kick off a compilation 2394 // before this one got a chance to do so. There's nothing for us to 2395 // do but wait. 2396 return EntryReason::Spurious; 2397 } 2398 return EntryReason::CheckingUpOnHowCompilationIsGoing; 2399 2400 case Worklist::Compiled: 2401 return EntryReason::CompilationFailed; 2402 } 2403 2404 RELEASE_ASSERT_NOT_REACHED(); 2405 return EntryReason::Spurious; 2406 } 2407 2408 enum class CanOSREnterFromHere { 2409 No, 2410 Yes, 2411 }; 2412 2413 static char* tierUpCommon(VM* vm, ExecState* exec, CodeBlock* codeBlock, JITCode* jitCode, unsigned bytecodeIndex, CanOSREnterFromHere canOSREnterFromHere) 2414 { 2415 CodeBlock* osrEntryBlock; 2416 EntryReason entryReason = whatHaveYouDoneAndWhyAmIHere(vm, codeBlock, jitCode, bytecodeIndex, osrEntryBlock); 2417 2418 switch (entryReason) { 2419 case EntryReason::CheckingUpOnHowCompilationIsGoing: 2353 JITCode* jitCode = codeBlock->jitCode()->dfg(); 2354 if (worklistState == Worklist::Compiling) { 2420 2355 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("still compiling")); 2421 2356 jitCode->setOptimizationThresholdBasedOnCompilationResult( 2422 2357 codeBlock, CompilationDeferred); 2423 2358 return nullptr; 2424 2425 case EntryReason::CompilationFailed: 2359 } 2360 2361 if (worklistState == Worklist::Compiled) { 2426 2362 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("compiled and failed")); 2427 // We've already set the thresholds.2363 // This means that compilation failed and we already set the thresholds. 2428 2364 if (Options::verboseOSR()) 2429 2365 dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n"); 2430 2366 return nullptr; 2431 2432 case EntryReason::HaveOSREntryReady: 2433 if (canOSREnterFromHere == CanOSREnterFromHere::No) 2434 break; // OSR entry is for another location. 2435 2436 { 2437 // If we can OSR Enter, do it right away. 2438 unsigned streamIndex = jitCode->bytecodeIndexToStreamIndex.get(bytecodeIndex); 2439 auto osrEntryPreparation = FTL::prepareOSREntry(exec, codeBlock, osrEntryBlock, bytecodeIndex, streamIndex); 2440 if (osrEntryPreparation) { 2441 CODEBLOCK_LOG_EVENT(osrEntryBlock, "osrEntry", ("at bc#", bytecodeIndex)); 2442 void* address = osrEntryPreparation.value(); 2443 ASSERT(address); 2367 } 2368 2369 // If we can OSR Enter, do it right away. 2370 if (originBytecodeIndex == osrEntryBytecodeIndex) { 2371 unsigned streamIndex = jitCode->bytecodeIndexToStreamIndex.get(originBytecodeIndex); 2372 if (CodeBlock* entryBlock = jitCode->osrEntryBlock()) { 2373 if (void* address = FTL::prepareOSREntry(exec, codeBlock, entryBlock, originBytecodeIndex, streamIndex)) { 2374 CODEBLOCK_LOG_EVENT(entryBlock, "osrEntry", ("at bc#", originBytecodeIndex)); 2444 2375 return static_cast<char*>(address); 2445 2376 } 2446 switch (osrEntryPreparation.error()) {2447 case FTL::OSREntryFail::StackGrowthFailed:2448 break;2449 case FTL::OSREntryFail::WrongBytecode:2450 // Above we checked that an entry was possible from the current2451 // location, but we didn't know whether the compiled OSR entry2452 // was for this location. Now we know it's not.2453 break;2454 }2455 2456 break;2457 2377 } 2458 2459 case EntryReason::ShouldStartCompiling:2460 case EntryReason::ShouldStartCompilingRightNow:2461 // We'll take care of that below.2462 break;2463 2464 case EntryReason::Spurious:2465 if (Options::verboseOSR())2466 dataLog("Code block ", *codeBlock, " was spuriously woken up, compilation is already under way.\n");2467 jitCode->checkIfOptimizationThresholdReached(codeBlock);2468 return nullptr;2469 2378 } 2470 2379 … … 2473 2382 // - If we couldn't enter for a while, then trigger OSR entry. 2474 2383 2475 // This updates the execution counter.2476 2384 if (!shouldTriggerFTLCompile(codeBlock, jitCode)) 2477 2385 return nullptr; … … 2491 2399 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("avoiding replacement compile")); 2492 2400 2493 if (osrEntryBlock) { 2494 // We have a compiled OSR entry for this function, but didn't enter. 2495 2401 // It's time to try to compile code for OSR entry. 2402 if (CodeBlock* entryBlock = jitCode->osrEntryBlock()) { 2496 2403 if (jitCode->osrEntryRetry < Options::ftlOSREntryRetryThreshold()) { 2497 2404 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry failed, OSR entry threshold not met")); … … 2502 2409 } 2503 2410 2504 FTL::ForOSREntryJITCode* entryCode = osrEntryBlock->jitCode()->ftlForOSREntry();2411 FTL::ForOSREntryJITCode* entryCode = entryBlock->jitCode()->ftlForOSREntry(); 2505 2412 entryCode->countEntryFailure(); 2506 2413 if (entryCode->entryFailureCount() < … … 2515 2422 // without exponential backoff and we only do this for the entry code block. 2516 2423 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry failed too many times")); 2517 unsigned osrEntryBytecode = osrEntryBlock->jitCode()->ftlForOSREntry()->bytecodeIndex();2424 unsigned osrEntryBytecode = entryBlock->jitCode()->ftlForOSREntry()->bytecodeIndex(); 2518 2425 jitCode->clearOSREntryBlock(); 2519 2426 jitCode->osrEntryRetry = 0; 2520 jitCode->tierUpEntryTriggers.set(osrEntryBytecode, TierUpEntryTrigger::None);2427 jitCode->tierUpEntryTriggers.set(osrEntryBytecode, 0); 2521 2428 jitCode->setOptimizationThresholdBasedOnCompilationResult( 2522 2429 codeBlock, CompilationDeferred); … … 2524 2431 } 2525 2432 2526 // We aren't compiling and haven't compiled anything for OSR entry. So, try to compile something. 2527 2528 if (entryReason != EntryReason::ShouldStartCompilingRightNow) { 2529 // We entered because our threshold was set, not because someone is forcing us to compile. 2530 // Try to see if there would be a better place to compile from than where we currently are. 2531 2532 // Compiling an outer-loop for OSR entry often generates better code than an inner-loop because 2533 // the entry is less disruptive. If we're at an inner-loop be smart and mark the outer-loop as 2534 // needing compilation ASAP. Once execution reaches the outer-loop compilation will trigger. 2535 auto tierUpHierarchyEntry = jitCode->tierUpInLoopHierarchy.find(bytecodeIndex); 2536 if (tierUpHierarchyEntry != jitCode->tierUpInLoopHierarchy.end() && !tierUpHierarchyEntry->value.isEmpty()) { 2537 // Traverse the loop hierarchy from the outer-most loop, to the inner-most one. 2538 for (auto iterator = tierUpHierarchyEntry->value.rbegin(), end = tierUpHierarchyEntry->value.rend(); iterator != end; ++iterator) { 2539 unsigned osrEntryCandidate = *iterator; 2540 if (jitCode->tierUpEntrySeen.contains(osrEntryCandidate)) { 2541 unsigned outerLoopOsrEntryBytecodeIndex = osrEntryCandidate; 2542 2543 // We found an outer-loop which would be a better OSR entry 2544 // than the current location: 2545 // - Set its trigger so it takes the slow-path ASAP; 2546 // - Tell the codeblock to stop its counter slow-path for a 2547 // while, because it should wait for the outer-loop to 2548 // trigger. 2549 // 2550 // If we slow-path again then one of these is true: 2551 // 1. We enter from the outer-loop because of its trigger, 2552 // it un-sets its trigger, kicks off a compile, 2553 // everything is good; 2554 // 2. We enter from anywhere and a compile is under way, 2555 // just chill as usual; 2556 // 3. We never got to that outer-loop and the counter 2557 // tripped again, bummer! 2558 // 2559 // We can detect 3. because the outer-loop's trigger is 2560 // set. It's still a great place to enter, so leave its 2561 // trigger set, but also: 2562 // - Set the trigger for the next loop in, hope that one triggers; 2563 // - Backoff the counter as before. 2564 // That is, unless all the inner-loop's parent triggers are 2565 // set. In that case just optimize the innermost-loop: it 2566 // won't generate as good code, but the outer-loops aren't 2567 // triggering so we may as we tier up where we can. 2568 auto outerLoopTierUpEntryTriggers = jitCode->tierUpEntryTriggers.find(outerLoopOsrEntryBytecodeIndex); 2569 ASSERT(outerLoopTierUpEntryTriggers != jitCode->tierUpEntryTriggers.end()); 2570 2571 if (outerLoopTierUpEntryTriggers->value != TierUpEntryTrigger::TakeSlowPath) { 2572 if (Options::verboseOSR()) 2573 dataLog("Forcibly FTL-optimize outer-loop bc#", outerLoopOsrEntryBytecodeIndex, " in ", *codeBlock, "by setting its trigger.\n"); 2574 2575 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry request from inner-loop for outer-loop")); 2576 jitCode->tierUpEntryTriggers.set(outerLoopOsrEntryBytecodeIndex, TierUpEntryTrigger::TakeSlowPath); 2577 jitCode->optimizeSoon(codeBlock); 2578 return nullptr; 2579 } 2580 2581 if (Options::verboseOSR()) 2582 dataLog("Trying to forcibly FTL-optimize outer-loop bc#", outerLoopOsrEntryBytecodeIndex, " in ", *codeBlock, ", but trigger is already set.\n"); 2583 } 2433 unsigned streamIndex = jitCode->bytecodeIndexToStreamIndex.get(osrEntryBytecodeIndex); 2434 auto tierUpHierarchyEntry = jitCode->tierUpInLoopHierarchy.find(osrEntryBytecodeIndex); 2435 if (tierUpHierarchyEntry != jitCode->tierUpInLoopHierarchy.end()) { 2436 for (unsigned osrEntryCandidate : tierUpHierarchyEntry->value) { 2437 if (jitCode->tierUpEntrySeen.contains(osrEntryCandidate)) { 2438 osrEntryBytecodeIndex = osrEntryCandidate; 2439 streamIndex = jitCode->bytecodeIndexToStreamIndex.get(osrEntryBytecodeIndex); 2584 2440 } 2585 2586 // All the outer-loops have their trigger set, but none have been entered.2587 2588 if (canOSREnterFromHere == CanOSREnterFromHere::No) {2589 // We just can't enter from here, we've asked everyone we know2590 // to please optimize ASAP, nobody has heeded our call. Keep2591 // hoping one of the outer loops triggers get to their slow2592 // path. Stop the counter, there's nothing we can do.2593 jitCode->dontOptimizeAnytimeSoon(codeBlock);2594 return nullptr;2595 }2596 2597 if (Options::verboseOSR())2598 dataLog("Tried to forcibly-optimize outer-loop, but falling back to bc#", bytecodeIndex, " in ", *codeBlock, ", outer-loop triggers didn't work.\n");2599 2441 } 2600 2442 } 2601 2443 2602 RELEASE_ASSERT(canOSREnterFromHere == CanOSREnterFromHere::Yes); 2603 2604 unsigned streamIndex = jitCode->bytecodeIndexToStreamIndex.get(bytecodeIndex); 2605 2606 // We're not trying to kick off a compile of an outer-loop from within an 2607 // inner-loop. We can compile right here, right now. 2608 auto triggerIterator = jitCode->tierUpEntryTriggers.find(bytecodeIndex); 2444 // We aren't compiling and haven't compiled anything for OSR entry. So, try to compile 2445 // something. 2446 auto triggerIterator = jitCode->tierUpEntryTriggers.find(osrEntryBytecodeIndex); 2609 2447 RELEASE_ASSERT(triggerIterator != jitCode->tierUpEntryTriggers.end()); 2610 TierUpEntryTrigger* triggerAddress = &(triggerIterator->value); 2611 2612 // Use OSR reconstruction to generate a snapshot of JSValues at the current 2613 // location of execution. The optimizer is happy when it can look at real 2614 // and live values, as opposed to mere type traces. 2448 uint8_t* triggerAddress = &(triggerIterator->value); 2449 2615 2450 Operands<JSValue> mustHandleValues; 2616 2451 jitCode->reconstruct( 2617 exec, codeBlock, CodeOrigin( bytecodeIndex), streamIndex, mustHandleValues);2452 exec, codeBlock, CodeOrigin(osrEntryBytecodeIndex), streamIndex, mustHandleValues); 2618 2453 CodeBlock* replacementCodeBlock = codeBlock->newReplacement(); 2619 2454 2620 2455 CODEBLOCK_LOG_EVENT(codeBlock, "triggerFTLOSR", ()); 2621 2456 CompilationResult forEntryResult = compile( 2622 *vm, replacementCodeBlock, codeBlock, FTLForOSREntryMode, bytecodeIndex,2457 *vm, replacementCodeBlock, codeBlock, FTLForOSREntryMode, osrEntryBytecodeIndex, 2623 2458 mustHandleValues, ToFTLForOSREntryDeferredCompilationCallback::create(triggerAddress)); 2624 2459 … … 2632 2467 return nullptr; 2633 2468 } 2634 2635 // It's possible that the for-entry compile already succeeded. In that case 2636 // OSR entry will succeed unless we ran out of stack. 2637 auto osrEntryPreparation = FTL::prepareOSREntry(exec, codeBlock, jitCode->osrEntryBlock(), bytecodeIndex, streamIndex); 2638 if (osrEntryPreparation) { 2639 CODEBLOCK_LOG_EVENT(jitCode->osrEntryBlock(), "osrEntry", ("at bc#", bytecodeIndex)); 2640 void* address = osrEntryPreparation.value(); 2641 ASSERT(address); 2642 return static_cast<char*>(address); 2643 } 2644 switch (osrEntryPreparation.error()) { 2645 case FTL::OSREntryFail::StackGrowthFailed: 2646 // It's not clear what we should do. We signal to try again after a 2647 // while if that happens. 2648 return nullptr; 2649 case FTL::OSREntryFail::WrongBytecode: 2650 RELEASE_ASSERT_NOT_REACHED(); 2651 } 2652 2653 RELEASE_ASSERT_NOT_REACHED(); 2654 return nullptr; 2469 2470 CODEBLOCK_LOG_EVENT(jitCode->osrEntryBlock(), "osrEntry", ("at bc#", originBytecodeIndex)); 2471 // It's possible that the for-entry compile already succeeded. In that case OSR 2472 // entry will succeed unless we ran out of stack. It's not clear what we should do. 2473 // We signal to try again after a while if that happens. 2474 void* address = FTL::prepareOSREntry( 2475 exec, codeBlock, jitCode->osrEntryBlock(), originBytecodeIndex, streamIndex); 2476 return static_cast<char*>(address); 2655 2477 } 2656 2478 … … 2675 2497 } 2676 2498 2677 // It's impossible to OSR enter from the current bytecode index: CheckTierUpInLoop is only even generated for non-OSR-entry bytecodes.2678 // It's nonetheless a good spot to request that a nearby loop get optimized the next time it's entered.2679 2680 2499 auto tierUpHierarchyEntry = jitCode->tierUpInLoopHierarchy.find(bytecodeIndex); 2681 2500 if (tierUpHierarchyEntry != jitCode->tierUpInLoopHierarchy.end() 2682 2501 && !tierUpHierarchyEntry->value.isEmpty()) { 2683 // There is a suitable loop to OSR enter from. 2684 tierUpCommon(vm, exec, codeBlock, jitCode, bytecodeIndex, CanOSREnterFromHere::No); 2685 } else if (shouldTriggerFTLCompile(codeBlock, jitCode)) // This updates the execution counter. 2502 tierUpCommon(exec, bytecodeIndex, tierUpHierarchyEntry->value.first()); 2503 } else if (shouldTriggerFTLCompile(codeBlock, jitCode)) 2686 2504 triggerFTLReplacementCompile(vm, codeBlock, jitCode); 2687 2505 … … 2693 2511 } 2694 2512 2695 char* JIT_OPERATION checkTierUpAndOSREnterNow(ExecState* exec, unsigned bytecodeIndex)2513 char* JIT_OPERATION triggerOSREntryNow(ExecState* exec, unsigned bytecodeIndex) 2696 2514 { 2697 2515 VM* vm = &exec->vm(); … … 2706 2524 2707 2525 JITCode* jitCode = codeBlock->jitCode()->dfg(); 2526 jitCode->tierUpEntrySeen.add(bytecodeIndex); 2708 2527 2709 2528 if (Options::verboseOSR()) { … … 2713 2532 } 2714 2533 2715 jitCode->tierUpEntrySeen.add(bytecodeIndex); 2716 return tierUpCommon(vm, exec, codeBlock, jitCode, bytecodeIndex, CanOSREnterFromHere::Yes); 2534 return tierUpCommon(exec, bytecodeIndex, bytecodeIndex); 2717 2535 } 2718 2536 -
trunk/Source/JavaScriptCore/dfg/DFGOperations.h
r211224 r211245 221 221 void JIT_OPERATION triggerTierUpNow(ExecState*) WTF_INTERNAL; 222 222 void JIT_OPERATION triggerTierUpNowInLoop(ExecState*, unsigned bytecodeIndex) WTF_INTERNAL; 223 char* JIT_OPERATION checkTierUpAndOSREnterNow(ExecState*, unsigned bytecodeIndex) WTF_INTERNAL;223 char* JIT_OPERATION triggerOSREntryNow(ExecState*, unsigned bytecodeIndex) WTF_INTERNAL; 224 224 #endif // ENABLE(FTL_JIT) 225 225 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r211237 r211245 5782 5782 auto triggerIterator = m_jit.jitCode()->tierUpEntryTriggers.find(bytecodeIndex); 5783 5783 DFG_ASSERT(m_jit.graph(), node, triggerIterator != m_jit.jitCode()->tierUpEntryTriggers.end()); 5784 TierUpEntryTrigger* forceEntryTrigger = &(m_jit.jitCode()->tierUpEntryTriggers.find(bytecodeIndex)->value); 5785 5786 static_assert(sizeof(TierUpEntryTrigger) == 1, "8-bit load is generated below"); 5787 static_assert(!static_cast<uint8_t>(TierUpEntryTrigger::None), "NonZero test below depends on this"); 5784 uint8_t* forceEntryTrigger = &(m_jit.jitCode()->tierUpEntryTriggers.find(bytecodeIndex)->value); 5785 5788 5786 MacroAssembler::Jump forceOSREntry = m_jit.branchTest8(MacroAssembler::NonZero, MacroAssembler::AbsoluteAddress(forceEntryTrigger)); 5789 5787 MacroAssembler::Jump overflowedCounter = m_jit.branchAdd32( … … 5805 5803 silentSpill(savePlans); 5806 5804 m_jit.setupArgumentsWithExecState(TrustedImm32(bytecodeIndex)); 5807 appendCallSetResult( checkTierUpAndOSREnterNow, tempGPR);5805 appendCallSetResult(triggerOSREntryNow, tempGPR); 5808 5806 5809 5807 if (savePlans.isEmpty()) -
trunk/Source/JavaScriptCore/dfg/DFGToFTLForOSREntryDeferredCompilationCallback.cpp
r211224 r211245 36 36 namespace JSC { namespace DFG { 37 37 38 ToFTLForOSREntryDeferredCompilationCallback::ToFTLForOSREntryDeferredCompilationCallback( TierUpEntryTrigger* forcedOSREntryTrigger)38 ToFTLForOSREntryDeferredCompilationCallback::ToFTLForOSREntryDeferredCompilationCallback(uint8_t* forcedOSREntryTrigger) 39 39 : m_forcedOSREntryTrigger(forcedOSREntryTrigger) 40 40 { … … 45 45 } 46 46 47 Ref<ToFTLForOSREntryDeferredCompilationCallback>ToFTLForOSREntryDeferredCompilationCallback::create( TierUpEntryTrigger* forcedOSREntryTrigger)47 Ref<ToFTLForOSREntryDeferredCompilationCallback>ToFTLForOSREntryDeferredCompilationCallback::create(uint8_t* forcedOSREntryTrigger) 48 48 { 49 49 return adoptRef(*new ToFTLForOSREntryDeferredCompilationCallback(forcedOSREntryTrigger)); … … 59 59 } 60 60 61 *m_forcedOSREntryTrigger = TierUpEntryTrigger::TakeSlowPath;61 *m_forcedOSREntryTrigger = 1; 62 62 } 63 63 … … 77 77 jitCode->setOSREntryBlock(*codeBlock->vm(), profiledDFGCodeBlock, codeBlock); 78 78 unsigned osrEntryBytecode = codeBlock->jitCode()->ftlForOSREntry()->bytecodeIndex(); 79 jitCode->tierUpEntryTriggers.set(osrEntryBytecode, TierUpEntryTrigger::TakeSlowPath);79 jitCode->tierUpEntryTriggers.set(osrEntryBytecode, 1); 80 80 break; 81 81 } -
trunk/Source/JavaScriptCore/dfg/DFGToFTLForOSREntryDeferredCompilationCallback.h
r211224 r211245 28 28 #if ENABLE(FTL_JIT) 29 29 30 #include "DFGTierUpEntryTrigger.h"31 30 #include "DeferredCompilationCallback.h" 32 31 #include <wtf/RefPtr.h> … … 40 39 class ToFTLForOSREntryDeferredCompilationCallback : public DeferredCompilationCallback { 41 40 protected: 42 ToFTLForOSREntryDeferredCompilationCallback( TierUpEntryTrigger* forcedOSREntryTrigger);41 ToFTLForOSREntryDeferredCompilationCallback(uint8_t* forcedOSREntryTrigger); 43 42 44 43 public: 45 44 virtual ~ToFTLForOSREntryDeferredCompilationCallback(); 46 45 47 static Ref<ToFTLForOSREntryDeferredCompilationCallback> create( TierUpEntryTrigger* forcedOSREntryTrigger);46 static Ref<ToFTLForOSREntryDeferredCompilationCallback> create(uint8_t* forcedOSREntryTrigger); 48 47 49 48 virtual void compilationDidBecomeReadyAsynchronously(CodeBlock*, CodeBlock* profiledDFGCodeBlock); … … 51 50 52 51 private: 53 TierUpEntryTrigger* m_forcedOSREntryTrigger;52 uint8_t* m_forcedOSREntryTrigger; 54 53 }; 55 54 -
trunk/Source/JavaScriptCore/ftl/FTLOSREntry.cpp
r211224 r211245 40 40 41 41 SUPPRESS_ASAN 42 Expected<void*, OSREntryFail>prepareOSREntry(42 void* prepareOSREntry( 43 43 ExecState* exec, CodeBlock* dfgCodeBlock, CodeBlock* entryCodeBlock, 44 44 unsigned bytecodeIndex, unsigned streamIndex) … … 62 62 if (Options::verboseOSR()) 63 63 dataLog(" OSR failed because we don't have an entrypoint for bc#", bytecodeIndex, "; ours is for bc#", entryCode->bytecodeIndex(), "\n"); 64 return makeUnexpected(OSREntryFail::WrongBytecode);64 return 0; 65 65 } 66 66 … … 96 96 if (Options::verboseOSR()) 97 97 dataLog(" OSR failed because stack growth failed.\n"); 98 return makeUnexpected(OSREntryFail::StackGrowthFailed);98 return 0; 99 99 } 100 100 -
trunk/Source/JavaScriptCore/ftl/FTLOSREntry.h
r211224 r211245 28 28 #if ENABLE(FTL_JIT) 29 29 30 #include <wtf/Expected.h>31 32 30 namespace JSC { 33 31 … … 37 35 namespace FTL { 38 36 39 enum class OSREntryFail { 40 WrongBytecode, 41 StackGrowthFailed, 42 }; 43 44 Expected<void*, OSREntryFail> prepareOSREntry( 37 void* prepareOSREntry( 45 38 ExecState*, CodeBlock* dfgCodeBlock, CodeBlock* entryCodeBlock, unsigned bytecodeIndex, 46 39 unsigned streamIndex); -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r211224 r211245 1424 1424 ASSERT(JITCode::isOptimizingJIT(optimizedCodeBlock->jitType())); 1425 1425 1426 if (auto osrEntryPreparation = DFG::prepareOSREntry(exec, optimizedCodeBlock, bytecodeIndex)) { 1427 void* dataBuffer = osrEntryPreparation.value(); 1426 if (void* dataBuffer = DFG::prepareOSREntry(exec, optimizedCodeBlock, bytecodeIndex)) { 1428 1427 CODEBLOCK_LOG_EVENT(optimizedCodeBlock, "osrEntry", ("at bc#", bytecodeIndex)); 1429 1428 if (Options::verboseOSR()) {
Note: See TracChangeset
for help on using the changeset viewer.