From 1c7f8a28a4e8c16133d13e5bc57dd26df2ba6b60 Mon Sep 17 00:00:00 2001 From: Jianchun Xu Date: Mon, 19 Sep 2016 17:11:49 -0700 Subject: [PATCH] JIT: build and test changes Build: - Add backend files. - Enable --no-jit option, and as default on OSX (temporarily). Test: - Add `dynapogo` test variant. Change `interpreted` test variant to create dynamic profiles and input to `dynapogo` test variant. To ensure the same profile file is used for these 2 variants, TestLoader (new) assigns each test case a unique test id, and uses the id to generate dynamic profile file name. - Add 'disable_jit` test variant and as default on OSX (temporarily). - Exclude 2 failing tests that need further work. --- CMakeLists.txt | 8 +- build.sh | 10 +- lib/Backend/CMakeLists.txt | 67 ++++++--- lib/CMakeLists.txt | 4 + lib/Common/Memory/CMakeLists.txt | 6 +- lib/Jsrt/CMakeLists.txt | 11 +- lib/Jsrt/Core/CMakeLists.txt | 2 + lib/Runtime/Base/CMakeLists.txt | 3 +- lib/Runtime/Language/CMakeLists.txt | 52 ++++--- lib/Runtime/Library/CMakeLists.txt | 52 ++++--- test/AsmJs/rlexe.xml | 1 + test/Date/rlexe.xml | 3 +- test/Function/rlexe.xml | 2 +- test/Optimizer/Invariants.baseline | 16 +- test/Optimizer/Invariants.js | 4 +- test/runtests.py | 222 ++++++++++++++++++---------- test/stackfunc/rlexe.xml | 2 +- 17 files changed, 297 insertions(+), 168 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2cef6b69394..9dd3fffd604 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -186,7 +186,6 @@ if(CLR_CMAKE_PLATFORM_XPLAT) -DUNICODE -D_SAFECRT_USE_CPP_OVERLOADS=1 -D__STDC_WANT_LIB_EXT1__=1 - -DDISABLE_JIT=1 # xplat-todo: enable the JIT for Linux ) set(CMAKE_CXX_STANDARD 11) @@ -291,6 +290,13 @@ if(CLR_CMAKE_PLATFORM_XPLAT) add_definitions(-DFEATURE_PAL) endif(CLR_CMAKE_PLATFORM_XPLAT) +if(NO_JIT + OR CLR_CMAKE_PLATFORM_DARWIN) # TODO: JIT for OSX + add_definitions(-DDISABLE_JIT=1) +else() + set(BuildJIT 1) +endif() + if(WITHOUT_FEATURES) add_definitions(${WITHOUT_FEATURES}) endif(WITHOUT_FEATURES) diff --git a/build.sh b/build.sh index d9d68e4c63b..d3e54a7752b 100755 --- a/build.sh +++ b/build.sh @@ -37,7 +37,8 @@ PRINT_USAGE() { echo " --icu=PATH Path to ICU include folder (see example below)" echo " -j [N], --jobs[=N] Multicore build, allow N jobs at once" echo " -n, --ninja Build with ninja instead of make" - echo " --no-icu Compile without unicode/icu support" + echo " --no-icu Compile without unicode/icu support" + echo " --no-jit Disable JIT" echo " --xcode Generate XCode project" echo " -t, --test-build Test build (by default Release build)" echo " --static Build as static library (by default shared library)" @@ -62,6 +63,7 @@ BUILD_TYPE="Release" CMAKE_GEN= MAKE=make MULTICORE_BUILD="" +NO_JIT= ICU_PATH="-DICU_SETTINGS_RESET=1" STATIC_LIBRARY="-DSHARED_LIBRARY_SH=1" WITHOUT_FEATURES="" @@ -191,6 +193,10 @@ while [[ $# -gt 0 ]]; do ICU_PATH="-DNO_ICU_PATH_GIVEN_SH=1" ;; + --no-jit) + NO_JIT="-DNO_JIT=1" + ;; + --xcode) CMAKE_GEN="-G Xcode -DCC_XCODE_PROJECT=1" MAKE=0 @@ -306,7 +312,7 @@ else fi echo Generating $BUILD_TYPE makefiles -cmake $CMAKE_GEN $CC_PREFIX $ICU_PATH $STATIC_LIBRARY $ARCH -DCMAKE_BUILD_TYPE=$BUILD_TYPE $WITHOUT_FEATURES ../.. +cmake $CMAKE_GEN $CC_PREFIX $ICU_PATH $STATIC_LIBRARY $ARCH -DCMAKE_BUILD_TYPE=$BUILD_TYPE $NO_JIT $WITHOUT_FEATURES ../.. _RET=$? if [[ $? == 0 ]]; then diff --git a/lib/Backend/CMakeLists.txt b/lib/Backend/CMakeLists.txt index 603ed0a89fe..bc78fce764d 100644 --- a/lib/Backend/CMakeLists.txt +++ b/lib/Backend/CMakeLists.txt @@ -1,6 +1,8 @@ -add_library (Chakra.Backend +add_library (Chakra.Backend OBJECT AgenPeeps.cpp + AsmJsJITInfo.cpp Backend.cpp + BackendApi.cpp BackendOpCodeAttrAsmJs.cpp BackwardPass.cpp BailOut.cpp @@ -10,10 +12,13 @@ add_library (Chakra.Backend CodeGenWorkItem.cpp DbCheckPostLower.cpp Debug.cpp + EhFrame.cpp EmitBuffer.cpp Encoder.cpp FlowGraph.cpp Func.cpp + FunctionJITRuntimeInfo.cpp + FunctionJITTimeInfo.cpp GlobOpt.cpp GlobOptBailOut.cpp GlobOptExpr.cpp @@ -32,6 +37,18 @@ add_library (Chakra.Backend InliningHeuristics.cpp IntBounds.cpp InterpreterThunkEmitter.cpp + JITObjTypeSpecFldInfo.cpp + JITOutput.cpp + JITTimeConstructorCache.cpp + JITTimeFixedField.cpp + JITTimeFunctionBody.cpp + JITTimePolymorphicInlineCache.cpp + JITTimePolymorphicInlineCacheInfo.cpp + JITTimeProfileInfo.cpp + JITTimeScriptContext.cpp + JITTimeWorkItem.cpp + JITType.cpp + JITTypeHandler.cpp JnHelperMethod.cpp LinearScan.cpp Lower.cpp @@ -48,6 +65,8 @@ add_library (Chakra.Backend Region.cpp SccLiveness.cpp Security.cpp + ServerScriptContext.cpp + ServerThreadContext.cpp SimpleJitProfilingHelpers.cpp SimpleLayout.cpp SwitchIRBuilder.cpp @@ -55,24 +74,34 @@ add_library (Chakra.Backend SymTable.cpp TempTracker.cpp ValueRelativeOffset.cpp - amd64\EncoderMD.cpp - amd64\LinearScanMD.cpp - amd64\LowererMDArch.cpp - amd64\PeepsMD.cpp - amd64\PrologEncoderMD.cpp - arm64\EncoderMD.cpp - arm64\LowerMD.cpp - arm\EncoderMD.cpp - arm\LegalizeMD.cpp - arm\LinearScanMD.cpp - arm\LowerMD.cpp - arm\PeepsMD.cpp - arm\UnwindInfoManager.cpp - i386\EncoderMD.cpp - i386\LinearScanMD.cpp - i386\LowererMDArch.cpp - i386\PeepsMD.cpp + amd64/EncoderMD.cpp + amd64/LinearScanMD.cpp + amd64/LowererMDArch.cpp + amd64/PeepsMD.cpp + amd64/PrologEncoderMD.cpp + amd64/LinearScanMdA.S + amd64/Thunks.S +# arm64/EncoderMD.cpp +# arm64/LowerMD.cpp +# arm/EncoderMD.cpp +# arm/LegalizeMD.cpp +# arm/LinearScanMD.cpp +# arm/LowerMD.cpp +# arm/PeepsMD.cpp +# arm/UnwindInfoManager.cpp +# i386/EncoderMD.cpp +# i386/LinearScanMD.cpp +# i386/LowererMDArch.cpp +# i386/PeepsMD.cpp ) target_include_directories ( - Chakra.Backend PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + Chakra.Backend PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} + amd64 + ../Common + ../JITIDL + ../Runtime + ../Runtime/ByteCode + ../Runtime/Math + ../Parser + ) diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 5f34badbd4d..f0bb0d7e944 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,5 +1,9 @@ add_compile_options(-fPIC) +if(BuildJIT) + add_subdirectory (Backend) +endif() + add_subdirectory (Common) add_subdirectory (Parser) add_subdirectory (Runtime) diff --git a/lib/Common/Memory/CMakeLists.txt b/lib/Common/Memory/CMakeLists.txt index 4826bb6ca26..e67d0bf1473 100644 --- a/lib/Common/Memory/CMakeLists.txt +++ b/lib/Common/Memory/CMakeLists.txt @@ -39,12 +39,10 @@ set (CCM_SOURCE_FILES ${CCM_SOURCE_FILES} ) if(CC_TARGETS_AMD64) - # xplat-todo: Include platform\XDataAllocator.cpp - # Needed on windows, need a replacement for linux to do - # amd64 stack walking set (CCM_SOURCE_FILES ${CCM_SOURCE_FILES} + amd64/XDataAllocator.cpp amd64/amd64_SAVE_REGISTERS.S - ) + ) endif() add_library (Chakra.Common.Memory OBJECT diff --git a/lib/Jsrt/CMakeLists.txt b/lib/Jsrt/CMakeLists.txt index 28268cd0e68..ac3dc0d28c7 100644 --- a/lib/Jsrt/CMakeLists.txt +++ b/lib/Jsrt/CMakeLists.txt @@ -1,3 +1,7 @@ +if(BuildJIT) + set(chakra_backend_objects $) +endif() + add_library (Chakra.Jsrt STATIC Jsrt.cpp JsrtDebugUtils.cpp @@ -14,7 +18,8 @@ add_library (Chakra.Jsrt STATIC JsrtSourceHolder.cpp JsrtThreadService.cpp $ -# Do not take this in. We need to control the + ${chakra_backend_objects} +# Do not take this in. We need to control the # linker order because of global constructors # and cross dependencies among them # $ @@ -36,12 +41,14 @@ add_library (Chakra.Jsrt STATIC ) add_subdirectory(Core) - + target_include_directories ( Chakra.Jsrt PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} + ../Backend ../JITIDL ../Runtime ../Runtime/Base + ../Runtime/ByteCode ../Runtime/Debug ../Parser ) diff --git a/lib/Jsrt/Core/CMakeLists.txt b/lib/Jsrt/Core/CMakeLists.txt index 9cc30d2e349..ab2cd0f4bc0 100644 --- a/lib/Jsrt/Core/CMakeLists.txt +++ b/lib/Jsrt/Core/CMakeLists.txt @@ -4,8 +4,10 @@ add_library (Chakra.Jsrt.Core OBJECT target_include_directories ( Chakra.Jsrt.Core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} + ../../Backend ../../JITIDL ../../Runtime + ../../Runtime/ByteCode ../../Parser ../ ) diff --git a/lib/Runtime/Base/CMakeLists.txt b/lib/Runtime/Base/CMakeLists.txt index 27c9a60dd1f..de0af1925eb 100644 --- a/lib/Runtime/Base/CMakeLists.txt +++ b/lib/Runtime/Base/CMakeLists.txt @@ -29,9 +29,10 @@ add_library (Chakra.Runtime.Base OBJECT ThreadContextTlsEntry.cpp ThreadServiceWrapperBase.cpp Utf8SourceInfo.cpp - VTuneChakraProfile.cpp + VTuneChakraProfile.cpp # WindowsFoundationAdapter.cpp # WindowsGlobalizationAdapter.cpp + jitprofiling.cpp ) target_include_directories ( diff --git a/lib/Runtime/Language/CMakeLists.txt b/lib/Runtime/Language/CMakeLists.txt index 20f87816ab4..df3581c4b5d 100644 --- a/lib/Runtime/Language/CMakeLists.txt +++ b/lib/Runtime/Language/CMakeLists.txt @@ -1,3 +1,7 @@ +if(BuildJIT) + add_definitions(-D_ENABLE_DYNAMIC_THUNKS=1) +endif() + set(CRL_SOURCE_FILES ${CRL_SOURCE_FILES} AsmJs.cpp AsmJsByteCodeGenerator.cpp @@ -26,32 +30,33 @@ set(CRL_SOURCE_FILES ${CRL_SOURCE_FILES} JavascriptStackWalker.cpp ModuleNamespace.cpp ModuleNamespaceEnumerator.cpp + ObjTypeSpecFldInfo.cpp ProfilingHelpers.cpp #ReadOnlyDynamicProfileInfo.cpp RuntimeLanguagePch.cpp - # SimdBool16x8Operation.cpp - # SimdBool16x8OperationX86X64.cpp - # SimdBool32x4Operation.cpp - # SimdBool32x4OperationX86X64.cpp - # SimdBool8x16Operation.cpp - # SimdBool8x16OperationX86X64.cpp - # SimdFloat32x4Operation.cpp - # SimdFloat32x4OperationX86X64.cpp - # SimdFloat64x2Operation.cpp - # SimdFloat64x2OperationX86X64.cpp - # SimdInt16x8Operation.cpp - # SimdInt16x8OperationX86X64.cpp - # SimdInt32x4Operation.cpp - # SimdInt32x4OperationX86X64.cpp - # SimdInt8x16Operation.cpp - # SimdInt8x16OperationX86X64.cpp - # SimdUint16x8Operation.cpp - # SimdUint16x8OperationX86X64.cpp - # SimdUint32x4Operation.cpp - # SimdUint32x4OperationX86X64.cpp - # SimdUint8x16Operation.cpp - # SimdUint8x16OperationX86X64.cpp - # SimdUtils.cpp + SimdBool16x8Operation.cpp + SimdBool16x8OperationX86X64.cpp + SimdBool32x4Operation.cpp + SimdBool32x4OperationX86X64.cpp + SimdBool8x16Operation.cpp + SimdBool8x16OperationX86X64.cpp + SimdFloat32x4Operation.cpp + SimdFloat32x4OperationX86X64.cpp + SimdFloat64x2Operation.cpp + SimdFloat64x2OperationX86X64.cpp + SimdInt16x8Operation.cpp + SimdInt16x8OperationX86X64.cpp + SimdInt32x4Operation.cpp + SimdInt32x4OperationX86X64.cpp + SimdInt8x16Operation.cpp + SimdInt8x16OperationX86X64.cpp + SimdUint16x8Operation.cpp + SimdUint16x8OperationX86X64.cpp + SimdUint32x4Operation.cpp + SimdUint32x4OperationX86X64.cpp + SimdUint8x16Operation.cpp + SimdUint8x16OperationX86X64.cpp + SimdUtils.cpp SourceDynamicProfileManager.cpp SourceTextModuleRecord.cpp StackTraceArguments.cpp @@ -64,6 +69,7 @@ if(CC_TARGETS_AMD64) amd64/AsmJsJitTemplate.cpp amd64/StackFrame.SystemV.cpp amd64/JavascriptOperatorsA.S + amd64/amd64_Thunks.S ) elseif(CC_TARGETS_X86) set (CRL_SOURCE_FILES ${CRL_SOURCE_FILES} diff --git a/lib/Runtime/Library/CMakeLists.txt b/lib/Runtime/Library/CMakeLists.txt index 747e306bf29..fef1aaeed6b 100644 --- a/lib/Runtime/Library/CMakeLists.txt +++ b/lib/Runtime/Library/CMakeLists.txt @@ -1,3 +1,7 @@ +if(BuildJIT) + add_definitions(-D_ENABLE_ASM_JS=1) +endif() + set(CRLIB_SOURCE_CODES ArgumentsObject.cpp ArgumentsObjectEnumerator.cpp @@ -56,18 +60,19 @@ set(CRLIB_SOURCE_CODES JavascriptRegularExpressionResult.cpp JavascriptSet.cpp JavascriptSetIterator.cpp - # JavascriptSimdBool16x8.cpp - # JavascriptSimdBool32x4.cpp - # JavascriptSimdBool8x16.cpp - # JavascriptSimdFloat32x4.cpp - # JavascriptSimdFloat64x2.cpp - # JavascriptSimdInt16x8.cpp - # JavascriptSimdInt32x4.cpp - # JavascriptSimdInt8x16.cpp - # JavascriptSimdObject.cpp - # JavascriptSimdUint16x8.cpp - # JavascriptSimdUint32x4.cpp - # JavascriptSimdUint8x16.cpp + JavascriptSimdBool16x8.cpp + JavascriptSimdBool32x4.cpp + JavascriptSimdBool8x16.cpp + JavascriptSimdFloat32x4.cpp + JavascriptSimdFloat64x2.cpp + JavascriptSimdInt16x8.cpp + JavascriptSimdInt32x4.cpp + JavascriptSimdInt8x16.cpp + JavascriptSimdObject.cpp + JavascriptSimdType.cpp + JavascriptSimdUint16x8.cpp + JavascriptSimdUint32x4.cpp + JavascriptSimdUint8x16.cpp JavascriptString.cpp JavascriptStringEnumerator.cpp JavascriptStringIterator.cpp @@ -89,19 +94,18 @@ set(CRLIB_SOURCE_CODES RuntimeFunction.cpp RuntimeLibraryPch.cpp ScriptFunction.cpp - # xplat-todo: enable SIMDjs on Linux - # SimdBool16x8Lib.cpp - # SimdBool32x4Lib.cpp - # SimdBool8x16Lib.cpp - # SimdFloat32x4Lib.cpp - # SimdFloat64x2Lib.cpp - # SimdInt16x8Lib.cpp - # SimdInt32x4Lib.cpp - # SimdInt8x16Lib.cpp - # SimdUint16x8Lib.cpp - # SimdUint32x4Lib.cpp - # SimdUint8x16Lib.cpp SharedArrayBuffer.cpp + SimdBool16x8Lib.cpp + SimdBool32x4Lib.cpp + SimdBool8x16Lib.cpp + SimdFloat32x4Lib.cpp + SimdFloat64x2Lib.cpp + SimdInt16x8Lib.cpp + SimdInt32x4Lib.cpp + SimdInt8x16Lib.cpp + SimdUint16x8Lib.cpp + SimdUint32x4Lib.cpp + SimdUint8x16Lib.cpp SingleCharString.cpp SparseArraySegment.cpp StackScriptFunction.cpp diff --git a/test/AsmJs/rlexe.xml b/test/AsmJs/rlexe.xml index cb751a95f00..d753466c50f 100644 --- a/test/AsmJs/rlexe.xml +++ b/test/AsmJs/rlexe.xml @@ -798,6 +798,7 @@ constloads.js constloads.baseline -testtrace:asmjs -maic:1 + exclude_xplat diff --git a/test/Date/rlexe.xml b/test/Date/rlexe.xml index 654a8d82fe9..b0b4c4fadec 100644 --- a/test/Date/rlexe.xml +++ b/test/Date/rlexe.xml @@ -93,7 +93,8 @@ - exclude_jenkins,exclude_mac + + exclude_jenkins,exclude_mac,exclude_xplat win8 diff --git a/test/Function/rlexe.xml b/test/Function/rlexe.xml index c5ce3a29b4a..9c31c7a52a3 100644 --- a/test/Function/rlexe.xml +++ b/test/Function/rlexe.xml @@ -432,7 +432,7 @@ failnativecodeinstall.js - /maxinterpretcount:2 /lic:1 /bgjit /off:simplejit /on:failnativecodeinstall + -maxinterpretcount:2 -lic:1 -bgjit -off:simplejit -on:failnativecodeinstall exclude_dynapogo,require_backend failnativecodeinstall.baseline diff --git a/test/Optimizer/Invariants.baseline b/test/Optimizer/Invariants.baseline index 3e0f53571ef..902af40f759 100644 --- a/test/Optimizer/Invariants.baseline +++ b/test/Optimizer/Invariants.baseline @@ -1,12 +1,12 @@ test0: 1 test1: 1 test2: undefined -6µ!%$caller -6µ!%$caller -6µ!%$caller -6µ!%$caller -6µ!%$caller -6µ!%$caller -6µ!%$caller -6µ!%$caller +6b!%$caller +6b!%$caller +6b!%$caller +6b!%$caller +6b!%$caller +6b!%$caller +6b!%$caller +6b!%$caller subset_of_ary = diff --git a/test/Optimizer/Invariants.js b/test/Optimizer/Invariants.js index c0235004847..c48f6aa5240 100644 --- a/test/Optimizer/Invariants.js +++ b/test/Optimizer/Invariants.js @@ -41,10 +41,10 @@ WScript.Echo("test2: " + test2()); // When hoisting an invariant with a new dst, value type of the old dst should be copied over to the new dst. function test3() { var func1 = function () { - return '6' + '\xb5!%$' + 'caller'; + return '6' + 'b!%$' + 'caller'; }; var func2 = function () { - return '6' + '\xb5!%$' + 'caller'; + return '6' + 'b!%$' + 'caller'; }; var ary = Array(); diff --git a/test/runtests.py b/test/runtests.py index 20e0ac3224a..d6f01f83842 100755 --- a/test/runtests.py +++ b/test/runtests.py @@ -10,6 +10,7 @@ from threading import Timer import sys import os +import glob import subprocess as SP import traceback import argparse @@ -43,6 +44,8 @@ parser.add_argument('-d', '--debug', action='store_true', help='use debug build'); parser.add_argument('-t', '--test', action='store_true', help='use test build') +parser.add_argument('--variants', metavar='variant', nargs='+', + help='run specified test variants') parser.add_argument('--include-slow', action='store_true', help='include slow tests (timeout ' + str(SLOW_TIMEOUT) + ' seconds)') parser.add_argument('--only-slow', action='store_true', @@ -81,6 +84,11 @@ sys.exit(1) flavor_alias = 'chk' if flavor == 'Debug' else 'fre' +# test variants +if not args.variants: + args.variants = ['interpreted', 'dynapogo'] if sys.platform != 'darwin' \ + else ['disable_jit'] # TODO: JIT for OSX + # binary: full ch path binary = args.binary if binary == None: @@ -114,7 +122,6 @@ if sys.platform != 'win32': not_tags.add('exclude_xplat') not_tags.add('Intl') - not_tags.add('require_backend') not_tags.add('require_debugger') if sys.platform == 'darwin': not_tags.add('exclude_mac') @@ -180,6 +187,7 @@ def normalize_new_line(text): # A test simply contains a collection of test attributes. # Misc attributes added by test run: +# id unique counter to identify a test # filename full path of test file # elapsed_time elapsed time when running the test # @@ -241,13 +249,14 @@ def log(self, filename, fail=False): # interpreted: -maxInterpretCount:1 -maxSimpleJitRunCount:1 -bgjit- # dynapogo: -forceNative -off:simpleJit -bgJitDelay:0 class TestVariant(object): - def __init__(self, name, compile_flags=[]): + def __init__(self, name, compile_flags=[], variant_not_tags=[]): self.name = name self.compile_flags = \ ['-WERExceptionSupport', '-ExtendedErrorStackForTestHost', '-BaselineMode'] + compile_flags + self._compile_flags_has_expansion = self._has_expansion(compile_flags) self.tags = tags.copy() - self.not_tags = not_tags.union( + self.not_tags = not_tags.union(variant_not_tags).union( ['{}_{}'.format(x, name) for x in ('fails','exclude')]) self.msg_queue = Manager().Queue() # messages from multi processes @@ -256,6 +265,19 @@ def __init__(self, name, compile_flags=[]): self._print_lines = [] # _print lines buffer self._last_len = 0 + @staticmethod + def _has_expansion(flags): + return any(re.match('.*\${.*}', f) for f in flags) + + @staticmethod + def _expand(flag, test): + return re.sub('\${id}', str(test.id), flag) + + def _expand_compile_flags(self, test): + if self._compile_flags_has_expansion: + return [self._expand(flag, test) for flag in self.compile_flags] + return self.compile_flags + # check if this test variant should run a given test def _should_test(self, test): tags = split_tags(test.get('tags')) @@ -372,7 +394,8 @@ def _run_one_test(self, test): working_path = os.path.dirname(js_file) flags = test.get('compile-flags') - flags = self.compile_flags + (flags.split() if flags else []) + flags = self._expand_compile_flags(test) + \ + (flags.split() if flags else []) cmd = [binary] + flags + [os.path.basename(js_file)] test.start() @@ -431,7 +454,7 @@ def timeout_func(timeout_data): self._log_result(test, fail=False) # run tests under this variant, using given multiprocessing Pool - def run(self, tests, pool): + def _run(self, tests, pool): print_and_log('\n############# Starting {} variant #############'\ .format(self.name)) if self.tags: @@ -458,6 +481,18 @@ def print_summary(self): print_and_log("----------------------------") print_and_log('Total: {}'.format(self.test_result)) + # run all tests from testLoader + def run(self, testLoader, pool, sequential_pool): + tests, sequential_tests = [], [] + for folder in testLoader.folders(): + if folder.tags.isdisjoint(self.not_tags): + dest = tests if not folder.is_sequential else sequential_tests + dest += folder.tests + if tests: + self._run(tests, pool) + if sequential_tests: + self._run(sequential_tests, sequential_pool) + # global run one test function for multiprocessing, used by TestVariant def run_one(data): try: @@ -467,9 +502,38 @@ def run_one(data): print('ERROR: Unhandled exception!!!') traceback.print_exc() -# record folder/tags info from test_root/rlexedirs.xml -class FolderTags(object): - def __init__(self): + +# A test folder contains a list of tests and maybe some tags. +class TestFolder(object): + def __init__(self, tests, tags=_empty_set): + self.tests = tests + self.tags = tags + self.is_sequential = 'sequential' in tags + +# TestLoader loads all tests +class TestLoader(object): + def __init__(self, paths): + self._folder_tags = self._load_folder_tags() + self._test_id = 0 + self._folders = [] + + for path in paths: + if os.path.isfile(path): + folder, file = os.path.dirname(path), os.path.basename(path) + else: + folder, file = path, None + + ftags = self._get_folder_tags(folder) + if ftags != None: # Only honor entries listed in rlexedirs.xml + tests = self._load_tests(folder, file) + self._folders.append(TestFolder(tests, ftags)) + + def folders(self): + return self._folders + + # load folder/tags info from test_root/rlexedirs.xml + @staticmethod + def _load_folder_tags(): xmlpath = os.path.join(test_root, 'rlexedirs.xml') try: xml = ET.parse(xmlpath).getroot() @@ -477,117 +541,117 @@ def __init__(self): print_and_log('ERROR: failed to read {}'.format(xmlpath)) exit(-1) - self._folder_tags = {} + folder_tags = {} for x in xml: d = x.find('default') key = d.find('files').text.lower() # avoid case mismatch tags = d.find('tags') - self._folder_tags[key] = \ + folder_tags[key] = \ split_tags(tags.text) if tags != None else _empty_set + return folder_tags # get folder tags if any - def _tags(self, folder): + def _get_folder_tags(self, folder): key = os.path.basename(os.path.normpath(folder)).lower() return self._folder_tags.get(key) - # check if should test a given folder - def should_test(self, folder): - ftags = self._tags(folder) + def _next_test_id(self): + self._test_id += 1 + return self._test_id - # folder listed in rlexedirs.xml and not exlucded by global not_tags - return ftags != None and ftags.isdisjoint(not_tags) + # load all tests in folder using rlexe.xml file + def _load_tests(self, folder, file): + try: + xmlpath = os.path.join(folder, 'rlexe.xml') + xml = ET.parse(xmlpath).getroot() + except IOError: + return [] - # check if a given folder is tagged sequential - def is_sequential(self, folder): - ftags = self._tags(folder) - return ftags and 'sequential' in ftags + def test_override(condition, check_tag, check_value, test): + target = condition.find(check_tag) + if target != None and target.text == check_value: + for override in condition.find('override'): + test[override.tag] = override.text -# load all tests in folder using rlexe.xml file -def load_tests(folder, file): - try: - xmlpath = os.path.join(folder, 'rlexe.xml') - xml = ET.parse(xmlpath).getroot() - except IOError: - return [] - - def test_override(condition, check_tag, check_value, test): - target = condition.find(check_tag) - if target != None and target.text == check_value: - for override in condition.find('override'): - test[override.tag] = override.text - - def load_test(testXml): - test = Test(folder=folder) - for c in testXml.find('default'): - if c.tag == 'timeout': # timeout seconds - test[c.tag] = int(c.text) - elif c.tag == 'tags' and c.tag in test: # merge multiple - test[c.tag] = test[c.tag] + ',' + c.text - else: - test[c.tag] = c.text + def load_test(testXml): + test = Test(folder=folder) + for c in testXml.find('default'): + if c.tag == 'timeout': # timeout seconds + test[c.tag] = int(c.text) + elif c.tag == 'tags' and c.tag in test: # merge multiple + test[c.tag] = test[c.tag] + ',' + c.text + else: + test[c.tag] = c.text - condition = testXml.find('condition') - if condition != None: - test_override(condition, 'target', arch_alias, test) + condition = testXml.find('condition') + if condition != None: + test_override(condition, 'target', arch_alias, test) - return test + return test - tests = [load_test(x) for x in xml] - if file != None: - tests = [x for x in tests if x.files == file] - if len(tests) == 0 and is_jsfile(file): - tests = [Test(folder=folder, files=file, baseline='')] - return tests + tests = [load_test(x) for x in xml] + if file != None: + tests = [x for x in tests if x.files == file] + if len(tests) == 0 and self.is_jsfile(file): + tests = [Test(folder=folder, files=file, baseline='')] -def is_jsfile(path): - return os.path.splitext(path)[1] == '.js' + for test in tests: # assign unique test.id + test.id = self._next_test_id() -def main(): - # By default run all tests - if len(args.folders) == 0: - files = (os.path.join(test_root, x) for x in os.listdir(test_root)) - args.folders = [f for f in sorted(files) if not os.path.isfile(f)] + return tests + + @staticmethod + def is_jsfile(path): + return os.path.splitext(path)[1] == '.js' +def main(): # Set the right timezone, the tests need Pacific Standard Time # TODO: Windows. time.tzset only supports Unix if hasattr(time, 'tzset'): os.environ['TZ'] = 'US/Pacific' time.tzset() + # By default run all tests + if len(args.folders) == 0: + files = (os.path.join(test_root, x) for x in os.listdir(test_root)) + args.folders = [f for f in sorted(files) if not os.path.isfile(f)] + # load all tests - tests, sequential_tests = [], [] - folder_tags = FolderTags() - for path in args.folders: - if os.path.isfile(path): - folder, file = os.path.dirname(path), os.path.basename(path) - else: - folder, file = path, None - if folder_tags.should_test(folder): - dest = sequential_tests if folder_tags.is_sequential(folder) \ - else tests - dest += load_tests(folder, file) + testLoader = TestLoader(args.folders) # test variants - variants = [ + variants = [x for x in [ TestVariant('interpreted', [ - '-maxInterpretCount:1', '-maxSimpleJitRunCount:1', '-bgjit-']) - ] + '-maxInterpretCount:1', '-maxSimpleJitRunCount:1', '-bgjit-', + '-dynamicprofilecache:profile.dpl.${id}' + ]), + TestVariant('dynapogo', [ + '-forceNative', '-off:simpleJit', '-bgJitDelay:0', + '-dynamicprofileinput:profile.dpl.${id}' + ]), + TestVariant('disable_jit', [ + '-nonative' + ], [ + 'exclude_interpreted', 'fails_interpreted', 'require_backend' + ]) + ] if x.name in args.variants] + + # rm profile.dpl.* + for f in glob.glob(test_root + '/*/profile.dpl.*'): + os.remove(f) # run each variant pool, sequential_pool = Pool(), Pool(1) start_time = datetime.now() for variant in variants: - if tests: - variant.run(tests, pool) - if sequential_tests: - variant.run(sequential_tests, sequential_pool) + variant.run(testLoader, pool, sequential_pool) elapsed_time = datetime.now() - start_time # print summary for variant in variants: variant.print_summary() - print() + failed = any(variant.test_result.fail_count > 0 for variant in variants) print('[{}] {}'.format( str(elapsed_time), 'Success!' if not failed else 'Failed!')) diff --git a/test/stackfunc/rlexe.xml b/test/stackfunc/rlexe.xml index f45cee4d80f..855f185d799 100644 --- a/test/stackfunc/rlexe.xml +++ b/test/stackfunc/rlexe.xml @@ -667,7 +667,7 @@ 622043.js - /force:deferparse /mic:1 /off:bailonnoprofile /force:inline /off:simplejit + -force:deferparse -mic:1 -off:bailonnoprofile -force:inline -off:simplejit exclude_dynapogo,exclude_fre