diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/dfg/DFGCommon.h | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGCommon.h')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGCommon.h | 173 |
1 files changed, 121 insertions, 52 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGCommon.h b/Source/JavaScriptCore/dfg/DFGCommon.h index 7b4b1db5f..4104eb324 100644 --- a/Source/JavaScriptCore/dfg/DFGCommon.h +++ b/Source/JavaScriptCore/dfg/DFGCommon.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2011-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,14 +23,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef DFGCommon_h -#define DFGCommon_h +#pragma once -#include <wtf/Platform.h> +#include "DFGCompilationMode.h" #if ENABLE(DFG_JIT) -#include "CodeOrigin.h" #include "Options.h" #include "VirtualRegister.h" @@ -41,11 +39,6 @@ struct Node; typedef uint32_t BlockIndex; static const BlockIndex NoBlock = UINT_MAX; -struct NodePointerTraits { - static Node* defaultValue() { return 0; } - static bool isEmptyForDump(Node* value) { return !value; } -}; - // Use RefChildren if the child ref counts haven't already been adjusted using // other means and either of the following is true: // - The node you're creating is MustGenerate. @@ -63,19 +56,28 @@ enum RefNodeMode { DontRefNode }; -inline bool verboseCompilationEnabled() +enum SwitchKind { + SwitchImm, + SwitchChar, + SwitchString, + SwitchCell +}; + +inline bool verboseCompilationEnabled(CompilationMode mode = DFGMode) { - return Options::verboseCompilation() || Options::dumpGraphAtEachPhase(); + return Options::verboseCompilation() || Options::dumpGraphAtEachPhase() || (isFTL(mode) && Options::verboseFTLCompilation()); } -inline bool logCompilationChanges() +inline bool logCompilationChanges(CompilationMode mode = DFGMode) { - return verboseCompilationEnabled() || Options::logCompilationChanges(); + return verboseCompilationEnabled(mode) || Options::logCompilationChanges(); } -inline bool shouldDumpGraphAtEachPhase() +inline bool shouldDumpGraphAtEachPhase(CompilationMode mode) { - return Options::dumpGraphAtEachPhase(); + if (isFTL(mode)) + return Options::dumpGraphAtEachPhase() || Options::dumpDFGFTLGraphAtEachPhase(); + return Options::dumpGraphAtEachPhase() || Options::dumpDFGGraphAtEachPhase(); } inline bool validationEnabled() @@ -87,15 +89,6 @@ inline bool validationEnabled() #endif } -inline bool enableConcurrentJIT() -{ -#if ENABLE(CONCURRENT_JIT) - return Options::enableConcurrentJIT() && Options::numberOfCompilerThreads(); -#else - return false; -#endif -} - inline bool enableInt52() { #if USE(JSVALUE64) @@ -105,9 +98,57 @@ inline bool enableInt52() #endif } -enum SpillRegistersMode { NeedToSpill, DontSpill }; +// The prediction propagator effectively does four passes, with the last pass +// being done by the separate FixuPhase. +enum PredictionPass { + // We're converging in a straight-forward forward flow fixpoint. This is the + // most conventional part of the propagator - it makes only monotonic decisions + // based on value profiles and rare case profiles. It ignores baseline JIT rare + // case profiles. The goal here is to develop a good guess of which variables + // are likely to be purely numerical, which generally doesn't require knowing + // the rare case profiles. + PrimaryPass, + + // At this point we know what is numerical and what isn't. Non-numerical inputs + // to arithmetic operations will not have useful information in the Baseline JIT + // rare case profiles because Baseline may take slow path on non-numerical + // inputs even if the DFG could handle the input on the fast path. Boolean + // inputs are the most obvious example. This pass of prediction propagation will + // use Baseline rare case profiles for purely numerical operations and it will + // ignore them for everything else. The point of this pass is to develop a good + // guess of which variables are likely to be doubles. + // + // This pass is intentionally weird and goes against what is considered good + // form when writing a static analysis: a new data flow of booleans will cause + // us to ignore rare case profiles except that by then, we will have already + // propagated double types based on our prior assumption that we shouldn't + // ignore rare cases. This probably won't happen because the PrimaryPass is + // almost certainly going to establish what is and isn't numerical. But it's + // conceivable that during this pass we will discover a new boolean data flow. + // This ends up being sound because the prediction propagator could literally + // make any guesses it wants and still be sound (worst case, we OSR exit more + // often or use too general of types are run a bit slower). This will converge + // because we force monotonicity on the types of nodes and variables. So, the + // worst thing that can happen is that we violate basic laws of theoretical + // decency. + RareCasePass, + + // At this point we know what is numerical and what isn't, and we also know what + // is a double and what isn't. So, we start forcing variables to be double. + // Doing so may have a cascading effect so this is a fixpoint. It's monotonic + // in the sense that once a variable is forced double, it cannot be forced in + // the other direction. + DoubleVotingPass, + + // This pass occurs once we have converged. At this point we are just installing + // type checks based on the conclusions we have already reached. It's important + // for this pass to reach the same conclusions that DoubleVotingPass reached. + FixupPass +}; + +enum StructureRegistrationState { HaveNotStartedRegistering, AllStructuresAreRegistered }; -enum NoResultTag { NoResult }; +enum StructureRegistrationResult { StructureRegisteredNormally, StructureRegisteredAndWatched }; enum OptimizationFixpointState { BeforeFixpoint, FixpointNotConverged, FixpointConverged }; @@ -145,12 +186,10 @@ enum GraphForm { // expect to be live at the head, and which locals they make available at the // tail. ThreadedCPS form also implies that: // - // - GetLocals and SetLocals to uncaptured variables are not redundant within - // a basic block. + // - GetLocals and SetLocals are not redundant within a basic block. // // - All GetLocals and Flushes are linked directly to the last access point - // of the variable, which must not be another GetLocal if the variable is - // uncaptured. + // of the variable, which must not be another GetLocal. // // - Phantom(Phi) is not legal, but PhantomLocal is. // @@ -208,14 +247,44 @@ inline KillStatus killStatusForDoesKill(bool doesKill) return doesKill ? DoesKill : DoesNotKill; } -template<typename T, typename U> -bool checkAndSet(T& left, U right) -{ - if (left == right) - return false; - left = right; - return true; -} +enum class PlanStage { + Initial, + AfterFixup +}; + +// If possible, this will acquire a lock to make sure that if multiple threads +// start crashing at the same time, you get coherent dump output. Use this only +// when you're forcing a crash with diagnostics. +void startCrashing(); + +JS_EXPORT_PRIVATE bool isCrashing(); + +struct NodeAndIndex { + NodeAndIndex() + : node(nullptr) + , index(UINT_MAX) + { + } + + NodeAndIndex(Node* node, unsigned index) + : node(node) + , index(index) + { + ASSERT(!node == (index == UINT_MAX)); + } + + bool operator!() const + { + return !node; + } + + Node* node; + unsigned index; +}; + +// A less-than operator for strings that is useful for generating string switches. Sorts by < +// relation on characters. Ensures that if a is a prefix of b, then a < b. +bool stringLessThan(StringImpl& a, StringImpl& b); } } // namespace JSC::DFG @@ -235,7 +304,12 @@ namespace JSC { namespace DFG { // Put things here that must be defined even if ENABLE(DFG_JIT) is false. -enum CapabilityLevel { CannotCompile, CanInline, CanCompile, CanCompileAndInline, CapabilityLevelNotSet }; +enum CapabilityLevel { + CannotCompile, + CanCompile, + CanCompileAndInline, + CapabilityLevelNotSet +}; inline bool canCompile(CapabilityLevel level) { @@ -251,7 +325,6 @@ inline bool canCompile(CapabilityLevel level) inline bool canInline(CapabilityLevel level) { switch (level) { - case CanInline: case CanCompileAndInline: return true; default: @@ -264,14 +337,6 @@ inline CapabilityLevel leastUpperBound(CapabilityLevel a, CapabilityLevel b) switch (a) { case CannotCompile: return CannotCompile; - case CanInline: - switch (b) { - case CanInline: - case CanCompileAndInline: - return CanInline; - default: - return CannotCompile; - } case CanCompile: switch (b) { case CanCompile: @@ -291,16 +356,20 @@ inline CapabilityLevel leastUpperBound(CapabilityLevel a, CapabilityLevel b) } // Unconditionally disable DFG disassembly support if the DFG is not compiled in. -inline bool shouldShowDisassembly() +inline bool shouldDumpDisassembly(CompilationMode mode = DFGMode) { #if ENABLE(DFG_JIT) - return Options::showDisassembly() || Options::showDFGDisassembly(); + return Options::dumpDisassembly() || Options::dumpDFGDisassembly() || (isFTL(mode) && Options::dumpFTLDisassembly()); #else + UNUSED_PARAM(mode); return false; #endif } } } // namespace JSC::DFG -#endif // DFGCommon_h +namespace WTF { +void printInternal(PrintStream&, JSC::DFG::CapabilityLevel); + +} // namespace WTF |