diff --git a/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml b/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml index 989ccdc9319a92..918ba5b814aaa3 100644 --- a/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml +++ b/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml @@ -30,6 +30,7 @@ parameters: runtimeVariant: '' shouldContinueOnError: false SuperPmiCollect: '' + SuperPmiReplayType: '' SuperPmiDiffType: '' SuperPmiBaseJitOptions: '' SuperPmiDiffJitOptions: '' @@ -65,6 +66,7 @@ steps: RuntimeFlavor: ${{ parameters.runtimeFlavor }} _RuntimeVariant: ${{ parameters.runtimeVariant }} _SuperPmiCollect: ${{ parameters.SuperPmiCollect }} + _SuperPmiReplayType: ${{ parameters.SuperPmiReplayType }} _SuperPmiDiffType: ${{ parameters.SuperPmiDiffType }} _SuperPmiBaseJitOptions: ${{ parameters.SuperPmiBaseJitOptions }} _SuperPmiDiffJitOptions: ${{ parameters.SuperPmiDiffJitOptions }} diff --git a/eng/pipelines/coreclr/superpmi-replay-apx.yml b/eng/pipelines/coreclr/superpmi-replay-apx.yml new file mode 100644 index 00000000000000..f5e3f0d1adba4e --- /dev/null +++ b/eng/pipelines/coreclr/superpmi-replay-apx.yml @@ -0,0 +1,19 @@ +trigger: none + +schedules: +- cron: "0 7 * * *" + displayName: Daily at 11:00 PM (UTC-8:00) + branches: + include: + - main + always: true + +variables: + - template: /eng/pipelines/common/variables.yml + +extends: + template: /eng/pipelines/coreclr/templates/jit-replay-pipeline.yml + parameters: + platforms: + - windows_x64 + replayType: apx \ No newline at end of file diff --git a/eng/pipelines/coreclr/superpmi-replay.yml b/eng/pipelines/coreclr/superpmi-replay.yml index 322b3207dbd965..b3eebfe27034b1 100644 --- a/eng/pipelines/coreclr/superpmi-replay.yml +++ b/eng/pipelines/coreclr/superpmi-replay.yml @@ -12,55 +12,9 @@ variables: - template: /eng/pipelines/common/variables.yml extends: - template: /eng/pipelines/common/templates/pipeline-with-resources.yml + template: /eng/pipelines/coreclr/templates/jit-replay-pipeline.yml parameters: - stages: - # Don't run if the JIT-EE GUID has changed, - # since there won't be any SuperPMI collections with the new GUID until the collection - # pipeline completes after this PR is merged. - - ${{ if eq(variables['Build.Reason'], 'PullRequest') }}: - - stage: EvaluatePaths - displayName: Evaluate Paths - jobs: - - template: /eng/pipelines/common/evaluate-paths-job.yml - parameters: - paths: - - subset: jiteeversionguid - include: - - src/coreclr/inc/jiteeversionguid.h - - - stage: Build - jobs: - - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/common/global-build-job.yml - buildConfig: checked - platforms: - - windows_x64 - - windows_x86 - jobParameters: - buildArgs: -s clr.alljits+clr.spmi -c $(_BuildConfig) - postBuildSteps: - - template: /eng/pipelines/common/upload-artifact-step.yml - parameters: - rootFolder: $(Build.SourcesDirectory)/artifacts/bin/coreclr - includeRootFolder: false - archiveType: $(archiveType) - tarCompression: $(tarCompression) - archiveExtension: $(archiveExtension) - artifactName: CheckedJIT_$(osGroup)$(osSubgroup)_$(archType) - displayName: JIT and SuperPMI Assets - condition: not(eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_jiteeversionguid.containsChange'], true)) - - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/coreclr/templates/superpmi-replay-job.yml - buildConfig: checked - platforms: - - windows_x64 - - windows_x86 - helixQueueGroup: ci - helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml - jobParameters: - condition: not(eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_jiteeversionguid.containsChange'], true)) + platforms: + - windows_x64 + - windows_x86 + replayType: standard diff --git a/eng/pipelines/coreclr/templates/jit-replay-pipeline.yml b/eng/pipelines/coreclr/templates/jit-replay-pipeline.yml new file mode 100644 index 00000000000000..74f2caf2ff3852 --- /dev/null +++ b/eng/pipelines/coreclr/templates/jit-replay-pipeline.yml @@ -0,0 +1,58 @@ +parameters: + - name: platforms + type: object + - name: replayType + type: string + default: standard + +extends: + template: /eng/pipelines/common/templates/pipeline-with-resources.yml + parameters: + stages: + # Don't run if the JIT-EE GUID has changed, + # since there won't be any SuperPMI collections with the new GUID until the collection + # pipeline completes after this PR is merged. + - ${{ if eq(variables['Build.Reason'], 'PullRequest') }}: + - stage: EvaluatePaths + displayName: Evaluate Paths + jobs: + - template: /eng/pipelines/common/evaluate-paths-job.yml + parameters: + paths: + - subset: jiteeversionguid + include: + - src/coreclr/inc/jiteeversionguid.h + + - stage: Build + jobs: + + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: checked + platforms: ${{ parameters.platforms }} + jobParameters: + buildArgs: -s clr.alljits+clr.spmi -c $(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/common/upload-artifact-step.yml + parameters: + rootFolder: $(Build.SourcesDirectory)/artifacts/bin/coreclr + includeRootFolder: false + archiveType: $(archiveType) + tarCompression: $(tarCompression) + archiveExtension: $(archiveExtension) + artifactName: BuildArtifacts_$(osGroup)$(osSubgroup)_$(archType)_$(_BuildConfig) + displayName: Build Assets + condition: not(eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_jiteeversionguid.containsChange'], true)) + + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/coreclr/templates/superpmi-replay-job.yml + buildConfig: checked + platforms: ${{ parameters.platforms }} + helixQueueGroup: ci + helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml + jobParameters: + condition: not(eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_jiteeversionguid.containsChange'], true)) + replayType: ${{ parameters.replayType }} + unifiedArtifactsName: BuildArtifacts_$(osGroup)$(osSubgroup)_$(archType)_$(_BuildConfig) diff --git a/eng/pipelines/coreclr/templates/run-superpmi-replay-job.yml b/eng/pipelines/coreclr/templates/run-superpmi-replay-job.yml index 4047a8cb2f7cf6..27cc61c653de47 100644 --- a/eng/pipelines/coreclr/templates/run-superpmi-replay-job.yml +++ b/eng/pipelines/coreclr/templates/run-superpmi-replay-job.yml @@ -16,6 +16,7 @@ parameters: enableTelemetry: false # optional -- enable for telemetry liveLibrariesBuildConfig: '' # optional -- live-live libraries configuration to use for the run helixQueues: '' # required -- Helix queues + replayType: 'standard' # required -- 'standard', 'apx' jobs: - template: /eng/pipelines/common/templates/runtimes/xplat-job.yml @@ -47,6 +48,9 @@ jobs: - ${{ each variable in parameters.variables }}: - ${{insert}}: ${{ variable }} + - name: replayType + value: ${{ parameters.replayType }} + - template: /eng/pipelines/coreclr/templates/jit-python-variables.yml parameters: osGroup: ${{ parameters.osGroup }} @@ -74,8 +78,8 @@ jobs: mkdir $(SpmiLogsLocation) displayName: Create directories - - script: $(PythonScript) $(Build.SourcesDirectory)/src/coreclr/scripts/superpmi_replay_setup.py -source_directory $(Build.SourcesDirectory) -product_directory $(buildProductRootFolderPath) -arch $(archType) - displayName: ${{ format('SuperPMI replay setup ({0})', parameters.archType) }} + - script: $(PythonScript) $(Build.SourcesDirectory)/src/coreclr/scripts/superpmi_replay_setup.py -source_directory $(Build.SourcesDirectory) -product_directory $(buildProductRootFolderPath) -type $(replayType) -arch $(archType) + displayName: ${{ format('SuperPMI replay setup ({0} {1})', parameters.replayType, parameters.archType) }} # Run superpmi replay in helix - template: /eng/pipelines/common/templates/runtimes/send-to-helix-step.yml @@ -93,6 +97,7 @@ jobs: BuildConfig: ${{ parameters.buildConfig }} osGroup: ${{ parameters.osGroup }} archType: ${{ parameters.archType }} + SuperPmiReplayType: ${{ parameters.replayType }} # Always upload the available logs for diagnostics - task: CopyFiles@2 diff --git a/eng/pipelines/coreclr/templates/superpmi-replay-job.yml b/eng/pipelines/coreclr/templates/superpmi-replay-job.yml index ea7854339a2147..ec364c8d506321 100644 --- a/eng/pipelines/coreclr/templates/superpmi-replay-job.yml +++ b/eng/pipelines/coreclr/templates/superpmi-replay-job.yml @@ -9,12 +9,14 @@ parameters: variables: {} helixQueues: '' runJobTemplate: '/eng/pipelines/coreclr/templates/run-superpmi-replay-job.yml' + replayType: 'standard' + unifiedArtifactsName: '' jobs: - template: ${{ parameters.runJobTemplate }} parameters: - jobName: ${{ format('superpmi_replay_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} - displayName: ${{ format('SuperPMI replay {0}{1} {2} {3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + jobName: ${{ format('superpmi_replay_{0}_{1}{2}_{3}_{4}', parameters.replayType, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + displayName: ${{ format('SuperPMI replay {0} {1}{2} {3} {4}', parameters.replayType, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} pool: ${{ parameters.pool }} buildConfig: ${{ parameters.buildConfig }} archType: ${{ parameters.archType }} @@ -23,6 +25,7 @@ jobs: condition: ${{ parameters.condition }} timeoutInMinutes: ${{ parameters.timeoutInMinutes }} helixQueues: ${{ parameters.helixQueues }} + replayType: ${{ parameters.replayType }} dependsOn: - 'build_${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.buildConfig }}_' @@ -30,11 +33,11 @@ jobs: steps: - # Download jit builds + # Download builds - template: /eng/pipelines/common/download-artifact-step.yml parameters: unpackFolder: $(Build.SourcesDirectory)/artifacts/bin/coreclr - artifactFileName: 'CheckedJIT_$(osGroup)$(osSubgroup)_$(archType)$(archiveExtension)' - artifactName: 'CheckedJIT_$(osGroup)$(osSubgroup)_$(archType)' - displayName: 'JIT checked build' + artifactFileName: '${{ parameters.unifiedArtifactsName }}$(archiveExtension)' + artifactName: '${{ parameters.unifiedArtifactsName }}' + displayName: 'unified artifacts' cleanUnpackFolder: false diff --git a/src/coreclr/scripts/superpmi-replay.proj b/src/coreclr/scripts/superpmi-replay.proj index 398dec78ecc221..c19831f43fb2f7 100644 --- a/src/coreclr/scripts/superpmi-replay.proj +++ b/src/coreclr/scripts/superpmi-replay.proj @@ -24,11 +24,17 @@ timeout: %(HelixWorkItem.Timeout) '"/> --> + + + standard + $(_SuperPmiReplayType) + + %HELIX_PYTHONPATH% %HELIX_CORRELATION_PAYLOAD% %HELIX_WORKITEM_UPLOAD_ROOT% - $(Python) $(ProductDirectory)\superpmi_replay.py -jit_directory $(ProductDirectory) + $(Python) $(ProductDirectory)\superpmi_replay.py -type $(SuperPmiReplayType) -jit_directory $(ProductDirectory) 3:15 @@ -49,7 +55,7 @@ - + @@ -97,7 +103,7 @@ - + @@ -118,11 +124,26 @@ + + + + + + + + + + + + + + + $(WorkItemCommand) -arch %(HelixWorkItem.Architecture) -platform %(HelixWorkItem.Platform) -partition %(HelixWorkItem.Partition) -partition_count %(HelixWorkItem.PartitionCount) -log_directory $(SuperpmiLogsLocation) $(WorkItemTimeout) - superpmi_%(HelixWorkItem.Platform)_%(HelixWorkItem.Architecture)_%(HelixWorkItem.Partition).log + superpmi_final_%(HelixWorkItem.Platform)_%(HelixWorkItem.Architecture)_%(HelixWorkItem.Partition).log diff --git a/src/coreclr/scripts/superpmi_replay.py b/src/coreclr/scripts/superpmi_replay.py index d2cf1eec37fb7b..6af44151cb599a 100644 --- a/src/coreclr/scripts/superpmi_replay.py +++ b/src/coreclr/scripts/superpmi_replay.py @@ -19,25 +19,36 @@ parser = argparse.ArgumentParser(description="description") +parser.add_argument("-type", required=True, help="Type of replay (standard, apx)") parser.add_argument("-arch", help="Architecture") parser.add_argument("-platform", help="OS platform") parser.add_argument("-jit_directory", help="path to the directory containing clrjit binaries") parser.add_argument("-log_directory", help="path to the directory containing superpmi log files") parser.add_argument("-partition", help="Partition number specifying which set of flags to use: between 1 and the `-partition_count` value") -parser.add_argument("-partition_count", help="Count of the total number of partitions we are using: should be <= 9 (number of jit_flags_all elements)") - -jit_flags_all = [ - "JitStressRegs=0", - "JitStressRegs=1", - "JitStressRegs=2", - "JitStressRegs=3", - "JitStressRegs=4", - "JitStressRegs=8", - "JitStressRegs=0x10", - "JitStressRegs=0x80", - "JitStressRegs=0x1000", +parser.add_argument("-partition_count", help="Count of the total number of partitions we are using: should be <= the total number of flags combinations for the type") + +configuration_standard = [ + [ "JitStressRegs=0" ], + [ "JitStressRegs=1" ], + [ "JitStressRegs=2" ], + [ "JitStressRegs=3" ], + [ "JitStressRegs=4" ], + [ "JitStressRegs=8" ], + [ "JitStressRegs=0x10" ], + [ "JitStressRegs=0x80" ], + [ "JitStressRegs=0x1000" ] ] +configuration_apx = [ + [ "RunAltJitCode=0", "EnableAPX=1" ], + [ "RunAltJitCode=0", "EnableAPX=1", "EnableApxNDD=1" ], + [ "RunAltJitCode=0", "EnableAPX=1", "JitStressRex2Encoding=1" ], + [ "RunAltJitCode=0", "EnableAPX=1", "JitStressPromotedEvexEncoding=1" ], + [ "RunAltJitCode=0", "EnableAPX=1", "JitStressRegs=4000" ], + [ "RunAltJitCode=0", "EnableAPX=1", "EnableApxNDD=1", "JitStressRex2Encoding=1", "JitStressPromotedEvexEncoding=1", "JitStressRegs=4000" ] +] + + def split(a, n): """ Splits array `a` in `n` partitions. Slightly modified from https://stackoverflow.com/a/2135920. @@ -66,6 +77,11 @@ def setup_args(args): coreclr_args = CoreclrArguments(args, require_built_core_root=False, require_built_product_dir=False, require_built_test_dir=False, default_build_type="Checked") + coreclr_args.verify(args, + "type", + lambda type: type in ["standard", "apx"], + "Invalid type \"{}\"".format) + coreclr_args.verify(args, "arch", lambda unused: True, @@ -137,8 +153,14 @@ def main(main_args): os_name = "universal" if arch_name.startswith("arm") else os_name jit_path = os.path.join(coreclr_args.jit_directory, 'clrjit_{}_{}_{}.dll'.format(os_name, arch_name, host_arch_name)) - jit_flags_partitioned = split(jit_flags_all, coreclr_args.partition_count) - jit_flags = jit_flags_partitioned[coreclr_args.partition - 1] # partition number is 1-based + type_configuration_settings = None + if coreclr_args.type == 'standard': + type_configuration_settings = configuration_standard + elif coreclr_args.type == 'apx': + type_configuration_settings = configuration_apx + + configuration_settings_partitioned = split(type_configuration_settings, coreclr_args.partition_count) + partition_configuration_settings = configuration_settings_partitioned[coreclr_args.partition - 1] # partition number is 1-based print("Running superpmi.py download") run_command([python_path, @@ -152,33 +174,47 @@ def main(main_args): "-log_level", "debug"], _exit_on_fail=True) failed_runs = [] - for jit_flag in jit_flags: - log_file = os.path.join(log_directory, 'superpmi_{}.log'.format(jit_flag.replace("=", "_"))) - print("Running superpmi.py replay for {}".format(jit_flag)) + for configuration_settings in partition_configuration_settings: + # Construct the command-line options and log file based on the configuration settings + log_file_tag = "_".join(configuration_settings).replace("=", "_") + log_file = os.path.join(log_directory, 'superpmi_config_{}.log'.format(log_file_tag)) + + config_arguments = [] + config_display = "" + for flag in configuration_settings: + config_arguments += "-jitoption", flag + config_display += " " + flag + + # Special case: setting altjit requires passing `--altjit` to superpmi.py. + if coreclr_args.type == 'apx': + config_arguments += [ "--altjit" ] + config_display += " --altjit" + + print("Running superpmi.py replay for{}".format(config_display)) - _, _, return_code = run_command([ + command_line = [ python_path, os.path.join(cwd, "superpmi.py"), "replay", "-core_root", cwd, - "-jitoption", jit_flag, "-target_os", platform_name, "-target_arch", arch_name, "-arch", host_arch_name, "-jit_path", jit_path, "-spmi_location", spmi_location, "-log_level", "debug", - "-log_file", log_file]) + "-log_file", log_file] + config_arguments + _, _, return_code = run_command(command_line) if return_code != 0: failed_runs.append("Failure in {}".format(log_file)) # Consolidate all superpmi_*.logs in superpmi_platform_architecture.log - final_log_name = os.path.join(log_directory, "superpmi_{}_{}_{}.log".format(platform_name, arch_name, coreclr_args.partition)) + final_log_name = os.path.join(log_directory, "superpmi_final_{}_{}_{}.log".format(platform_name, arch_name, coreclr_args.partition)) print("Consolidating final {}".format(final_log_name)) with open(final_log_name, "a") as final_superpmi_log: for superpmi_log in os.listdir(log_directory): - if not superpmi_log.startswith("superpmi_Jit") or not superpmi_log.endswith(".log"): + if not superpmi_log.startswith("superpmi_config_") or not superpmi_log.endswith(".log"): continue print("Appending {}".format(superpmi_log)) @@ -193,7 +229,7 @@ def main(main_args): if len(failed_runs) > 0: final_superpmi_log.write(os.linesep) final_superpmi_log.write(os.linesep) - final_superpmi_log.write("========Failed runs summary========".format(os.linesep)) + final_superpmi_log.write("========Failed runs summary========{}".format(os.linesep)) final_superpmi_log.write(os.linesep.join(failed_runs)) return 0 if len(failed_runs) == 0 else 1 diff --git a/src/coreclr/scripts/superpmi_replay_setup.py b/src/coreclr/scripts/superpmi_replay_setup.py index b7717da8efaf24..d3c62f561cab1c 100644 --- a/src/coreclr/scripts/superpmi_replay_setup.py +++ b/src/coreclr/scripts/superpmi_replay_setup.py @@ -22,8 +22,9 @@ parser = argparse.ArgumentParser(description="description") parser.add_argument("-arch", help="Architecture") -parser.add_argument("-source_directory", help="path to the directory containing binaries") -parser.add_argument("-product_directory", help="path to the directory containing binaries") +parser.add_argument("-type", required=True, help="Type of diff (standard, apx)") +parser.add_argument("-source_directory", required=True, help="Path to the root directory of the dotnet/runtime source tree") +parser.add_argument("-product_directory", required=True, help="path to the directory containing binaries") def setup_args(args): @@ -54,6 +55,11 @@ def setup_args(args): lambda product_directory: os.path.isdir(product_directory), "product_directory doesn't exist") + coreclr_args.verify(args, + "type", + lambda type: type in ["standard", "apx"], + "Invalid type \"{}\"".format) + return coreclr_args diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 0621f2bcd1eb23..22213afb82b30a 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -7499,7 +7499,7 @@ MethodContext::Environment MethodContext::cloneEnvironment() } if (GetStringConfigValue != nullptr) { - env.getStingConfigValue = new LightWeightMap(*GetStringConfigValue); + env.getStringConfigValue = new LightWeightMap(*GetStringConfigValue); } return env; } @@ -7525,7 +7525,7 @@ bool MethodContext::IsEnvironmentHeaderEqual(const Environment& prevEnv) { return false; } - if (!AreLWMHeadersEqual(prevEnv.getStingConfigValue, GetStringConfigValue)) + if (!AreLWMHeadersEqual(prevEnv.getStringConfigValue, GetStringConfigValue)) { return false; } @@ -7539,7 +7539,7 @@ bool MethodContext::IsEnvironmentContentEqual(const Environment& prevEnv) { return false; } - if (!IsStringContentEqual(prevEnv.getStingConfigValue, GetStringConfigValue)) + if (!IsStringContentEqual(prevEnv.getStringConfigValue, GetStringConfigValue)) { return false; } diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index 8763439565410e..dd9f4abc0f0d4f 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -915,12 +915,12 @@ class MethodContext struct Environment { - Environment() : getIntConfigValue(nullptr), getStingConfigValue(nullptr) + Environment() : getIntConfigValue(nullptr), getStringConfigValue(nullptr) { } LightWeightMap* getIntConfigValue; - LightWeightMap* getStingConfigValue; + LightWeightMap* getStringConfigValue; }; Environment cloneEnvironment(); diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index 544b8f5d169bd8..d3792172ddd97f 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -1544,16 +1544,7 @@ void MyICJI::updateEntryPointForTailCall(CORINFO_CONST_LOOKUP* entryPoint) uint32_t MyICJI::getJitFlags(CORJIT_FLAGS* jitFlags, uint32_t sizeInBytes) { jitInstance->mc->cr->AddCall("getJitFlags"); - uint32_t ret = jitInstance->mc->repGetJitFlags(jitFlags, sizeInBytes); - if (jitInstance->forceClearAltJitFlag) - { - jitFlags->Clear(CORJIT_FLAGS::CORJIT_FLAG_ALT_JIT); - } - else if (jitInstance->forceSetAltJitFlag) - { - jitFlags->Set(CORJIT_FLAGS::CORJIT_FLAG_ALT_JIT); - } - return ret; + return jitInstance->getJitFlags(jitFlags, sizeInBytes); } // Runs the given function with the given parameter under an error trap diff --git a/src/coreclr/tools/superpmi/superpmi/jitinstance.cpp b/src/coreclr/tools/superpmi/superpmi/jitinstance.cpp index 0b02e4b8afe9e5..b24201fb831c24 100644 --- a/src/coreclr/tools/superpmi/superpmi/jitinstance.cpp +++ b/src/coreclr/tools/superpmi/superpmi/jitinstance.cpp @@ -56,8 +56,8 @@ JitInstance* JitInstance::InitJit(char* nameOfJit, } } - jit->environment.getIntConfigValue = nullptr; - jit->environment.getStingConfigValue = nullptr; + jit->environment.getIntConfigValue = nullptr; + jit->environment.getStringConfigValue = nullptr; if (st1 != nullptr) st1->Start(); @@ -244,7 +244,7 @@ ReplayResults JitInstance::CompileMethod(MethodContext* MethodToCompile, int mcI pParam->pThis->mc->repCompileMethod(&pParam->info, &pParam->flags, &os); CORJIT_FLAGS jitFlags; - pParam->pThis->mc->repGetJitFlags(&jitFlags, sizeof(jitFlags)); + pParam->pThis->getJitFlags(&jitFlags, sizeof(jitFlags)); pParam->results.IsMinOpts = jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE) || @@ -309,6 +309,17 @@ ReplayResults JitInstance::CompileMethod(MethodContext* MethodToCompile, int mcI { jitResult = CORJIT_OK; } + else + { + // If the target matches, but the JIT is an altjit and the user specified RunAltJitCode=0, + // then the JIT will also return CORJIT_SKIPPED, to prevent the generated code from being used. + // However, we don't want to treat that as a replay failure. + if (jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_ALT_JIT) && + (pParam->pThis->jitHost->getIntConfigValue("RunAltJitCode", 1) == 0)) + { + jitResult = CORJIT_OK; + } + } } if ((jitResult == CORJIT_OK) || (jitResult == CORJIT_BADCODE)) @@ -445,6 +456,22 @@ const char* JitInstance::getOption(const char* key, LightWeightMap return (const char*)options->GetBuffer(options->Get(keyIndex)); } +// Returns extended flags for a particular compilation instance, adjusted for altjit. +// This is a helper call; it does not record the call in the CompileResult. +uint32_t JitInstance::getJitFlags(CORJIT_FLAGS* jitFlags, uint32_t sizeInBytes) +{ + uint32_t ret = mc->repGetJitFlags(jitFlags, sizeInBytes); + if (forceClearAltJitFlag) + { + jitFlags->Clear(CORJIT_FLAGS::CORJIT_FLAG_ALT_JIT); + } + else if (forceSetAltJitFlag) + { + jitFlags->Set(CORJIT_FLAGS::CORJIT_FLAG_ALT_JIT); + } + return ret; +} + // Used to allocate memory that needs to handed to the EE. // For eg, use this to allocated memory for reporting debug info, // which will be handed to the EE by setVars() and setBoundaries() @@ -507,7 +534,7 @@ bool JitInstance::callJitStartup(ICorJitHost* jithost) } PAL_ENDTRY - Assert(environment.getIntConfigValue == nullptr && environment.getStingConfigValue == nullptr); + Assert(environment.getIntConfigValue == nullptr && environment.getStringConfigValue == nullptr); environment = mc->cloneEnvironment(); return param.result; @@ -527,10 +554,10 @@ bool JitInstance::resetConfig(MethodContext* firstContext) environment.getIntConfigValue = nullptr; } - if (environment.getStingConfigValue != nullptr) + if (environment.getStringConfigValue != nullptr) { - delete environment.getStingConfigValue; - environment.getStingConfigValue = nullptr; + delete environment.getStringConfigValue; + environment.getStringConfigValue = nullptr; } mc = firstContext; diff --git a/src/coreclr/tools/superpmi/superpmi/jitinstance.h b/src/coreclr/tools/superpmi/superpmi/jitinstance.h index 164147a100c0d6..b264894d368499 100644 --- a/src/coreclr/tools/superpmi/superpmi/jitinstance.h +++ b/src/coreclr/tools/superpmi/superpmi/jitinstance.h @@ -72,6 +72,8 @@ class JitInstance const char* getOption(const char* key); const char* getOption(const char* key, LightWeightMap* options); + uint32_t getJitFlags(CORJIT_FLAGS* jitFlags, uint32_t sizeInBytes); + const MethodContext::Environment& getEnvironment(); void* allocateArray(size_t size);