blob: 32860ce020c0955d3944419feae283161fe21ae4 [file]
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#pragma once
namespace Js
{
#if DBG && defined(ENABLE_SCRIPT_DEBUGGING)
enum DebuggerMode : unsigned int;
#endif
class FunctionExecutionStateMachine
{
public:
FunctionExecutionStateMachine();
void InitializeExecutionModeAndLimits(FunctionBody* functionBody);
void ReinitializeExecutionModeAndLimits(FunctionBody* functionBody);
// Public Getters and Setters
ExecutionMode GetExecutionMode() const;
void SetDefaultInterpreterExecutionMode();
void SetAsmJsExecutionMode();
// Interpreter-related functions
ExecutionMode GetInterpreterExecutionMode(const bool isPostBailout);
bool IsInterpreterExecutionMode() const;
uint16 GetProfiledIterations() const;
uint32 GetInterpretedCount() const { return interpretedCount; }
uint32 SetInterpretedCount(uint32 val) { return interpretedCount = val; }
uint32 IncreaseInterpretedCount() { return interpretedCount++; }
bool InterpretedSinceCallCountCollection() const;
void CollectInterpretedCounts();
void CommitExecutedIterations();
// JIT-relatedfunctions
void SetIsSpeculativeJitCandidate();
uint16 GetSimpleJitLimit() const { return simpleJitLimit; }
void ResetSimpleJitLimit();
uint16 GetSimpleJitExecutedIterations() const;
void SetSimpleJitCallCount(const uint16 simpleJitLimit) const;
void SetFullJitThreshold(const uint16 newFullJitThreshold, const bool skipSimpleJit = false);
uint16 GetFullJitThreshold() const { return fullJitThreshold; }
void SetFullJitRequeueThreshold(const uint16 newFullJitRequeueThreshold);
// Transition functions
bool TryTransitionToNextExecutionMode();
void TryTransitionToNextInterpreterExecutionMode();
bool TryTransitionToJitExecutionMode();
void TransitionToSimpleJitExecutionMode();
void TransitionToFullJitExecutionMode();
// Debug functions
void PrintLimits() const;
void AssertIsInitialized() const;
private:
// This enum creates a linear view of the progression of ExecutionModes, as
// described in the banner comment for TryTransitionToNextExecutionMode. Each
// state has an associated member variable for the state's limit.
// For more information about ExecutionModes, see ExecutionModes.h.
enum class ExecutionState : uint8
{
Interpreter,
AutoProfilingInterpreter0,
ProfilingInterpreter0,
AutoProfilingInterpreter1,
SimpleJit,
ProfilingInterpreter1,
FullJit
};
ExecutionState ModeToState(ExecutionMode mode) const;
ExecutionMode StateToMode(ExecutionState state) const;
uint16& GetStateLimit(ExecutionState state);
bool IsTerminalState(ExecutionState state);
void SetExecutionState(ExecutionState state);
ExecutionState GetDefaultInterpreterExecutionState() const;
void CommitExecutedIterations(uint16 &limit, const uint executedIterations);
void VerifyExecutionMode(const ExecutionMode executionMode) const;
void VerifyExecutionModeLimits() const;
// This state machine should be a member of this owner FunctionBody
FieldWithBarrier(FunctionBody*) owner;
// Tracks the current execution state. See ExecutionModes.h for more info.
FieldWithBarrier(ExecutionState) executionState;
// Each of the following limits below is decremented when transitioning from its related mode:
// Number of times to run interpreter (no profiling) before advancing to next mode
FieldWithBarrier(uint16) interpreterLimit;
// Number of times to run interpreter (min profiling) before advancing to next mode
FieldWithBarrier(uint16) autoProfilingInterpreter0Limit;
// Number of times to run interpreter (full profiling) before advancing to next mode
FieldWithBarrier(uint16) profilingInterpreter0Limit;
// Number of times to run interpreter (min profiling) after already running min and full profiling
FieldWithBarrier(uint16) autoProfilingInterpreter1Limit;
// Number of times to run simple JIT before advancing to next mode
FieldWithBarrier(uint16) simpleJitLimit;
// Number of times to run interpreter (full profiling) before advancing to next mode
FieldWithBarrier(uint16) profilingInterpreter1Limit;
// Total limit to run in non-full JIT execution mode. Typically the sum of the other limits
FieldWithBarrier(uint16) fullJitThreshold;
// Number of attempts to schedule FullJIT until it becomes forced
FieldWithBarrier(uint16) fullJitRequeueThreshold;
// Total number of times this function has run under the interpreter with full profiling
FieldWithBarrier(uint16) committedProfiledIterations;
// Number of times this function has run under the interpreter in the current execution mode
FieldWithBarrier(uint32) interpretedCount;
// Used to detect when interpretedCount changed from a particular call
FieldWithBarrier(uint32) lastInterpretedCount;
inline uint16 GetDefaultAutoProfilingInterpreter0Limit(bool isCoroutine) const;
inline uint16 GetDefaultProfilingInterpreter0Limit(bool isCoroutine) const;
inline uint16 GetDefaultAutoProfilingInterpreter1Limit(bool isCoroutine) const;
inline uint16 GetDefaultSimpleJitLimit(bool isCoroutine) const;
inline uint16 GetDefaultProfilingInterpreter1Limit(bool isCoroutine) const;
inline uint16 GetDefaultFullJitThreshold(bool isCoroutine) const;
#if DBG
FieldWithBarrier(bool) initializedExecutionModeAndLimits;
// Temporary debug flags for automation
FieldWithBarrier(bool) hasBeenReinitialized;
#ifdef ENABLE_SCRIPT_DEBUGGING
FieldWithBarrier(Js::DebuggerMode) initDebuggerMode;
FieldWithBarrier(Js::DebuggerMode) reinitDebuggerMode;
#endif
#endif
};
};